Discussion of the most significant changes
This section documents noteworthy security-relevant differences between Astria Geth and the official repository.
New gRPC service
The Geth codebase was modified to add a gRPC endpoint exposing the executor interface required by Astria (specifically, by the Astria conductor component).
This interface allows to create new blocks by executing transactions (via ExecuteBlock
) and to update the blockchain head (via UpdateCommitmentState
).
The gRPC service is intended to be exposed only to a trusted conductor service, and by default it binds only to the local loopback interface.
Mempool and miner changes
The codebase significantly simplified the block miner so that transaction ordering is determined by the order in which they are received via the gRPC service from the conductor, which in turn receives ordered transactions from the sequencer.
Deposit transactions
Astria added the new DepositTx
transaction type to Geth, used to represent incoming bridge transactions.
Gas charges
Deposit transactions do not charge any intrinsic gas; native deposits do not involve actual bytecode execution and do not consume any gas, while ERC-20 deposits have a low gas budget (16,000) and invoke the contract that represents the deposited asset. The gas budget is fixed and not taken from any balance. Since all deposit transactions are not externally sourced but are instead generated by the sequencer, no gas-related denial-of-service issues can occur.
Since deposit transactions do not consume any gas, they also do not originate gas refunds.
Validation
Deposit transactions skip several checks, entirely bypassing the StateTransition::preCheck
function. Skipped checks include nonce verification, ensuring that the transaction is sent from an EOA and not from a contract (which should be impossible as the private key for a contract address is not recoverable) as well as minimum gas requirements. Even more notably, deposit transactions are not subject to any sort of signature check; there is no need to provide a valid sender signature.
Skipping these checks is justified since deposit transactions are not externally sourced but automatically generated from deposit events by the sequencer (and validated by the conductor).
Execution
Deposit transactions are added to the mempool alongside other Ethereum transactions. Their execution is handled by the same function that handles the other preexisting transaction types.
However, deposits are distinguished from normal transaction types via a boolean field IsDepositTx
. The most crucial part of deposits handling is implemented in state_transition.go::StateTransition::TransitionDb
. Deposits are divided into two kinds, handled differently: native deposits and ERC-20 deposits.
Native deposits grant the recipient some balance denominated in the native currency of the chain. These deposits are handled by increasing the recipient native balance and returning early.
ERC-20 deposits are handled almost identically to any regular transaction invoking a contract. This is because when an ERC-20 deposit transaction generated by the sequencer is received from the conductor, it is converted into a transaction invoking the mint
function of the ERC-20 contract that represents the bridged asset. The only changes made to TransitionDb
to handle ERC-20 deposits concern gas budget, gas refunds, and coinbase tips. Due to modifications in other functions (specifically, skipping preCheck
leading to not invoke buyGas
), the gas budget of ERC-20 deposit transactions is not set; therefore, a block of code that sets the appropriate gas limit was introduced.
Additionally, the function returns early to avoid originating gas refunds and distributing coinbase tips.