---
id: TIP-1031
title: Embed consensus context in the block Header
description: Embed consensus context into the block header
authors: Hamdi, Janis
status: Approved
related: N/A
protocolVersion: T4
---

# 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](https://github.com/commonwarexyz/monorepo/blob/main/consensus/src/marshal/standard/deferred.rs#L487). 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](https://github.com/commonwarexyz/monorepo/blob/2a588e4e341548333a4bd753c016e814ae0ecca0/consensus/src/lib.rs#L57) 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.

```rust
#[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](https://github.com/commonwarexyz/monorepo/blob/main/consensus/src/simplex/types.rs#L22), 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:

1. Construct the `Context` from the information provided from the consensus engine.
2. **MUST** set the context field on the header.

If not activated, the context field **MUST** be `None`.

## Block Verification

During `Automaton::verify()` step:

1. If not activated, the context **MUST** be `None`.
2. If activated, the context **MUST** be set and match the information provided by the consensus engine.
3. 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

If activated at genesis, genesis block encodes a sentinel context for consistency in the setting of this field.

```rust
let sentinel_context = Context {
  epoch: 0,
  view: 0,
  parent_view: 0,
  leader: B256::ZERO,
};
```

---

# Invariants

1. **Context presence**: Every block when activated has a set `Context`.

2. **Context correctness**: The encoded context MUST exactly match the `Context` provided by the consensus engine when the block was proposed. Validators MUST reject blocks where the embedded context does not match.

3. **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.

4. **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.

5. **Encoding backward compatibility**: The `context` field MUST be the last field in `TempoHeader`. When `None`, 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.

6. **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 `TempoHeader` with `context: Some(...)` and `context: None`, and that a pre-activation header's hash is unchanged after the upgrade.