Skip to main content

tempo_evm/
context.rs

1use std::collections::HashMap;
2
3use alloy_evm::eth::EthBlockExecutionCtx;
4use alloy_primitives::{Address, B256};
5use reth_evm::NextBlockEnvAttributes;
6use tempo_primitives::{TempoConsensusContext, subblock::PartialValidatorKey};
7
8/// Execution context for Tempo block.
9#[derive(Debug, Clone, derive_more::Deref)]
10pub struct TempoBlockExecutionCtx<'a> {
11    /// Inner [`EthBlockExecutionCtx`].
12    #[deref]
13    pub inner: EthBlockExecutionCtx<'a>,
14    /// Non-payment gas limit for the block.
15    pub general_gas_limit: u64,
16    /// Shared gas limit for the block.
17    pub shared_gas_limit: u64,
18    /// Validator set for the block.
19    ///
20    /// Only set for un-finalized blocks coming from consensus layer.
21    ///
22    /// When this is set to `None`, no validation of subblock signatures is performed.
23    /// Make sure to always set this field when executing blocks from untrusted sources
24    pub validator_set: Option<Vec<B256>>,
25    /// Consensus metadata for the block. `None` for pre-fork blocks.
26    pub consensus_context: Option<TempoConsensusContext>,
27    /// Mapping from a subblock validator public key to the fee recipient configured.
28    ///
29    /// Used to provide EVM with the fee recipient context when executing subblock transactions.
30    pub subblock_fee_recipients: HashMap<PartialValidatorKey, Address>,
31}
32
33/// Context required for next block environment.
34#[derive(Debug, Clone, derive_more::Deref)]
35pub struct TempoNextBlockEnvAttributes {
36    /// Inner [`NextBlockEnvAttributes`].
37    #[deref]
38    pub inner: NextBlockEnvAttributes,
39    /// Non-payment gas limit for the block.
40    pub general_gas_limit: u64,
41    /// Shared gas limit for the block.
42    pub shared_gas_limit: u64,
43    /// Milliseconds portion of the timestamp.
44    pub timestamp_millis_part: u64,
45    /// Consensus context
46    pub consensus_context: Option<TempoConsensusContext>,
47    /// Mapping from a subblock validator public key to the fee recipient configured.
48    pub subblock_fee_recipients: HashMap<PartialValidatorKey, Address>,
49}
50
51#[cfg(feature = "rpc")]
52impl reth_rpc_eth_api::helpers::pending_block::BuildPendingEnv<tempo_primitives::TempoHeader>
53    for TempoNextBlockEnvAttributes
54{
55    fn build_pending_env(
56        parent: &crate::SealedHeader<tempo_primitives::TempoHeader>,
57        block_overrides: Option<&alloy_rpc_types_eth::BlockOverrides>,
58    ) -> Self {
59        Self {
60            inner: NextBlockEnvAttributes::build_pending_env(parent, block_overrides),
61            general_gas_limit: parent.general_gas_limit,
62            shared_gas_limit: parent.shared_gas_limit,
63            timestamp_millis_part: parent.timestamp_millis_part,
64            consensus_context: None,
65            subblock_fee_recipients: Default::default(),
66        }
67    }
68}
69
70#[cfg(test)]
71mod tests {
72    use super::*;
73    use reth_primitives_traits::SealedHeader;
74    use reth_rpc_eth_api::helpers::pending_block::BuildPendingEnv;
75    use tempo_primitives::TempoHeader;
76
77    #[test]
78    fn test_build_pending_env_uses_parent_values() {
79        // Pending env uses parent's values directly since pending blocks are disabled
80        let gas_limit = 500_000_000u64;
81        let timestamp_millis_part = 500u64;
82        let general_gas_limit = 30_000_000u64;
83        let shared_gas_limit = 250_000_000u64;
84        let parent_header = TempoHeader {
85            inner: alloy_consensus::Header {
86                number: 10,
87                timestamp: 1000,
88                gas_limit,
89                ..Default::default()
90            },
91            general_gas_limit,
92            timestamp_millis_part,
93            shared_gas_limit,
94            ..Default::default()
95        };
96        let parent = SealedHeader::seal_slow(parent_header);
97        let pending_env = TempoNextBlockEnvAttributes::build_pending_env(&parent, None);
98
99        // Verify values are copied directly from parent
100        assert_eq!(pending_env.general_gas_limit, general_gas_limit);
101        assert_eq!(pending_env.shared_gas_limit, shared_gas_limit);
102        assert_eq!(pending_env.timestamp_millis_part, timestamp_millis_part);
103        assert!(pending_env.subblock_fee_recipients.is_empty());
104    }
105}