Architecture
Frost is built from two halves, joined by a narrow, versioned interface — the same split Ethereum adopted at the Merge, with one significant change in who decides what goes into a block.
users │ eth_sendRawTransaction ▼ ┌───────────────┐ │ ingress │ public JSON-RPC endpoint └───────┬───────┘ │ submit ▼ ┌───────────────────────────────┐ │ consensus layer (CL) │ Mysticeti V2 DAG │ orders opaque transactions │ post-quantum block signatures └───────────────┬───────────────┘ │ committed order ▼ ┌───────────────┐ │ driver │ Engine API, forced-list profile └───────┬───────┘ │ engine_forkchoiceUpdated / getPayload / newPayload ▼ ┌───────────────────────────────┐ │ execution layer (EL) │ EVM, state, EIP-8141 └───────────────────────────────┘Execution layer
Section titled “Execution layer”The EL is a standard Ethereum execution client carrying the EIP-8141
implementation: the 0x06 transaction type, the frame opcodes, the ML-DSA
verifier precompiles, and the frame-transaction pool. There are two of them,
running side by side in the live fleet: 8141-geth, a Go fork of
go-ethereum, and frost-reth, written in Rust on reth. The two are
consensus-identical — the same committed input produces byte-identical blocks
on either — and the public RPC endpoint is served by frost-reth.
It is not a standalone Ethereum client. Block production is driven entirely by the consensus layer, and the EL does not choose what goes into a block. Both clients refuse to build a block from their own mempool: a build request that does not carry an explicit forced transaction list is rejected, so there is no path by which a node could locally reorder or censor.
Everything else about it is an ordinary Ethereum execution layer: the same state trie, the same receipts, the same JSON-RPC handlers, the same EVM at the Osaka feature level.
Consensus layer
Section titled “Consensus layer”The CL is Mysticeti V2, extracted from the Sui codebase and adapted. It is a DAG-based BFT protocol: validators continuously propose blocks that reference each other, and the protocol derives a total order from the resulting graph rather than electing one proposer per slot.
Two properties matter for how Frost behaves:
Ordering is decided before execution. The consensus layer orders opaque bytes. It does not run the EVM, does not know what a transaction does, and cannot price one above another. By the time the execution layer sees a transaction, its position is already fixed. This is what makes the chain fee-blind.
Consensus itself is post-quantum. Validators sign their blocks with post-quantum keys, and the checkpoint chain that pins consensus history is signed with two independent post-quantum schemes. The transport between validators uses hybrid post-quantum key exchange as the only offered group. See Two-tier consensus keys.
The join: a forced-transaction Engine API
Section titled “The join: a forced-transaction Engine API”Standard Ethereum consensus clients tell the execution client “build a block” and let the EL pick transactions from its own mempool. Frost cannot work that way — the ordering has already been decided by consensus, and the EL must reproduce it exactly.
So the driver uses a forced-list profile of the Engine API. It passes the committed transaction list to the EL as an explicit payload attribute, together with a flag saying “do not add anything from your own pool”, then asks for the payload and delivers it back as the new head.
The critical property is deterministic skipping. Consensus orders bytes without validating them, so the committed list can contain transactions that turn out to be invalid — a bad nonce, an insufficient balance, a corrupt witness. Every EL must skip exactly the same ones, for exactly the same reasons, or the nodes would produce different blocks from the same input. The forced-list build path is specified so that skipping is a pure function of the ordered list and the parent state.
Ingress
Section titled “Ingress”The public RPC endpoint is not the execution layer directly. It is an ingress service that sits in front of it:
eth_sendRawTransactionis handled by the ingress itself, which validates the submission and forwards it to consensus. The acknowledgement means ordered into a proposed block, not executed.- Read methods are proxied to the local execution layer, so one URL serves the whole familiar surface.
- Signing methods and anything not on the allowlist are refused. A public endpoint holds no keys.
Before forwarding, the ingress runs the transaction’s VERIFY frame under a bounded gas budget with a banned-opcode tracer — the ERC-7562 validation rules — so a transaction with a bad post-quantum signature is rejected at submission with a reason, rather than being ordered and then skipped silently. This is a courtesy, not a consensus rule: the safety property is the deterministic skipping beneath it.
See the JSON-RPC reference for exactly which methods are served.
Node types
Section titled “Node types”Not every node does all of this. A validator runs consensus, a driver, an execution layer and an ingress. A follower streams the committed order from a validator and drives its own execution layer to the identical chain, without participating in consensus. That stream is allowlisted: a validator completes the handshake only for followers whose network keys it has been configured to serve, and fetching a bootstrap snapshot requires a token issued by the fleet’s operators, so following the public fleet is not open to third parties today. Nodes also differ in how much history they retain.
Node types covers the full taxonomy.
Why this shape
Section titled “Why this shape”The short answer is that post-quantum signatures make ordering and storage the scarce resources, and this architecture puts both under explicit control: consensus decides order without seeing fees, and the execution layer’s history can be tiered and pruned because the consensus layer independently certifies what happened.
The longer answers are in Design — in particular Consensus and the Engine API and Witness segregation.