Skip to main content

tempo_payload_types/
lib.rs

1//! Tempo payload types.
2
3#![cfg_attr(not(test), warn(unused_crate_dependencies))]
4#![cfg_attr(docsrs, feature(doc_cfg))]
5
6mod attrs;
7
8use alloy_primitives::B256;
9pub use attrs::{InterruptHandle, TempoPayloadAttributes};
10use std::sync::Arc;
11
12use alloy_eips::eip7685::Requests;
13use alloy_primitives::U256;
14use alloy_rpc_types_eth::Withdrawal;
15use reth_ethereum_engine_primitives::EthBuiltPayload;
16use reth_node_api::{BlockBody, ExecutionPayload, PayloadTypes};
17use reth_payload_primitives::{BuiltPayload, BuiltPayloadExecutedBlock};
18use reth_primitives_traits::{AlloyBlockHeader as _, SealedBlock};
19use serde::{Deserialize, Serialize};
20use tempo_primitives::{Block, TempoPrimitives};
21
22/// Payload types for Tempo node.
23#[derive(Debug, Clone, Copy, Default)]
24#[non_exhaustive]
25pub struct TempoPayloadTypes;
26
27/// Built payload type for Tempo node.
28///
29/// Wraps [`EthBuiltPayload`] and optionally includes the executed block data
30/// to enable the engine tree fast path (skipping re-execution for self-built payloads).
31#[derive(Debug, Clone)]
32pub struct TempoBuiltPayload {
33    /// The inner built payload.
34    inner: EthBuiltPayload<TempoPrimitives>,
35    /// The executed block data, used to skip re-execution in the engine tree.
36    executed_block: Option<BuiltPayloadExecutedBlock<TempoPrimitives>>,
37}
38
39impl TempoBuiltPayload {
40    /// Creates a new [`TempoBuiltPayload`].
41    pub fn new(
42        inner: EthBuiltPayload<TempoPrimitives>,
43        executed_block: Option<BuiltPayloadExecutedBlock<TempoPrimitives>>,
44    ) -> Self {
45        Self {
46            inner,
47            executed_block,
48        }
49    }
50
51    /// Converts the built payload into [`TempoExecutionData`].
52    pub fn into_execution_data(self) -> TempoExecutionData {
53        TempoExecutionData {
54            block: Arc::new(self.inner.block().clone()),
55            validator_set: None,
56        }
57    }
58}
59
60impl BuiltPayload for TempoBuiltPayload {
61    type Primitives = TempoPrimitives;
62
63    fn block(&self) -> &SealedBlock<Block> {
64        self.inner.block()
65    }
66
67    fn fees(&self) -> U256 {
68        self.inner.fees()
69    }
70
71    fn executed_block(&self) -> Option<BuiltPayloadExecutedBlock<Self::Primitives>> {
72        self.executed_block.clone()
73    }
74
75    fn requests(&self) -> Option<Requests> {
76        self.inner.requests()
77    }
78}
79
80/// Execution data for Tempo node. Simply wraps a sealed block.
81#[derive(Debug, Clone, Serialize, Deserialize)]
82pub struct TempoExecutionData {
83    /// The built block.
84    pub block: Arc<SealedBlock<Block>>,
85    /// Validator set active at the time this block was built.
86    pub validator_set: Option<Vec<B256>>,
87}
88
89impl ExecutionPayload for TempoExecutionData {
90    fn parent_hash(&self) -> alloy_primitives::B256 {
91        self.block.parent_hash()
92    }
93
94    fn block_hash(&self) -> alloy_primitives::B256 {
95        self.block.hash()
96    }
97
98    fn block_number(&self) -> u64 {
99        self.block.number()
100    }
101
102    fn withdrawals(&self) -> Option<&Vec<Withdrawal>> {
103        self.block
104            .body()
105            .withdrawals
106            .as_ref()
107            .map(|withdrawals| &withdrawals.0)
108    }
109
110    fn parent_beacon_block_root(&self) -> Option<alloy_primitives::B256> {
111        self.block.parent_beacon_block_root()
112    }
113
114    fn timestamp(&self) -> u64 {
115        self.block.timestamp()
116    }
117
118    fn transaction_count(&self) -> usize {
119        self.block.body().transaction_count()
120    }
121
122    fn gas_used(&self) -> u64 {
123        self.block.gas_used()
124    }
125
126    fn gas_limit(&self) -> u64 {
127        self.block.gas_limit()
128    }
129
130    fn slot_number(&self) -> Option<u64> {
131        self.block.slot_number()
132    }
133
134    fn block_access_list(&self) -> Option<&alloy_primitives::Bytes> {
135        None
136    }
137}
138
139impl From<TempoBuiltPayload> for TempoExecutionData {
140    fn from(value: TempoBuiltPayload) -> Self {
141        value.into_execution_data()
142    }
143}
144
145impl PayloadTypes for TempoPayloadTypes {
146    type ExecutionData = TempoExecutionData;
147    type BuiltPayload = TempoBuiltPayload;
148    type PayloadAttributes = TempoPayloadAttributes;
149
150    fn block_to_payload(block: SealedBlock<Block>) -> Self::ExecutionData {
151        TempoExecutionData {
152            block: Arc::new(block),
153            validator_set: None,
154        }
155    }
156}