TIP-1031: Embed Consensus Context into the Block Header
Abstract
Embed consensus metadata into the TempoHeader.
Motivation
Consensus context is a prerequisite to newer features in Commonware.
- Deferred Verification. A reduction in finalization latency by optimisitically notarizing blocks and verifying them async in the background.
By embedding the context into the header, Tempo blocks can implement the required CertifiableBlock trait.
Specification
When activated, a new field, Option<Context> is added as the last field of TempoHeader, which must be set on every subsequent block containing consensus metadata. The field follows the trailing‑optional pattern used by Ethereum's fork‑activated header fields (e.g. base_fee_per_gas, blob_gas_used): when None, it is omitted entirely from the RLP stream, preserving existing block hashes for pre‑activation headers.
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default, RlpEncodable, RlpDecodable)]
#[cfg_attr(feature = "reth-codec", derive(reth_codecs::Compact))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Context {
pub epoch: u64,
pub view: u64,
pub parent_view: u64,
pub leader: B256,
}The Context adds 3 fields: 3 u64 values and 1 B256 value, totaling 56 bytes raw. The field required to construct the context required by simplex, not present in this struct can be computed using properties of the block, parent_hash -> parent_digest.
RLP: Each u64 encodes to at most 9 bytes (1‑byte prefix + 8 bytes); each B256 encodes to 33 bytes (1‑byte prefix + 32 bytes). With a list header, the worst‑case overhead is 60 bytes per block. Pre‑activation headers incur zero overhead.
Compact (DB): The reth_codecs::Compact representation is comparable, using bitflag‑compressed integer widths.
Block Production
When activated the proposals must:
- Construct the
Contextfrom the information provided from the consensus engine. - MUST set the context field on the header.
If not activated, the context field MUST be None.
Block Verification
During Automaton::verify() step:
- If not activated, the context MUST be
None. - If activated, the context MUST be set and match the information provided by the consensus engine.
- Continue with verification as-is.
Important to note the immediate switch to Deferred is not strictly required. For example a validator can choose an implementation that preserves synchronous verification. This validator simply does not contribute to the reduced latency in forming the notarization certificate.
Genesis Block
The Genesis block MUST have the consensus context set to None.
Invariants
-
Context presence: Every block beyond genesis when activated has a set
Context. -
Context correctness: The encoded context MUST exactly match the
Contextprovided by the consensus engine when the block was proposed. Validators MUST reject blocks where the embedded context does not match. -
Context commitment: Because the context is a part of the header, and the header hash is the block's digest, the context is transitively committed to by any notarization or finalization certificate over that digest.
-
Backward incompatibility: This is a breaking change to block verification. All nodes must upgrade at the same protocol version. Blocks produced before the upgrade do not have the set context. Any blocks proposed by a non-upgraded node will have their proposals rejected, and will incorrectly notarize blocks with an invalid context.
-
Encoding backward compatibility: The
contextfield MUST be the last field inTempoHeader. WhenNone, it MUST be omitted entirely from the RLP stream so that the encoded representation of pre‑activation headers remains unchanged and existing block hashes are preserved. -
Round-trip fidelity: Context serializes and de-serializes into the same values.
Test Coverage
CertifiableBlock::context()returns the correct context for a block built with known parameters.- Block rejection when embedded context does not match the consensus engine's context.
- RLP round-trip for
TempoHeaderwithcontext: Some(...)andcontext: None, and that a pre-activation header's hash is unchanged after the upgrade.
Was this helpful?