Taiko nodes
Taiko nodes are minimally modified Ethereum execution clients (opens in a new tab) that consist of two parts:
You can think of it like an Ethereum mainnet node, except replacing the consensus client with taiko-client
. taiko-client
then drives taiko-geth
over the Engine API (opens in a new tab). This is a modular design that allows easily plugging in other execution clients.

taiko-geth
The taiko-geth (opens in a new tab) software is a fork of go-ethereum (opens in a new tab) with some changes made according to the Taiko protocol.
Like Ethereum mainnet execution engines, taiko-geth
listens to new L2 transactions broadcasted in the L2 network, executes them in the EVM, and holds the latest state and database of all current L2 data.
You can see all the changes made in the taiko-geth
fork at geth.taiko.xyz (opens in a new tab)!
taiko-client
The taiko-client (opens in a new tab) software replaces the consensus client piece of an Ethereum mainnet node. It connects to taiko-geth
, and the compiled binary includes three sub-commands:
driver
The driver
serves as an L2 consensus client. It listens for new L2 blocks from the TaikoL1
protocol contract, then directs the connected L2 execution engine to insert them or reorganize its local chain through the Engine API.
proposer
The proposer
fetches pending transactions from the L2 execution engine's mempool intervally pool, then tries to propose them to the TaikoL1
protocol contract.
prover
The prover
requests validity proofs from the ZK-EVM and sends transactions to prove the proposed blocks are valid or invalid.
Chain synchronization process
The Taiko protocol allows a block's timestamp to be equal to its parent
block's timestamp, which differs from the original Ethereum protocol. So it's
fine that there are two TaikoL1.proposeBlock
transactions included in one L1
block.
Taiko client's driver informs the L2 execution engine about Taiko protocol contract's latest verified L2 head and tries to let it catch up with the latest verified L2 block through P2P at first.
The driver monitors the execution engine's sync progress: If it's unable to make any new sync progress in a period of time, the driver switches to inserting the verified blocks into its local chain through the Engine API one by one.
After the L2 execution engine catches up with the latest verified L2 head, the driver subscribes to TaikoL1.BlockProposed
events. When a new pending block is proposed, the driver:
- Gets the corresponding
TaikoL1.proposeBlock
L1 transaction. - Decodes the
txList
and block metadata from the transaction's calldata. - Checks whether the
txList
is valid based on the rules defined in the Taiko protocol.
If the txList
is valid, the driver:
- Assembles a deterministic
TaikoL2.anchor
transaction based on the rules defined in the protocol and puts it as the first transaction in the proposedtxList
. - Uses this
txList
and the decoded block metadata to assemble a deterministic L2 block. - Directs the L2 execution engine to insert this assembled block and sets it as the current canonical chain's head via the Engine API.
If the txList
is invalid, the driver:
- Assembles an empty L2 block with only the anchor transaction.
You can see more detailed information here:
- Read more about block metadata here (opens in a new tab) or see
5.2.2 Block Metadata
in the whitepaper (opens in a new tab). - Read more about
txList
validation rules here (opens in a new tab) or see5.3.1 Validation
in the whitepaper (opens in a new tab). - Read more about the
TaikoL2.anchor
transaction and proposed block's determination here (opens in a new tab) or see5.4.1 Construction of Anchor Transactions
in the whitepaper (opens in a new tab).
Process of proposing a block
To propose a block, the proposer
:
- Fetches the pending transactions from the L2 execution engine through the
txpool_content
RPC method. - If there are too many pending transactions in the L2 execution engine, splits them into several smaller
txLists
. This is because the Taiko protocol restricts the max size of each proposedtxList
. - Proposes all split
txLists
by sendingTaikoL1.proposeBlock
transactions.
Process of proving a block
When a new block is proposed, the prover
:
- Gets the
TaikoL1.proposeBlock
L1 transaction calldata, decodes it, and validates thetxList
, just like what thedriver
software does. - Waits until the corresponding block is inserted by the L2 execution engine's
driver
software. - Generates a validity proof for that block asynchronously.
If the proposed block has a valid or invalid txList
, the prover
:
- Generates a Merkle proof of the block's
TaikoL2.anchor
transaction to prove its existence in theblock.txRoot
's MPT (opens in a new tab) and this transaction receipt's Merkle proof (opens in a new tab) in theblock.receiptRoot
's MPT from the L2 execution engine. - Submits the
TaikoL2.anchor
transaction's RLP encoded bytes, its receipt's RLP encoded bytes, the generated Merkle proofs, and a validity proof to prove this block valid by sending aTaikoL1.proveBlock
transaction (the block is valid even for an invalidtxList
because we prove the invalidtxList
maps to an empty block with only the anchor transaction).
Read more about why we need these Merkle proofs when proving in 5.5 Proving Blocks
in the whitepaper (opens in a new tab).