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::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    /// Mapping from a subblock validator public key to the fee recipient configured.
26    ///
27    /// Used to provide EVM with the fee recipient context when executing subblock transactions.
28    pub subblock_fee_recipients: HashMap<PartialValidatorKey, Address>,
29}
30
31/// Context required for next block environment.
32#[derive(Debug, Clone, derive_more::Deref)]
33pub struct TempoNextBlockEnvAttributes {
34    /// Inner [`NextBlockEnvAttributes`].
35    #[deref]
36    pub inner: NextBlockEnvAttributes,
37    /// Non-payment gas limit for the block.
38    pub general_gas_limit: u64,
39    /// Shared gas limit for the block.
40    pub shared_gas_limit: u64,
41    /// Milliseconds portion of the timestamp.
42    pub timestamp_millis_part: u64,
43    /// Mapping from a subblock validator public key to the fee recipient configured.
44    pub subblock_fee_recipients: HashMap<PartialValidatorKey, Address>,
45}
46
47#[cfg(feature = "rpc")]
48impl reth_rpc_eth_api::helpers::pending_block::BuildPendingEnv<tempo_primitives::TempoHeader>
49    for TempoNextBlockEnvAttributes
50{
51    fn build_pending_env(parent: &crate::SealedHeader<tempo_primitives::TempoHeader>) -> Self {
52        Self {
53            inner: NextBlockEnvAttributes::build_pending_env(parent),
54            general_gas_limit: parent.general_gas_limit,
55            shared_gas_limit: parent.shared_gas_limit,
56            timestamp_millis_part: parent.timestamp_millis_part,
57            subblock_fee_recipients: Default::default(),
58        }
59    }
60}
61
62#[cfg(test)]
63mod tests {
64    use super::*;
65    use reth_primitives_traits::SealedHeader;
66    use reth_rpc_eth_api::helpers::pending_block::BuildPendingEnv;
67    use tempo_primitives::TempoHeader;
68
69    #[test]
70    fn test_build_pending_env_uses_parent_values() {
71        // Pending env uses parent's values directly since pending blocks are disabled
72        let gas_limit = 500_000_000u64;
73        let timestamp_millis_part = 500u64;
74        let general_gas_limit = 30_000_000u64;
75        let shared_gas_limit = 250_000_000u64;
76
77        let parent_header = TempoHeader {
78            inner: alloy_consensus::Header {
79                number: 10,
80                timestamp: 1000,
81                gas_limit,
82                ..Default::default()
83            },
84            general_gas_limit,
85            timestamp_millis_part,
86            shared_gas_limit,
87        };
88        let parent = SealedHeader::seal_slow(parent_header);
89        let pending_env = TempoNextBlockEnvAttributes::build_pending_env(&parent);
90
91        // Verify values are copied directly from parent
92        assert_eq!(pending_env.general_gas_limit, general_gas_limit);
93        assert_eq!(pending_env.shared_gas_limit, shared_gas_limit);
94        assert_eq!(pending_env.timestamp_millis_part, timestamp_millis_part);
95        assert!(pending_env.subblock_fee_recipients.is_empty());
96    }
97}