signet_types/primitives/
block.rs

1//! Many of these types are re-produced from the `reth-primitives` crate family.
2
3use alloy::{
4    consensus::{
5        Block as AlloyBlock, BlockBody as AlloyBlockBody, BlockHeader, EthereumTxEnvelope,
6        EthereumTypedTransaction, Header, TxEip4844,
7    },
8    primitives::{Address, BlockHash, BlockNumber, Bloom, Bytes, B256, B64, U256},
9};
10use std::sync::OnceLock;
11
12/// A type alias for the block body used in Ethereum blocks.
13pub type BlockBody<T = TransactionSigned, H = Header> = AlloyBlockBody<T, H>;
14
15/// A Sealed header type
16#[derive(Debug, Clone, PartialEq, Eq, Default)]
17pub struct SealedHeader<H = Header> {
18    /// Block hash
19    hash: OnceLock<BlockHash>,
20    /// Locked Header fields.
21    header: H,
22}
23
24impl<H> SealedHeader<H> {
25    /// Create a new sealed header.
26    pub const fn new(header: H) -> Self {
27        Self { hash: OnceLock::new(), header }
28    }
29
30    /// Get the header
31    pub const fn header(&self) -> &H {
32        &self.header
33    }
34}
35
36impl SealedHeader {
37    /// Get the block hash of the sealed header.
38    pub fn hash(&self) -> BlockHash {
39        *self.hash.get_or_init(|| BlockHash::from(self.header.hash_slow()))
40    }
41
42    /// Split the sealed header into its components.
43    pub fn split(self) -> (BlockHash, Header) {
44        let hash = self.hash();
45        (hash, self.header)
46    }
47}
48
49impl<H: BlockHeader> BlockHeader for SealedHeader<H> {
50    fn parent_hash(&self) -> B256 {
51        self.header.parent_hash()
52    }
53
54    fn ommers_hash(&self) -> B256 {
55        self.header.ommers_hash()
56    }
57
58    fn beneficiary(&self) -> Address {
59        self.header.beneficiary()
60    }
61
62    fn state_root(&self) -> B256 {
63        self.header.state_root()
64    }
65
66    fn transactions_root(&self) -> B256 {
67        self.header.transactions_root()
68    }
69
70    fn receipts_root(&self) -> B256 {
71        self.header.receipts_root()
72    }
73
74    fn withdrawals_root(&self) -> Option<B256> {
75        self.header.withdrawals_root()
76    }
77
78    fn logs_bloom(&self) -> Bloom {
79        self.header.logs_bloom()
80    }
81
82    fn difficulty(&self) -> U256 {
83        self.header.difficulty()
84    }
85
86    fn number(&self) -> BlockNumber {
87        self.header.number()
88    }
89
90    fn gas_limit(&self) -> u64 {
91        self.header.gas_limit()
92    }
93
94    fn gas_used(&self) -> u64 {
95        self.header.gas_used()
96    }
97
98    fn timestamp(&self) -> u64 {
99        self.header.timestamp()
100    }
101
102    fn mix_hash(&self) -> Option<B256> {
103        self.header.mix_hash()
104    }
105
106    fn nonce(&self) -> Option<B64> {
107        self.header.nonce()
108    }
109
110    fn base_fee_per_gas(&self) -> Option<u64> {
111        self.header.base_fee_per_gas()
112    }
113
114    fn blob_gas_used(&self) -> Option<u64> {
115        self.header.blob_gas_used()
116    }
117
118    fn excess_blob_gas(&self) -> Option<u64> {
119        self.header.excess_blob_gas()
120    }
121
122    fn parent_beacon_block_root(&self) -> Option<B256> {
123        self.header.parent_beacon_block_root()
124    }
125
126    fn requests_hash(&self) -> Option<B256> {
127        self.header.requests_hash()
128    }
129
130    fn extra_data(&self) -> &Bytes {
131        self.header.extra_data()
132    }
133}
134
135/// Ethereum sealed block type.
136#[derive(Debug, Clone, PartialEq, Eq, Default)]
137pub struct SealedBlock<T = TransactionSigned, H = Header> {
138    /// The sealed header of the block.
139    pub header: SealedHeader<H>,
140    /// The transactions in the block.
141    pub body: AlloyBlockBody<T, H>,
142}
143
144impl<T, H> SealedBlock<T, H> {
145    /// Create a new sealed block without checking the header hash.
146    pub const fn new_unchecked(header: SealedHeader<H>, body: AlloyBlockBody<T, H>) -> Self {
147        Self { header, body }
148    }
149}
150
151impl<T, H: BlockHeader> BlockHeader for SealedBlock<T, H> {
152    fn parent_hash(&self) -> B256 {
153        self.header.parent_hash()
154    }
155
156    fn ommers_hash(&self) -> B256 {
157        self.header.ommers_hash()
158    }
159
160    fn beneficiary(&self) -> Address {
161        self.header.beneficiary()
162    }
163
164    fn state_root(&self) -> B256 {
165        self.header.state_root()
166    }
167
168    fn transactions_root(&self) -> B256 {
169        self.header.transactions_root()
170    }
171
172    fn receipts_root(&self) -> B256 {
173        self.header.receipts_root()
174    }
175
176    fn withdrawals_root(&self) -> Option<B256> {
177        self.header.withdrawals_root()
178    }
179
180    fn logs_bloom(&self) -> Bloom {
181        self.header.logs_bloom()
182    }
183
184    fn difficulty(&self) -> U256 {
185        self.header.difficulty()
186    }
187
188    fn number(&self) -> BlockNumber {
189        self.header.number()
190    }
191
192    fn gas_limit(&self) -> u64 {
193        self.header.gas_limit()
194    }
195
196    fn gas_used(&self) -> u64 {
197        self.header.gas_used()
198    }
199
200    fn timestamp(&self) -> u64 {
201        self.header.timestamp()
202    }
203
204    fn mix_hash(&self) -> Option<B256> {
205        self.header.mix_hash()
206    }
207
208    fn nonce(&self) -> Option<B64> {
209        self.header.nonce()
210    }
211
212    fn base_fee_per_gas(&self) -> Option<u64> {
213        self.header.base_fee_per_gas()
214    }
215
216    fn blob_gas_used(&self) -> Option<u64> {
217        self.header.blob_gas_used()
218    }
219
220    fn excess_blob_gas(&self) -> Option<u64> {
221        self.header.excess_blob_gas()
222    }
223
224    fn parent_beacon_block_root(&self) -> Option<B256> {
225        self.header.parent_beacon_block_root()
226    }
227
228    fn requests_hash(&self) -> Option<B256> {
229        self.header.requests_hash()
230    }
231
232    fn extra_data(&self) -> &Bytes {
233        self.header.extra_data()
234    }
235}
236
237/// A [`SealedBlock`] with the senders of the transactions.
238#[derive(Debug, Clone, PartialEq, Eq, Default)]
239pub struct RecoveredBlock<T = TransactionSigned, H = Header> {
240    /// The block.
241    pub block: SealedBlock<T, H>,
242    /// The senders
243    pub senders: Vec<Address>,
244}
245
246impl<T, H> RecoveredBlock<T, H> {
247    /// Create a new recovered block.
248    pub const fn new(block: SealedBlock<T, H>, senders: Vec<Address>) -> Self {
249        Self { block, senders }
250    }
251}
252
253impl<T, H: BlockHeader> BlockHeader for RecoveredBlock<T, H> {
254    fn parent_hash(&self) -> B256 {
255        self.block.parent_hash()
256    }
257
258    fn ommers_hash(&self) -> B256 {
259        self.block.ommers_hash()
260    }
261
262    fn beneficiary(&self) -> Address {
263        self.block.beneficiary()
264    }
265
266    fn state_root(&self) -> B256 {
267        self.block.state_root()
268    }
269
270    fn transactions_root(&self) -> B256 {
271        self.block.transactions_root()
272    }
273
274    fn receipts_root(&self) -> B256 {
275        self.block.receipts_root()
276    }
277
278    fn withdrawals_root(&self) -> Option<B256> {
279        self.block.withdrawals_root()
280    }
281
282    fn logs_bloom(&self) -> Bloom {
283        self.block.logs_bloom()
284    }
285
286    fn difficulty(&self) -> U256 {
287        self.block.difficulty()
288    }
289
290    fn number(&self) -> BlockNumber {
291        self.block.number()
292    }
293
294    fn gas_limit(&self) -> u64 {
295        self.block.gas_limit()
296    }
297
298    fn gas_used(&self) -> u64 {
299        self.block.gas_used()
300    }
301
302    fn timestamp(&self) -> u64 {
303        self.block.timestamp()
304    }
305
306    fn mix_hash(&self) -> Option<B256> {
307        self.block.mix_hash()
308    }
309
310    fn nonce(&self) -> Option<B64> {
311        self.block.nonce()
312    }
313
314    fn base_fee_per_gas(&self) -> Option<u64> {
315        self.block.base_fee_per_gas()
316    }
317
318    fn blob_gas_used(&self) -> Option<u64> {
319        self.block.blob_gas_used()
320    }
321
322    fn excess_blob_gas(&self) -> Option<u64> {
323        self.block.excess_blob_gas()
324    }
325
326    fn parent_beacon_block_root(&self) -> Option<B256> {
327        self.block.parent_beacon_block_root()
328    }
329
330    fn requests_hash(&self) -> Option<B256> {
331        self.block.requests_hash()
332    }
333
334    fn extra_data(&self) -> &Bytes {
335        self.block.extra_data()
336    }
337}
338
339/// Typed Transaction type without a signature
340pub type Transaction = EthereumTypedTransaction<TxEip4844>;
341
342/// Signed transaction.
343pub type TransactionSigned = EthereumTxEnvelope<TxEip4844>;
344
345/// Ethereum full block.
346///
347/// Withdrawals can be optionally included at the end of the RLP encoded message.
348pub type Block<T = TransactionSigned, H = Header> = AlloyBlock<T, H>;