Wischain nodes
Last updated
Last updated
Wischain nodes are slightly adjusted Ethereum execution clients, comprising two primary components:
wischain-geth
wischain-client
You can envision this setup as an Ethereum mainnet node, but with the consensus client replaced by the Wischain Client. The Wischain Client manages the Wischain Geth through the Engine API. This modular architecture enables the seamless integration of other execution clients as needed.
The Wischain Client serves as a critical component in the Wischain ecosystem, replacing the consensus client of a standard Ethereum node. It directly connects to Wischain Geth and is comprised of three main sub-commands:
Driver: This acts as the Layer 2 (L2) consensus client, monitoring for new L2 blocks from the Wischain Layer 1 (WischainL1) protocol contract. It guides the L2 execution engine to either insert these blocks or reorganize its local blockchain using the Engine API.
Proposer: The proposer component retrieves pending transactions from the mempool of the L2 execution engine and seeks to propose these transactions to the WischainL1 protocol contract.
Prover: This component is responsible for obtaining validity proofs from the ZK-EVM. It sends transactions to validate whether the proposed blocks are accurate.
The Wischain Geth software is a modified fork of Go-Ethereum, designed to comply with the Wischain protocol. Like execution engines on the Ethereum mainnet, Wischain Geth listens for new L2 transactions within the Wischain network, executes these transactions using the Ethereum Virtual Machine (EVM), and maintains the latest state and database of current L2 data.
For a detailed look at the changes made in the Wischain Geth fork, refer to the documentation available at geth.wischain.io
In the Wischain protocol, a block's timestamp can match that of its parent block, allowing two WischainL1.proposeBlock transactions to be included in a single Layer 1 block.
The driver within the Wischain Client keeps the L2 execution engine updated about the latest verified L2 head from the Wischain protocol contract. Initially, it attempts to synchronize with the latest verified L2 block using a peer-to-peer (P2P) approach.
The driver monitors the synchronization progress of the execution engine. If it fails to achieve progress within a certain timeframe, the driver switches to a method of inserting the verified blocks into its local chain sequentially via the Engine API.
Once the L2 execution engine is caught up with the latest verified L2 head, the driver subscribes to WischainL1.BlockProposed events. When a new block proposal is made, the driver follows these steps:
Retrieves the associated WischainL1.proposeBlock Layer 1 transaction.
Decompresses the transaction list bytes from the transaction's calldata (and blob data, if applicable).
Decodes the transaction list and block metadata from the decompressed data.
Validates the transaction list according to the Wischain protocol's rules.
If the transaction list is valid, the driver will:
Construct a deterministic WischainL2.anchor transaction based on the protocol’s guidelines and include it as the first entry in the proposed transaction list.
Utilize this transaction list alongside the decoded block metadata to assemble a valid L2 block.
Instruct the L2 execution engine to incorporate this assembled block, setting it as the new head of the canonical chain via the Engine API.
In cases where the transaction list is invalid, the driver will create an empty L2 block containing only the anchor transaction.
To propose a block, the proposer:
Accesses pending transactions from the L2 execution engine using the txpool_content
RPC method.
If the volume of pending transactions is excessive, the proposer divides them into smaller transaction lists, adhering to the Wischain protocol's maximum size limitations for each proposed transaction list.
Sends WischainL1.proposeBlock transactions for all segmented transaction lists.
When a new block is proposed, the prover:
Retrieves the calldata for the WischainL1.proposeBlock Layer 1 transaction, decodes it, and validates the transaction list, mirroring the process performed by the driver.
Waits for the corresponding block to be incorporated by the L2 execution engine’s driver software.
Asynchronously generates a validity proof for the block.
If the proposed block contains a valid or invalid transaction list, the prover:
Creates a Merkle proof of the block’s WischainL2.anchor transaction to confirm its presence in the block's transaction root (txRoot) and generates the Merkle proof for this transaction receipt within the block's receipt root (receiptRoot) sourced from the L2 execution engine.
Submits the RLP-encoded bytes of the WischainL2.anchor transaction, its receipt, the generated Merkle proofs, and a validity proof to establish the block's validity by sending a WischainL1.proveBlock transaction. This validity holds even for an invalid transaction list, as it is proven to correspond to an empty block containing only the anchor transaction.
Engaging with a Wischain node is designed to be similar to the experience of using a standard Layer 1 node. This is achieved by leveraging the core components of the L1 client while incorporating a few backward-compatible modifications.
To explore the specific changes made to the Geth client, you can view the fork diff page here.
For details on the execution client specification, check .
Refer to the Engine API specification
To ensure that the Wischain node operates similarly to other Layer 1 nodes, it must successfully pass the . Currently, these hive tests serve as a valuable reference for the API standards of an Ethereum node.