Skip to main content

anvil/eth/
tempo_consensus.rs

1//! Native Tempo consensus RPC response types.
2//!
3//! `consensus_getFinalization` returns a [`TempoCertifiedBlock`]. `consensus_getLatest` returns a
4//! [`TempoConsensusState`] with nullable `finalized` and `notarized`; local mining only populates
5//! `finalized`. The certificate bytes are unprefixed hex.
6//!
7//! Identity rotation takes effect in the epoch after the next block's epoch, allowing its
8//! predecessor's boundary block to announce the new key before it signs. Snapshots restore pending
9//! rotations exactly; rollback restores the retained block's key schedule.
10//!
11//! Locally mined fork blocks commit to a partial trie of the accounts and storage slots cached
12//! when the block was mined, rather than the complete upstream state. Non-pending `eth_getProof`
13//! queries use that immutable trie, including at the current head after development state edits.
14//! Accounts and slots absent from it have exclusion proofs, even if they exist upstream. Later
15//! upstream reads cannot extend an already certified trie. Proof snapshots follow the configured
16//! state-history cache limits; evicted snapshots are unavailable rather than rebuilt from live
17//! state. The latest snapshot is retained even when historical state retention is disabled.
18
19use super::{
20    backend::tempo_consensus::TempoFinalization,
21    error::{BlockchainError, Result},
22};
23use anvil_core::eth::block::Block;
24use foundry_primitives::{FoundryHeader, FoundryTxEnvelope};
25use serde::{Deserialize, Serialize};
26use tempo_primitives::TempoTxEnvelope;
27
28/// A finalization certificate and the complete native Tempo block it authenticates.
29#[derive(Clone, Debug, Deserialize, Serialize)]
30pub struct TempoCertifiedBlock {
31    /// Certificate metadata and bytes for this block.
32    #[serde(flatten)]
33    pub finalization: TempoFinalization,
34    /// Native header and body, without Anvil transaction wrappers.
35    pub block: tempo_primitives::Block,
36}
37
38impl TryFrom<(TempoFinalization, Block)> for TempoCertifiedBlock {
39    type Error = BlockchainError;
40
41    fn try_from((finalization, block): (TempoFinalization, Block)) -> Result<Self> {
42        let block = block
43            .try_map_header(|header| match header {
44                FoundryHeader::Tempo(header) => Ok(header),
45                FoundryHeader::Ethereum(_) => {
46                    Err(BlockchainError::Internal("expected a native Tempo header".into()))
47                }
48            })?
49            .try_map_transactions(|tx| match tx.into_inner() {
50                FoundryTxEnvelope::Legacy(tx) => Ok(TempoTxEnvelope::Legacy(tx)),
51                FoundryTxEnvelope::Eip2930(tx) => Ok(TempoTxEnvelope::Eip2930(tx)),
52                FoundryTxEnvelope::Eip1559(tx) => Ok(TempoTxEnvelope::Eip1559(tx)),
53                FoundryTxEnvelope::Eip7702(tx) => Ok(TempoTxEnvelope::Eip7702(tx)),
54                FoundryTxEnvelope::Tempo(tx) => Ok(TempoTxEnvelope::AA(tx)),
55                _ => Err(BlockchainError::Internal("expected a native Tempo transaction".into())),
56            })?;
57        Ok(Self { finalization, block })
58    }
59}
60
61/// Current consensus state, matching Tempo's `consensus_getLatest` response.
62#[derive(Clone, Debug, Serialize)]
63pub struct TempoConsensusState {
64    /// Latest local finalization, or the pinned upstream finalization before local mining.
65    pub finalized: Option<TempoCertifiedBlock>,
66    /// Reserved by Tempo; local mining only produces finalizations.
67    pub notarized: Option<TempoCertifiedBlock>,
68}