Skip to main content

Shared checkpoint behavior

The light clients on Metal expose the state-root interface used by ForeignInbox:
They also expose checkpoint(blockHash) and isAccepted(blockHash). checkpoint and stateRoot revert for an unknown checkpoint, while isAccepted returns false.

Configured routes

Obtain the light client address, deployed ABI and runtime bytecode hash, source chain ID, and authenticated trust configuration from the route provider. Compare them with the inbox’s lightClient() and source chain ID. MetalInbox exposes metalChainId(), while ForeignInbox exposes foreignChainId(), foreignOutbox() and foreignOutboxCodeHash(). The latter pins the approved runtime bytecode hash of the direct, immutable source Outbox. Compare it to the authenticated deployment artifact’s runtime bytecode hash and the source contract’s runtime bytecode hash at the checkpoint used for delivery. A new Outbox version requires a new inbox and an updated route configuration. Metal, Tempo, and Arc clients pin their verification keys for their lifetime. Replacing a client also requires a new inbox. Its consumed-nonce state starts empty, so application records must prevent previously completed instructions from executing again through the replacement route. ForeignInbox verifies the pinned code hash from the same account proof that establishes the Outbox’s storage root. CodeHashMismatch means that the proven runtime bytecode hash differs from the configured route. Correct the route or proof selection before retrying.

Metal light client

The Metal verifier accepts only epoch 0, and each update must advance both block height and view. signature is the 256-byte EIP-2537 G2 encoding. Read latestBlockHash() and then checkpoint(blockHash). The checkpoint returns (uint64 blockNumber, uint64 viewNumber, uint64 timestampMs, bytes32 stateRoot, bytes32 receiptsRoot, bytes32 interopMessageRoot). isAccepted(bytes32) returns a boolean. The client also exposes metalChainId(), metalGenesisHash(), VERIFIER_VERSION(), participantCount(), quorum(), latestBlockNumber(), latestView(), and validatorKey(uint256) for checking the authenticated deployment configuration. The key getter returns a 128-byte EIP-2537 G1 key in bitmap order. Supply headerRlp, epoch, view, parentView, signersBitmap, and signatureEipUncompressed from the finality-certificate response to update in that order. Verify keccak256(headerRlp) == blockHash before submission. Checkpoint acceptance is established by a successful update and isAccepted(blockHash), followed by destination-chain finality.

Ethereum light client

The protocol contract at 0x00000000000000000000000000000000000000FC exposes read methods only:
slot is the finalized beacon slot. timestamp is the Ethereum execution block’s timestamp in seconds, and latestUpdateTimestamp is the Metal block timestamp of the latest accepted store update. An update can advance the store without recording a newer execution checkpoint. Metal block execution verifies the update witness carried in the header and writes the resulting store and checkpoints before transactions execute. Trust roots, fork schedule, and participation threshold come from Metal’s network configuration.

Tempo light client

Tempo updates must advance block height and the (epoch, view) pair. The 128-byte voteSignature is the recovered threshold signature in EIP-2537 G1 encoding. The route provider must supply a public finalized-header and certificate feed and its conversion instructions. headerRlp is the exact finalized header, epoch, viewNumber, and parentView are its consensus fields, and voteSignature is the recovered threshold vote signature in EIP-2537 G1 encoding. The pinned group key identifies the source network. Resharing that preserves the key is supported, while replacing the key requires a new client. latestBlockHash() selects the most recent checkpoint. checkpoint(bytes32) returns (uint64 blockNumber, uint64 viewNumber, uint64 timestampMs, bytes32 stateRoot, bytes32 receiptsRoot).

Arc light client

The route provider must supply the finalized header and its precommit votes with a documented public conversion to this ABI. Each vote contains a validator index and a 64-byte Ed25519 signature. Sort votes by strictly increasing validator index and include more than two-thirds of the pinned voting power. Every vote must authenticate the same block and round. The block number must advance. The pinned validator keys identify the source network, and validator-set changes require a new client. latestBlockHash() selects the most recent checkpoint. checkpoint(bytes32) returns (uint64 blockNumber, uint64 timestampMs, bytes32 stateRoot, bytes32 receiptsRoot). Arc header timestamps are converted from seconds to milliseconds. Follow receiving messages to bind account and storage proofs to these checkpoints, or sending messages for the Metal message-tree proof path.