Inside Krypton: the beacon-kit + bera-reth architecture
Every EVM chain that launched in the last few years made the same first decision: pick a consensus mechanism, pick an execution engine, and decide whether to bolt them together with a custom bridge or use the standard Engine API. This post explains the choices Krypton made, how the two clients actually interact, and what we had to patch to build a working reward model on top.
Why two clients?
The Ethereum ecosystem standardized the consensus-execution split after the Merge. The Engine API (authenticated JSON-RPC over HTTP, JWT on port 8551) is the boundary: one process handles consensus and block validation; another handles EVM state transitions. The interface is clean, narrow, and well-tested across multiple independent implementations.
Krypton inherits this split directly. Each node runs two containers wired together:
beacond— the consensus layer (CL), a fork of Berachain's beacon-kit, which uses CometBFT (Tendermint BFT) for consensusbera-reth— the execution layer (EL), a fork of Reth with Rust'srevmEVM interpreter
The CL drives everything. The EL is a stateful coprocessor that executes EVM payloads when told to and reports back. Nothing in the EL calls out to the CL; the communication is strictly one-directional through the Engine API.
Validators / P2P
│
│ CometBFT p2p (port 26656)
▼
┌─────────────────────────────┐
│ beacond (consensus layer) │
│ CometBFT / ABCI++ │
│ PrepareProposal │
│ ProcessProposal │
│ FinalizeBlock / Commit │
└────────────┬────────────────┘
│ Engine API (port 8551, JWT)
│ forkchoiceUpdated
│ newPayload / getPayload
▼
┌─────────────────────────────┐
│ bera-reth (execution layer)│
│ revm EVM / MDBX state │
│ eth_* / debug_* / trace_* │
└────────────┬────────────────┘
│ devp2p (port 30303)
▼
EL peer syncExternal JSON-RPC (eth_*, debug_*, trace_*) is served exclusively by the EL. The CL exposes a CometBFT RPC on port 26657 for node status and consensus queries. Public ports are 30303 (EL devp2p) and 26656 (CL p2p); everything else stays on loopback or behind a VPN.
CometBFT: one height, one block, instant finality
The key architectural difference from an Ethereum-style beacon chain is the consensus algorithm. Krypton uses CometBFT (a Berachain fork of upstream CometBFT, itself a descendant of Tendermint), which gives it BFT finality at every single block.
There are no epochs in the Ethereum sense, no probabilistic finality, and no waiting for two checkpoints. Once a block commits, it is final. Byzantine fault tolerance holds as long as fewer than one-third of the validator stake weight is malicious.
A few properties that matter for building on top:
| Property | Detail |
|---|---|
| Height = slot | One CometBFT height maps 1:1 to one beacon slot. There are no missed slots. |
| Sequential, no gaps | ProcessSlots is called for every height. Block heights never skip. |
| Round-based failure | A failed or timed-out proposal increments the round, not the height. A new proposer is selected and tries again at the same height. |
| BFT threshold | Finalization requires 2/3+ of stake weight to prevote and precommit. Below that, the chain halts (liveness requires 2/3+; safety holds up to 1/3 malicious). |
The CL's app_hash (the value CometBFT anchors to a committed block) is the beacon state root. The EL execution payload state root is independently verified via newPayload during ProcessProposal, before any vote is cast.
ABCI++ and the Engine API: the full block lifecycle
beacond implements three ABCI++ hooks that CometBFT calls in order for each height:
PrepareProposal — called only on the current proposer. The validator service calls forkchoiceUpdated with payload attributes to tell the EL to start building a block, waits briefly, then calls getPayload to retrieve the assembled execution payload. The beacon block is assembled around that payload and returned to CometBFT.
ProcessProposal — called on all nodes. The blockchain service validates the proposed block's structure, verifies KZG proofs for any blob sidecars, and sends the execution payload to the EL via newPayload. The EL validates the payload (checks state root, gas, transactions) without committing. The node votes ACCEPT or REJECT. If REJECT, CometBFT starts a new round at the same height with a different proposer.
FinalizeBlock / Commit — called on all nodes after 2/3+ precommits are received. The state processor runs the full state transition: slot processing, validator balance updates, epoch transitions if applicable. Storage backends are flushed — beacon state to BeaconDB, block to BlockStore. A final forkchoiceUpdated is sent to the EL to advance its chain head. CometBFT increments to the next height.
This structure means block validation (newPayload) happens at proposal time, not finalization time. Any node that receives an invalid payload rejects the proposal before casting a vote, which means invalid EVM state transitions never reach a committed block.
The reward patches
A standard beacon-kit + bera-reth deployment routes inflation and fees the way Berachain does — into their Proof-of-Liquidity system. Krypton dropped that and implemented two consensus-level patches to redirect value to on-chain sink addresses that the app-layer reward contracts drain.
Patch 1: beacon-kit epoch-mint
beacon-kit already mints a fixed amount of native token to a fixed address on every block via EVMInflationWithdrawal, enforced as the first withdrawal in every block's state transition. The patch re-parametrizes this existing mechanism rather than inventing a new CL→EVM crossing.
The change: a curve-derived per-block inflation amount (a function of the current bonded ratio, persisted in beacon state) replaces the static chain-spec constant, and the mint credits INFLATION_SINK (a predeploy address) instead of the upstream address.
The bonded ratio is computed from consensus active-validator effective balances, not from the app-layer StakingRouter. This is required for determinism: every node must derive the same amount from the same beacon state, independently of any EVM contract state that could drift.
Patch 2: bera-reth fee-router
The fee-router patch sets the block coinbase to FEE_SINK in-protocol, hardcoded in bera-reth's block execution BlockEnv setup. The fee accounting after execution redirects the base fee (minus a governable burn fraction, set to 0 at genesis) plus priority tips to FEE_SINK. Value conservation is asserted on every node:
burn = baseFeeTotal × baseFeeBurnBps / 10_000
toSink = (baseFeeTotal − burn) + priorityTipsTotal
assert: burn + toSink == baseFeeTotal + priorityTipsTotalThe coinbase must be hardcoded, not left to the proposer to forward. If tips accrued to the proposer who was trusted to forward, nodes would disagree on FEE_SINK's balance and fork. Setting it directly in the EL removes that trust assumption and makes the outcome identical on every validator.
Determinism proof
Both patches were proven deterministic on a 4-validator network: 139+ blocks finalized in lockstep, with byte-identical EL stateRoot and CL app_hash across all nodes, and identical INFLATION_SINK and FEE_SINK balances. The app-layer StakingRouter, FeeDistributor, and InflationSource/FeeSource contracts then settle rewards from those sinks.
What is built and what is not
The binaries are real and the determinism proof is real. The deploy artifacts (Docker Compose, Helm chart, monitoring stack) are config-validated. What has not happened yet: an end-to-end run on real cloud or baremetal hardware. The earlier live proofs ran under Kurtosis. The remaining mainnet gate is an external audit of the two reward patches, which are the only new consensus-critical code.
| Component | Status |
|---|---|
beacond + bera-reth from source, patched | Built and run |
| Determinism proof (4-validator net, 4+ epochs) | Proven |
| 4→5 validator join and EIP-7002 voluntary exit | Proven live |
| App-layer staking/governance suite (177 tests) | Built, internally audited |
| Deploy artifacts (compose, Helm, monitoring) | Config-validated, not yet on real hardware |
| External audit of reward patches | Pending — mainnet gate |
For node setup, see the nodes overview. For port and network reference, see ports and networks.