@@ -5,17 +5,24 @@ use alloy::{
5
5
eips:: eip4895:: { Withdrawal , Withdrawals } ,
6
6
primitives:: B256 ,
7
7
} ;
8
- use alloy_hardforks:: { EthereumHardfork , EthereumHardforks } ;
8
+ use alloy_hardforks:: EthereumHardforks ;
9
9
use anyhow:: { anyhow, bail, ensure} ;
10
10
use ethportal_api:: {
11
+ consensus:: {
12
+ beacon_block:: {
13
+ BeaconBlockBellatrix , BeaconBlockCapella , BeaconBlockDeneb , BeaconBlockElectra ,
14
+ SignedBeaconBlock ,
15
+ } ,
16
+ beacon_state:: HistoricalBatch ,
17
+ } ,
11
18
types:: {
12
19
execution:: {
13
20
accumulator:: EpochAccumulator ,
14
21
block_body:: BlockBody ,
15
22
header_with_proof:: {
16
23
build_capella_historical_summaries_proof, build_deneb_historical_summaries_proof,
17
- build_historical_roots_proof , BlockHeaderProof ,
18
- BlockProofHistoricalHashesAccumulator , HeaderWithProof ,
24
+ build_electra_historical_summaries_proof , build_historical_roots_proof ,
25
+ BlockHeaderProof , BlockProofHistoricalHashesAccumulator , HeaderWithProof ,
19
26
} ,
20
27
} ,
21
28
network_spec:: network_spec,
@@ -32,7 +39,7 @@ use crate::{
32
39
provider:: EraProvider ,
33
40
utils:: {
34
41
bellatrix_execution_payload_to_header, capella_execution_payload_to_header,
35
- lookup_epoch_acc , post_deneb_execution_payload_to_header ,
42
+ deneb_execution_payload_to_header , electra_execution_payload_to_header , lookup_epoch_acc ,
36
43
} ,
37
44
} ;
38
45
@@ -107,6 +114,16 @@ impl EpochReader {
107
114
} )
108
115
}
109
116
117
+ pub fn iter_blocks ( mut self ) -> impl Iterator < Item = anyhow:: Result < AllBlockData > > {
118
+ ( self . starting_block ..self . ending_block ) . map ( move |current_block| {
119
+ if network_spec ( ) . is_paris_active_at_block ( current_block) {
120
+ self . get_post_merge_block_data ( current_block)
121
+ } else {
122
+ self . get_pre_merge_block_data ( current_block)
123
+ }
124
+ } )
125
+ }
126
+
110
127
fn get_pre_merge_block_data ( & self , block_number : u64 ) -> anyhow:: Result < AllBlockData > {
111
128
let tuple = self . era_provider . get_pre_merge ( block_number) ?;
112
129
let header = tuple. header . header ;
@@ -129,23 +146,53 @@ impl EpochReader {
129
146
} )
130
147
}
131
148
132
- fn get_merge_to_capella_block_data (
133
- & mut self ,
134
- block_number : u64 ,
135
- ) -> anyhow:: Result < AllBlockData > {
136
- let ( block, era) = self . era_provider . get_post_merge ( block_number) ?;
137
- let block = block
138
- . block
139
- . message_merge ( )
140
- . map_err ( |e| anyhow ! ( "Unable to decode merge block: {e:?}" ) ) ?;
141
- let execution_payload = & block. body . execution_payload ;
142
- let transactions = decode_transactions ( & execution_payload. transactions ) ?;
149
+ fn get_post_merge_block_data ( & mut self , block_number : u64 ) -> anyhow:: Result < AllBlockData > {
150
+ let ( block, historical_batch) = self . era_provider . get_post_merge ( block_number) ?;
151
+ ensure ! (
152
+ block. execution_block_number( ) == block_number,
153
+ "Post-merge block data is for wrong block! Expected: {block_number}, actual: {}" ,
154
+ block. execution_block_number( )
155
+ ) ;
156
+
157
+ let ( header_with_proof, body) = match & block {
158
+ SignedBeaconBlock :: Bellatrix ( beacon_block) => {
159
+ self . get_merge_to_capella_header_and_body ( & beacon_block. message , historical_batch) ?
160
+ }
161
+ SignedBeaconBlock :: Capella ( beacon_block) => {
162
+ self . get_capella_to_deneb_header_and_body ( & beacon_block. message , historical_batch) ?
163
+ }
164
+ SignedBeaconBlock :: Deneb ( beacon_block) => {
165
+ self . get_deneb_to_electra_header_and_body ( & beacon_block. message , historical_batch) ?
166
+ }
167
+ SignedBeaconBlock :: Electra ( beacon_block) => {
168
+ self . get_post_electra_header_and_body ( & beacon_block. message , historical_batch) ?
169
+ }
170
+ } ;
171
+
172
+ let receipts = self . get_receipts ( block_number, header_with_proof. header . receipts_root ) ?;
173
+
174
+ Ok ( AllBlockData {
175
+ block_number,
176
+ header_with_proof,
177
+ body,
178
+ receipts,
179
+ } )
180
+ }
181
+
182
+ fn get_merge_to_capella_header_and_body (
183
+ & self ,
184
+ block : & BeaconBlockBellatrix ,
185
+ historical_batch : & HistoricalBatch ,
186
+ ) -> anyhow:: Result < ( HeaderWithProof , BlockBody ) > {
187
+ let payload = & block. body . execution_payload ;
188
+
189
+ let transactions = decode_transactions ( & payload. transactions ) ?;
143
190
144
191
let header_with_proof = HeaderWithProof {
145
- header : bellatrix_execution_payload_to_header ( execution_payload , & transactions) ?,
192
+ header : bellatrix_execution_payload_to_header ( payload , & transactions) ?,
146
193
proof : BlockHeaderProof :: HistoricalRoots ( build_historical_roots_proof (
147
194
block. slot ,
148
- & era . historical_batch ,
195
+ historical_batch,
149
196
block,
150
197
) ) ,
151
198
} ;
@@ -154,25 +201,17 @@ impl EpochReader {
154
201
ommers : vec ! [ ] ,
155
202
withdrawals : None ,
156
203
} ) ;
157
- let receipts = self . get_receipts ( block_number, header_with_proof. header . receipts_root ) ?;
158
- Ok ( AllBlockData {
159
- block_number,
160
- header_with_proof,
161
- body,
162
- receipts,
163
- } )
204
+
205
+ Ok ( ( header_with_proof, body) )
164
206
}
165
207
166
- fn get_capella_to_deneb_block_data (
167
- & mut self ,
168
- block_number : u64 ,
169
- ) -> anyhow:: Result < AllBlockData > {
170
- let ( block, era) = self . era_provider . get_post_merge ( block_number) ?;
171
- let block = block
172
- . block
173
- . message_capella ( )
174
- . map_err ( |e| anyhow ! ( "Unable to decode capella block: {e:?}" ) ) ?;
208
+ fn get_capella_to_deneb_header_and_body (
209
+ & self ,
210
+ block : & BeaconBlockCapella ,
211
+ historical_batch : & HistoricalBatch ,
212
+ ) -> anyhow:: Result < ( HeaderWithProof , BlockBody ) > {
175
213
let payload = & block. body . execution_payload ;
214
+
176
215
let transactions = decode_transactions ( & payload. transactions ) ?;
177
216
let withdrawals: Vec < Withdrawal > =
178
217
payload. withdrawals . iter ( ) . map ( Withdrawal :: from) . collect ( ) ;
@@ -182,7 +221,7 @@ impl EpochReader {
182
221
proof : BlockHeaderProof :: HistoricalSummariesCapella (
183
222
build_capella_historical_summaries_proof (
184
223
block. slot ,
185
- & era . historical_batch . block_roots ,
224
+ & historical_batch. block_roots ,
186
225
block,
187
226
) ,
188
227
) ,
@@ -192,28 +231,23 @@ impl EpochReader {
192
231
ommers : vec ! [ ] ,
193
232
withdrawals : Some ( Withdrawals :: new ( withdrawals) ) ,
194
233
} ) ;
195
- let receipts = self . get_receipts ( block_number, header_with_proof. header . receipts_root ) ?;
196
- Ok ( AllBlockData {
197
- block_number,
198
- header_with_proof,
199
- body,
200
- receipts,
201
- } )
234
+
235
+ Ok ( ( header_with_proof, body) )
202
236
}
203
237
204
- fn get_deneb_block_data ( & mut self , block_number : u64 ) -> anyhow:: Result < AllBlockData > {
205
- let ( block, era) = self . era_provider . get_post_merge ( block_number) ?;
206
- let block = block
207
- . block
208
- . message_deneb ( )
209
- . map_err ( |e| anyhow ! ( "Unable to decode deneb block: {e:?}" ) ) ?;
238
+ fn get_deneb_to_electra_header_and_body (
239
+ & self ,
240
+ block : & BeaconBlockDeneb ,
241
+ historical_batch : & HistoricalBatch ,
242
+ ) -> anyhow:: Result < ( HeaderWithProof , BlockBody ) > {
210
243
let payload = & block. body . execution_payload ;
244
+
211
245
let transactions = decode_transactions ( & payload. transactions ) ?;
212
246
let withdrawals: Vec < Withdrawal > =
213
247
payload. withdrawals . iter ( ) . map ( Withdrawal :: from) . collect ( ) ;
214
248
215
249
let header_with_proof = HeaderWithProof {
216
- header : post_deneb_execution_payload_to_header (
250
+ header : deneb_execution_payload_to_header (
217
251
payload,
218
252
block. parent_root ,
219
253
& transactions,
@@ -222,7 +256,7 @@ impl EpochReader {
222
256
proof : BlockHeaderProof :: HistoricalSummariesDeneb (
223
257
build_deneb_historical_summaries_proof (
224
258
block. slot ,
225
- & era . historical_batch . block_roots ,
259
+ & historical_batch. block_roots ,
226
260
block,
227
261
) ,
228
262
) ,
@@ -232,39 +266,44 @@ impl EpochReader {
232
266
ommers : vec ! [ ] ,
233
267
withdrawals : Some ( Withdrawals :: new ( withdrawals) ) ,
234
268
} ) ;
235
- let receipts = self . get_receipts ( block_number, header_with_proof. header . receipts_root ) ?;
236
- Ok ( AllBlockData {
237
- block_number,
238
- header_with_proof,
239
- body,
240
- receipts,
241
- } )
269
+
270
+ Ok ( ( header_with_proof, body) )
242
271
}
243
272
244
- pub fn iter_blocks ( mut self ) -> impl Iterator < Item = anyhow:: Result < AllBlockData > > {
245
- ( self . starting_block ..self . ending_block ) . map ( move |current_block| {
246
- if current_block
247
- < EthereumHardfork :: Paris
248
- . activation_block ( network_spec ( ) . network ( ) . into ( ) )
249
- . expect ( "Paris should be available" )
250
- {
251
- self . get_pre_merge_block_data ( current_block)
252
- } else if current_block
253
- < EthereumHardfork :: Shanghai
254
- . activation_block ( network_spec ( ) . network ( ) . into ( ) )
255
- . expect ( "Shanghai should be available" )
256
- {
257
- self . get_merge_to_capella_block_data ( current_block)
258
- } else if current_block
259
- < EthereumHardfork :: Cancun
260
- . activation_block ( network_spec ( ) . network ( ) . into ( ) )
261
- . expect ( "Cancun should be available" )
262
- {
263
- self . get_capella_to_deneb_block_data ( current_block)
264
- } else {
265
- self . get_deneb_block_data ( current_block)
266
- }
267
- } )
273
+ fn get_post_electra_header_and_body (
274
+ & self ,
275
+ block : & BeaconBlockElectra ,
276
+ historical_batch : & HistoricalBatch ,
277
+ ) -> anyhow:: Result < ( HeaderWithProof , BlockBody ) > {
278
+ let payload = & block. body . execution_payload ;
279
+
280
+ let transactions = decode_transactions ( & payload. transactions ) ?;
281
+ let withdrawals: Vec < Withdrawal > =
282
+ payload. withdrawals . iter ( ) . map ( Withdrawal :: from) . collect ( ) ;
283
+
284
+ let header_with_proof = HeaderWithProof {
285
+ header : electra_execution_payload_to_header (
286
+ payload,
287
+ block. parent_root ,
288
+ & transactions,
289
+ & withdrawals,
290
+ & block. body . execution_requests ,
291
+ ) ?,
292
+ proof : BlockHeaderProof :: HistoricalSummariesDeneb (
293
+ build_electra_historical_summaries_proof (
294
+ block. slot ,
295
+ & historical_batch. block_roots ,
296
+ block,
297
+ ) ,
298
+ ) ,
299
+ } ;
300
+ let body = BlockBody ( AlloyBlockBody {
301
+ transactions,
302
+ ommers : vec ! [ ] ,
303
+ withdrawals : Some ( Withdrawals :: new ( withdrawals) ) ,
304
+ } ) ;
305
+
306
+ Ok ( ( header_with_proof, body) )
268
307
}
269
308
270
309
/// Returns the receipts for a given block number and receipts root.
0 commit comments