1
1
use std:: sync:: Arc ;
2
2
3
- use alloy:: primitives:: B256 ;
4
- use anyhow:: { anyhow, ensure} ;
5
- use ethportal_api:: types:: execution:: {
6
- accumulator:: EpochAccumulator ,
7
- header:: { Header , TxHashes } ,
8
- transaction:: Transaction ,
9
- withdrawal:: Withdrawal ,
3
+ use alloy:: {
4
+ consensus:: { Header , TxEnvelope } ,
5
+ eips:: eip4895:: Withdrawal ,
6
+ primitives:: B256 ,
10
7
} ;
8
+ use anyhow:: { anyhow, ensure} ;
9
+ use ethportal_api:: types:: execution:: accumulator:: EpochAccumulator ;
11
10
use serde:: { Deserialize , Deserializer } ;
12
11
use serde_json:: Value ;
13
12
use trin_validation:: constants:: { EPOCH_SIZE , MERGE_BLOCK_NUMBER } ;
@@ -44,8 +43,8 @@ impl<'de> Deserialize<'de> for FullHeaderBatch {
44
43
#[ derive( Debug , Clone , PartialEq , Eq ) ]
45
44
pub struct FullHeader {
46
45
pub header : Header ,
47
- pub txs : Vec < Transaction > ,
48
- pub tx_hashes : TxHashes ,
46
+ pub txs : Vec < TxEnvelope > ,
47
+ pub tx_hashes : Vec < B256 > ,
49
48
pub uncles : Vec < B256 > ,
50
49
pub epoch_acc : Option < Arc < EpochAccumulator > > ,
51
50
pub withdrawals : Option < Vec < Withdrawal > > ,
@@ -59,8 +58,8 @@ impl TryFrom<Value> for FullHeader {
59
58
fn try_from ( val : Value ) -> anyhow:: Result < Self > {
60
59
let header: Header = serde_json:: from_value ( val. clone ( ) ) ?;
61
60
let uncles: Vec < B256 > = serde_json:: from_value ( val[ "uncles" ] . clone ( ) ) ?;
62
- let tx_hashes : TxHashes = serde_json:: from_value ( val[ "transactions" ] . clone ( ) ) ?;
63
- let txs : Vec < Transaction > = serde_json :: from_value ( val [ "transactions" ] . clone ( ) ) ? ;
61
+ let txs : Vec < TxEnvelope > = serde_json:: from_value ( val[ "transactions" ] . clone ( ) ) ?;
62
+ let tx_hashes : Vec < B256 > = txs . iter ( ) . map ( |tx| * tx . hash ( ) ) . collect ( ) ;
64
63
let withdrawals = match val[ "withdrawals" ] . clone ( ) {
65
64
Value :: Null => None ,
66
65
_ => serde_json:: from_value ( val[ "withdrawals" ] . clone ( ) ) ?,
@@ -90,7 +89,7 @@ impl FullHeader {
90
89
let header_record = & epoch_acc[ header_index as usize ] ;
91
90
92
91
// Validate Header
93
- let actual_header_hash = self . header . hash ( ) ;
92
+ let actual_header_hash = self . header . hash_slow ( ) ;
94
93
95
94
ensure ! (
96
95
header_record. block_hash == actual_header_hash,
@@ -100,20 +99,19 @@ impl FullHeader {
100
99
) ;
101
100
}
102
101
ensure ! (
103
- self . txs. len( ) == self . tx_hashes. hashes . len( ) ,
102
+ self . txs. len( ) == self . tx_hashes. len( ) ,
104
103
"txs.len() != tx_hashes.hashes.len(): {} != {}" ,
105
104
self . txs. len( ) ,
106
- self . tx_hashes. hashes . len( )
105
+ self . tx_hashes. len( )
107
106
) ;
108
107
Ok ( ( ) )
109
108
}
110
109
}
111
110
112
111
#[ cfg( test) ]
113
112
mod tests {
114
- use ethportal_api:: types:: execution:: block_body:: {
115
- BlockBody , BlockBodyLegacy , BlockBodyShanghai ,
116
- } ;
113
+ use alloy:: { consensus:: BlockBody as AlloyBlockBody , eips:: eip4895:: Withdrawals } ;
114
+ use ethportal_api:: types:: execution:: block_body:: BlockBody ;
117
115
use serde_json:: Value ;
118
116
use ssz:: { Decode , Encode } ;
119
117
@@ -127,7 +125,7 @@ mod tests {
127
125
let full_header = FullHeader :: try_from ( body[ "result" ] . clone ( ) ) . unwrap ( ) ;
128
126
let header: Header = serde_json:: from_value ( body[ "result" ] . clone ( ) ) . unwrap ( ) ;
129
127
assert_eq ! ( full_header. txs. len( ) , 19 ) ;
130
- assert_eq ! ( full_header. tx_hashes. hashes . len( ) , 19 ) ;
128
+ assert_eq ! ( full_header. tx_hashes. len( ) , 19 ) ;
131
129
assert_eq ! ( full_header. uncles. len( ) , 1 ) ;
132
130
assert_eq ! ( full_header. header, header) ;
133
131
}
@@ -138,9 +136,10 @@ mod tests {
138
136
std:: fs:: read_to_string ( "../../test_assets/mainnet/block_17034871_value.json" ) . unwrap ( ) ;
139
137
let body: Value = serde_json:: from_str ( & body) . unwrap ( ) ;
140
138
let full_header = FullHeader :: try_from ( body[ "result" ] . clone ( ) ) . unwrap ( ) ;
141
- let block_body = BlockBody :: Shanghai ( BlockBodyShanghai {
142
- txs : full_header. txs . clone ( ) ,
143
- withdrawals : full_header. withdrawals . unwrap ( ) ,
139
+ let block_body = BlockBody ( AlloyBlockBody {
140
+ transactions : full_header. txs . clone ( ) ,
141
+ ommers : vec ! [ ] ,
142
+ withdrawals : full_header. withdrawals . map ( Withdrawals ) ,
144
143
} ) ;
145
144
let header: Header = serde_json:: from_value ( body[ "result" ] . clone ( ) ) . unwrap ( ) ;
146
145
block_body. validate_against_header ( & header) . unwrap ( ) ;
@@ -152,9 +151,10 @@ mod tests {
152
151
std:: fs:: read_to_string ( "../../test_assets/mainnet/block_17034873_value.json" ) . unwrap ( ) ;
153
152
let body: Value = serde_json:: from_str ( & body) . unwrap ( ) ;
154
153
let full_header = FullHeader :: try_from ( body[ "result" ] . clone ( ) ) . unwrap ( ) ;
155
- let block_body = BlockBody :: Shanghai ( BlockBodyShanghai {
156
- txs : full_header. txs . clone ( ) ,
157
- withdrawals : full_header. withdrawals . unwrap ( ) ,
154
+ let block_body = BlockBody ( AlloyBlockBody {
155
+ transactions : full_header. txs . clone ( ) ,
156
+ ommers : vec ! [ ] ,
157
+ withdrawals : full_header. withdrawals . map ( Withdrawals ) ,
158
158
} ) ;
159
159
let header: Header = serde_json:: from_value ( body[ "result" ] . clone ( ) ) . unwrap ( ) ;
160
160
block_body. validate_against_header ( & header) . unwrap ( ) ;
@@ -172,9 +172,10 @@ mod tests {
172
172
let body: Value = serde_json:: from_str ( & body) . unwrap ( ) ;
173
173
let full_header = FullHeader :: try_from ( body[ "result" ] . clone ( ) ) . unwrap ( ) ;
174
174
let header: Header = serde_json:: from_value ( body[ "result" ] . clone ( ) ) . unwrap ( ) ;
175
- let block_body = BlockBody :: Shanghai ( BlockBodyShanghai {
176
- txs : full_header. txs . clone ( ) ,
177
- withdrawals : full_header. withdrawals . unwrap ( ) ,
175
+ let block_body = BlockBody ( AlloyBlockBody {
176
+ transactions : full_header. txs . clone ( ) ,
177
+ ommers : vec ! [ ] ,
178
+ withdrawals : full_header. withdrawals . map ( Withdrawals ) ,
178
179
} ) ;
179
180
block_body. validate_against_header ( & header) . unwrap ( ) ;
180
181
// test ssz roundtrip
@@ -191,19 +192,23 @@ mod tests {
191
192
std:: fs:: read_to_string ( "../../test_assets/geth_batch/headers.json" ) . unwrap ( ) ;
192
193
let full_headers: FullHeaderBatch = serde_json:: from_str ( & expected) . unwrap ( ) ;
193
194
for full_header in full_headers. headers {
194
- let block_body = BlockBody :: Legacy ( BlockBodyLegacy {
195
- txs : full_header. txs ,
196
- uncles : vec ! [ ] ,
195
+ let block_body = BlockBody ( AlloyBlockBody {
196
+ transactions : full_header. txs ,
197
+ ommers : vec ! [ ] ,
198
+ withdrawals : None ,
197
199
} ) ;
198
200
// test that txs are properly deserialized if tx root is properly calculated
199
201
assert_eq ! (
200
- block_body. transactions_root( ) . unwrap ( ) ,
202
+ block_body. transactions_root( ) ,
201
203
full_header. header. transactions_root
202
204
) ;
203
205
// this block has no uncles, aka an empty uncles root is calculated.
204
206
// there's no need to validate deserialization of uncles, since they're just a
205
207
// vector of Header, which are already tested above
206
- assert_eq ! ( block_body. uncles_root( ) , full_header. header. uncles_hash) ;
208
+ assert_eq ! (
209
+ block_body. calculate_ommers_root( ) ,
210
+ full_header. header. ommers_hash
211
+ ) ;
207
212
}
208
213
}
209
214
}
0 commit comments