Recent History ()
The Recent History state transition maintains a rolling window of the most recent block metadata, enabling the protocol to detect duplicate work-reports and verify historical commitments.
Purpose
The recent history component () serves several critical functions:
- Duplicate Detection: Prevents the same work-report from being submitted multiple times across recent blocks
- State Integrity: Maintains Merkle commitments to recent block states for verification
- Accumulation Tracking: Records the accumulation output log using a Merkle Mountain Range (MMR) structure
- Work-Package History: Tracks which work-packages were reported in recent blocks
State Structure
The recent history state consists of two main components:
β ≡ ⟨h, b⟩ // Recent history tuple
h ∈ [BlockHistory; ≤8] // Sequence of up to 8 recent block records
b ∈ MMR // Accumulation output MMR
Each block history entry contains:
BlockHistory {
header_hash: H, // Blake2b hash of the block header
state_root: H, // State trie root (corrected in next block)
beefy_root: H, // MMR super-peak (used for BEEFY finality proofs)
reported: {H → H} // Map: work-package hash → segment root
}
The beefy_root is the MMR super-peak of the accumulation output log, used by the BEEFY finality gadget to provide concise finality proofs to third-party systems.
Constants:
- Window size: 8 blocks (configurable via
RECENT_HISTORY_SIZE) - Hashing: Keccak-256 for MMR operations (legacy compatibility)
How It Works
1. Parent State Root Correction
When a new block is processed, the first step updates the parent block's state root with the actual value:
if len(beta.h):
beta.h[-1].state_root = block.header.parent_state_root
This corrects the placeholder zero hash from the previous block's transition, ensuring historical state roots are accurate.
2. Accumulation Output MMR Update
The accumulation outputs from the current block are Merklized and appended to the MMR:
# Append accumulation root to MMR
beta.b = mmr_append(beta.b, acc_root, keccak256)
# Calculate MMR super-peak (Beefy root)
beefy_root = mmr_super_peak(beta.b)
The Beefy root is the MMR super-peak, providing a succinct commitment to all historical accumulation outputs.
3. Work-Package Tracking
For each guarantee in the block, we extract and store the work-package hash and its segment root:
def package(guarantees: GuaranteesExtrinsic) -> dict:
package_dict = {}
for g in guarantees:
spec = g.report.package_spec
package_dict[spec.hash] = spec.exports_root
return package_dict
This mapping allows the protocol to verify that a work-package hasn't been reported in recent history.
4. New Block History Entry
Finally, a new history entry is created and appended (with the state root initially set to zero):
new_entry = BlockHistory(
header_hash=header_hash,
state_root=Bytes[32]([0] * 32), # Placeholder, corrected next block
beefy_root=beefy_root,
reported=package(block.extrinsic.guarantees)
)
beta.h.append(new_entry)
beta.h = beta.h[-8:] // Keep only last 8 entries
State Transition Equation
The recent history transition updates both components:
β' = ⟨h', b'⟩
Where:
h' = (h† + n) [last 8 elements]
b' = MMR-append(b, acc_root, Keccak)
h†is the history after parent state root correctionnis the new block history entryacc_rootis the accumulation output root for this block
Implementation Details
Location: tessera/jam/state/transitions/recent_history/recent_history.py
Key Functions:
RecentHistory.transition(): Main state transition functionpackage(): Transforms guarantees into segment root lookup dictionaryMMRFunctions.append_fn(): Appends to Merkle Mountain RangeMMRFunctions.super_peak(): Computes MMR commitment
Dependencies:
- Keccak-256 hashing for MMR operations
- Blake2b for header hashing
- MMR utilities from
jam.utils.merkle
Usage in Protocol
Recent history is consulted during:
- Work-Report Validation: Checking that a work-package hash hasn't appeared in recent blocks
- State Proofs: Verifying historical state commitments
- Accumulation Verification: Validating accumulation output sequences via the MMR
Example
When block at slot 1000 is processed:
- Update block 999's state root:
h[7].state_root = parent_state_root - Append accumulation output to MMR:
b' = MMR-append(b, acc_root) - Record work-packages:
reported = {pkg_hash_1 → seg_root_1, ...} - Add new entry:
h[8] = {header_hash, 0x00...00, beefy_root, reported} - Trim to last 8:
h' = h[1:9]
References
- Gray Paper: Section on Recent History
- Specification: Equations defining , , and
- Implementation:
tessera/jam/state/transitions/recent_history/
Next: SAFROLE | Authorization