1- use alloy_primitives:: { Address , B256 , U256 } ;
1+ use alloy_consensus:: proofs:: { ordered_trie_root, ordered_trie_root_with_encoder} ;
2+ use alloy_primitives:: { b256, bytes, keccak256, Address , Bytes , B256 , B64 , U256 } ;
3+ use alloy_rlp:: Encodable ;
24use serde:: { Deserialize , Serialize } ;
35use ssz_derive:: { Decode , Encode } ;
46use ssz_types:: {
@@ -9,6 +11,9 @@ use tree_hash_derive::TreeHash;
911
1012use crate :: withdrawal:: Withdrawal ;
1113
14+ const EMPTY_UNCLE_ROOT_HASH : B256 =
15+ b256 ! ( "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" ) ;
16+
1217#[ derive( Debug , PartialEq , Clone , Serialize , Deserialize , Encode , Decode , TreeHash ) ]
1318pub struct ExecutionPayload {
1419 // Execution block header fields
@@ -36,3 +41,94 @@ pub struct ExecutionPayload {
3641 pub blob_gas_used : u64 ,
3742 pub excess_blob_gas : u64 ,
3843}
44+
45+ impl ExecutionPayload {
46+ pub fn header_hash ( & self , parent_beacon_block_root : B256 ) -> B256 {
47+ let mut buf = vec ! [ ] ;
48+ self . encode ( & mut buf, parent_beacon_block_root) ;
49+ keccak256 ( buf)
50+ }
51+
52+ fn encode ( & self , out : & mut dyn bytes:: BufMut , parent_beacon_block_root : B256 ) {
53+ let transactions = self
54+ . transactions
55+ . clone ( )
56+ . into_iter ( )
57+ . map ( |transaction| Bytes :: from ( transaction. to_vec ( ) ) )
58+ . collect :: < Vec < _ > > ( ) ;
59+ let transactions_root = calculate_transactions_root ( & transactions) ;
60+ let withdrawals_root = calculate_withdrawals_root ( & self . withdrawals ) ;
61+ alloy_rlp:: Header {
62+ list : true ,
63+ payload_length : self . rlp_payload_length (
64+ parent_beacon_block_root,
65+ transactions_root,
66+ withdrawals_root,
67+ ) ,
68+ }
69+ . encode ( out) ;
70+
71+ self . parent_hash . encode ( out) ;
72+ EMPTY_UNCLE_ROOT_HASH . encode ( out) ;
73+ self . fee_recipient . encode ( out) ;
74+ self . state_root . encode ( out) ;
75+ transactions_root. encode ( out) ;
76+ self . receipts_root . encode ( out) ;
77+ self . logs_bloom . encode ( out) ;
78+ U256 :: ZERO . encode ( out) ;
79+ self . block_number . encode ( out) ;
80+ self . gas_limit . encode ( out) ;
81+ self . gas_used . encode ( out) ;
82+ self . timestamp . encode ( out) ;
83+ self . extra_data . to_vec ( ) . as_slice ( ) . encode ( out) ;
84+ self . prev_randao . encode ( out) ;
85+ B64 :: ZERO . encode ( out) ;
86+ self . base_fee_per_gas . encode ( out) ;
87+ withdrawals_root. encode ( out) ;
88+ self . blob_gas_used . encode ( out) ;
89+ self . excess_blob_gas . encode ( out) ;
90+ parent_beacon_block_root. encode ( out) ;
91+ }
92+
93+ fn rlp_payload_length (
94+ & self ,
95+ parent_beacon_block_root : B256 ,
96+ transactions_root : B256 ,
97+ withdrawals_root : B256 ,
98+ ) -> usize {
99+ self . parent_hash . length ( )
100+ + EMPTY_UNCLE_ROOT_HASH . length ( ) // ommers_hash
101+ + self . fee_recipient . length ( )
102+ + self . state_root . length ( )
103+ + transactions_root. length ( )
104+ + self . receipts_root . length ( )
105+ + self . logs_bloom . length ( )
106+ + U256 :: ZERO . length ( ) // difficulty
107+ + self . block_number . length ( )
108+ + self . gas_limit . length ( )
109+ + self . gas_used . length ( )
110+ + self . timestamp . length ( )
111+ + self . extra_data . to_vec ( ) . as_slice ( ) . length ( )
112+ + self . prev_randao . length ( )
113+ + B64 :: ZERO . length ( ) // nonce
114+ + self . base_fee_per_gas . length ( )
115+ + withdrawals_root. length ( )
116+ + self . blob_gas_used . length ( )
117+ + self . excess_blob_gas . length ( )
118+ + parent_beacon_block_root. length ( )
119+ }
120+ }
121+
122+ /// Calculate the Merkle Patricia Trie root hash from a list of items
123+ /// `(rlp(index), encoded(item))` pairs.
124+ pub fn calculate_transactions_root < T > ( transactions : & [ T ] ) -> B256
125+ where
126+ T : Encodable ,
127+ {
128+ ordered_trie_root_with_encoder ( transactions, |tx : & T , buf| tx. encode ( buf) )
129+ }
130+
131+ /// Calculates the root hash of the withdrawals.
132+ pub fn calculate_withdrawals_root ( withdrawals : & [ Withdrawal ] ) -> B256 {
133+ ordered_trie_root ( withdrawals)
134+ }
0 commit comments