1
1
use std:: {
2
+ borrow:: Cow ,
2
3
fmt:: Debug ,
3
4
path:: { Path , PathBuf } ,
4
5
sync:: Arc ,
@@ -7,6 +8,7 @@ use std::{
7
8
8
9
use alloy_consensus:: { constants:: KECCAK_EMPTY , Header } ;
9
10
use alloy_eips:: { BlockId , BlockNumHash , BlockNumberOrTag } ;
11
+ use alloy_json_rpc:: RpcSend ;
10
12
use alloy_primitives:: { BlockHash , BlockNumber , StorageKey , StorageValue , U64 } ;
11
13
use dashmap:: DashMap ;
12
14
use quick_cache:: sync:: Cache ;
@@ -23,7 +25,7 @@ use reth_trie::{
23
25
} ;
24
26
use revm:: db:: { BundleAccount , BundleState } ;
25
27
use revm_primitives:: { map:: B256HashMap , Address , Bytes , HashMap , B256 , U256 } ;
26
- use serde:: { Deserialize , Serialize } ;
28
+ use serde:: { de :: DeserializeOwned , Deserialize , Serialize } ;
27
29
use tokio:: sync:: broadcast;
28
30
use tokio_util:: sync:: CancellationToken ;
29
31
use tracing:: { trace, trace_span} ;
@@ -131,40 +133,27 @@ impl StateProviderFactory for IpcStateProviderFactory {
131
133
132
134
/// Gets block header given block hash
133
135
fn header ( & self , block_hash : & BlockHash ) -> ProviderResult < Option < Header > > {
134
- let span =
135
- trace_span ! ( "header" , id = rand:: random:: <u64 >( ) , block_hash = %block_hash. to_string( ) ) ;
136
- let _guard = span. enter ( ) ;
137
- trace ! ( "header: get" ) ;
138
-
139
- let header = self
140
- . ipc_provider
141
- . call :: < _ , Option < <alloy_network:: Ethereum as alloy_network:: Network >:: BlockResponse > > (
142
- "eth_getBlockByHash" ,
143
- ( block_hash, false ) ,
144
- )
145
- . map_err ( ipc_to_provider_error) ?
146
- . map ( |b| b. header . inner ) ;
147
-
148
- trace ! ( "header: got" ) ;
136
+ let header = rpc_call :: <
137
+ _ ,
138
+ Option < <alloy_network:: Ethereum as alloy_network:: Network >:: BlockResponse > ,
139
+ > (
140
+ & self . ipc_provider ,
141
+ "eth_getBlockByHash" ,
142
+ ( block_hash, false ) ,
143
+ ) ?
144
+ . map ( |b| b. header . inner ) ;
145
+
149
146
Ok ( header)
150
147
}
151
148
152
149
/// Gets block hash given block number
153
150
fn block_hash ( & self , number : BlockNumber ) -> ProviderResult < Option < B256 > > {
154
- let span = trace_span ! (
155
- "block_hash provider factory" ,
156
- id = rand:: random:: <u64 >( ) ,
157
- block_num = number
158
- ) ;
159
- let _guard = span. enter ( ) ;
160
- trace ! ( "block_hash:get" ) ;
161
-
162
- let block_hash = self
163
- . ipc_provider
164
- . call :: < _ , Option < B256 > > ( "rbuilder_getBlockHash" , ( BlockNumberOrTag :: Number ( number) , ) )
165
- . map_err ( ipc_to_provider_error) ?;
151
+ let block_hash = rpc_call :: < _ , Option < B256 > > (
152
+ & self . ipc_provider ,
153
+ "rbuilder_getBlockHash" ,
154
+ ( BlockNumberOrTag :: Number ( number) , ) ,
155
+ ) ?;
166
156
167
- trace ! ( "block_hash: got" ) ;
168
157
Ok ( block_hash)
169
158
}
170
159
@@ -175,41 +164,18 @@ impl StateProviderFactory for IpcStateProviderFactory {
175
164
176
165
/// Gets block header given block hash
177
166
fn header_by_number ( & self , num : u64 ) -> ProviderResult < Option < Header > > {
178
- let span = trace_span ! (
179
- "header_by_number" ,
180
- id = rand:: random:: <u64 >( ) ,
181
- block_num = num
182
- ) ;
183
- let _guard = span. enter ( ) ;
184
- trace ! ( "header_by_num:get" ) ;
185
-
186
- let block = self
187
- . ipc_provider
188
- . call :: < _ , Option < <alloy_network:: Ethereum as alloy_network:: Network >:: BlockResponse > > (
189
- "eth_getBlockByNumber" ,
190
- ( num, false ) ,
191
- )
192
- . map_err ( ipc_to_provider_error) ?
193
- . map ( |b| b. header . inner ) ;
194
-
195
- trace ! ( "header_by_num: got" ) ;
167
+ let block = rpc_call :: <
168
+ _ ,
169
+ Option < <alloy_network:: Ethereum as alloy_network:: Network >:: BlockResponse > ,
170
+ > ( & self . ipc_provider , "eth_getBlockByNumber" , ( num, false ) ) ?
171
+ . map ( |b| b. header . inner ) ;
172
+
196
173
Ok ( block)
197
174
}
198
175
199
176
/// Gets block number of latest known block
200
177
fn last_block_number ( & self ) -> ProviderResult < BlockNumber > {
201
- let span = trace_span ! ( "last_block_num" , id = rand:: random:: <u64 >( ) ) ;
202
- let _guard = span. enter ( ) ;
203
- trace ! ( "last_block_num:get" ) ;
204
-
205
- let block_num = self
206
- . ipc_provider
207
- . call :: < _ , U64 > ( "eth_blockNumber" , ( ) )
208
- . map_err ( ipc_to_provider_error) ?
209
- . to :: < u64 > ( ) ;
210
-
211
- trace ! ( "last_block_num: got" ) ;
212
- Ok ( block_num)
178
+ Ok ( rpc_call :: < _ , U64 > ( & self . ipc_provider , "eth_blockNumber" , ( ) ) ?. to :: < u64 > ( ) )
213
179
}
214
180
215
181
/// Creates new root hasher - struct responsible for calculating root hash
@@ -277,33 +243,20 @@ impl StateProvider for IpcStateProvider {
277
243
account : Address ,
278
244
storage_key : StorageKey ,
279
245
) -> ProviderResult < Option < StorageValue > > {
280
- let span = trace_span ! ( "storage" , id = rand:: random:: <u64 >( ) ) ;
281
- let _guard = span. enter ( ) ;
282
- trace ! ( "storage:get" ) ;
283
-
284
246
if let Some ( storage) = self . storage_cache . get ( & ( account, storage_key) ) {
285
247
return Ok ( * storage) ;
286
248
}
287
249
288
250
let key: U256 = storage_key. into ( ) ;
289
- let storage = self
290
- . ipc_provider
291
- . call :: < _ , Option < StorageValue > > ( "eth_getStorageAt" , ( account, key) )
292
- . map_err ( ipc_to_provider_error) ?;
293
-
251
+ let storage = rpc_call ( & self . ipc_provider , "eth_getStorageAt" , ( account, key) ) ?;
294
252
self . storage_cache . insert ( ( account, storage_key) , storage) ;
295
253
296
- trace ! ( "got storage" ) ;
297
254
Ok ( storage)
298
255
}
299
256
300
257
/// Get account code by its hash
301
258
/// IMPORTANT: Assumes remote provider (node) has RPC call:"rbuilder_getCodeByHash"
302
259
fn bytecode_by_hash ( & self , code_hash : & B256 ) -> ProviderResult < Option < Bytecode > > {
303
- let span = trace_span ! ( "bytecode" , id = rand:: random:: <u64 >( ) ) ;
304
- let _guard = span. enter ( ) ;
305
- trace ! ( "bytecode:get" ) ;
306
-
307
260
let empty_hash = code_hash. is_zero ( ) || * code_hash == KECCAK_EMPTY ;
308
261
if empty_hash {
309
262
return Ok ( None ) ;
@@ -313,17 +266,17 @@ impl StateProvider for IpcStateProvider {
313
266
return Ok ( Some ( bytecode. clone ( ) ) ) ;
314
267
}
315
268
316
- let bytecode = self
317
- . ipc_provider
318
- . call :: < _ , Option < Bytes > > ( "rbuilder_getCodeByHash" , ( code_hash , ) )
319
- . map_err ( ipc_to_provider_error ) ?
320
- . map ( |b| {
321
- let bytecode = Bytecode :: new_raw ( b ) ;
322
- self . code_cache . insert ( * code_hash , bytecode . clone ( ) ) ;
323
- bytecode
324
- } ) ;
325
-
326
- trace ! ( "bytecode: got" ) ;
269
+ let bytecode = rpc_call :: < _ , Option < Bytes > > (
270
+ & self . ipc_provider ,
271
+ "rbuilder_getCodeByHash" ,
272
+ ( code_hash , ) ,
273
+ ) ?
274
+ . map ( |b| {
275
+ let bytecode = Bytecode :: new_raw ( b ) ;
276
+ self . code_cache . insert ( * code_hash , bytecode. clone ( ) ) ;
277
+ bytecode
278
+ } ) ;
279
+
327
280
Ok ( bytecode)
328
281
}
329
282
}
@@ -332,24 +285,20 @@ impl BlockHashReader for IpcStateProvider {
332
285
/// Get the hash of the block with the given number. Returns `None` if no block with this number exists
333
286
/// IMPORTANT: Assumes IPC provider (node) has RPC call:"rbuilder_getBlockHash"
334
287
fn block_hash ( & self , number : BlockNumber ) -> ProviderResult < Option < B256 > > {
335
- let span = trace_span ! ( "block_hash provider" , id = rand:: random:: <u64 >( ) ) ;
336
- let _guard = span. enter ( ) ;
337
- trace ! ( "block_hash: get" ) ;
338
-
339
288
if let Some ( hash) = self . block_hash_cache . get ( & number) {
340
289
return Ok ( Some ( * hash) ) ;
341
290
}
342
291
343
- let block_hash = self
344
- . ipc_provider
345
- . call :: < _ , Option < B256 > > ( "rbuilder_getBlockHash" , ( BlockNumberOrTag :: Number ( number) , ) )
346
- . map_err ( ipc_to_provider_error) ?;
292
+ let block_hash = rpc_call :: < _ , Option < B256 > > (
293
+ & self . ipc_provider ,
294
+ "rbuilder_getBlockHash" ,
295
+ ( BlockNumberOrTag :: Number ( number) , ) ,
296
+ ) ?;
347
297
348
298
if let Some ( bh) = block_hash {
349
299
self . block_hash_cache . insert ( number, bh) ;
350
300
}
351
301
352
- trace ! ( "block_hash provider: got" ) ;
353
302
Ok ( block_hash)
354
303
}
355
304
@@ -367,31 +316,26 @@ impl AccountReader for IpcStateProvider {
367
316
/// IMPORTANT: Assumes IPC provider (node) has RPC call:"rbuilder_getAccount"
368
317
/// Returns `None` if the account doesn't exist.
369
318
fn basic_account ( & self , address : & Address ) -> ProviderResult < Option < Account > > {
370
- let span = trace_span ! (
371
- "account" ,
372
- id = rand:: random:: <u64 >( ) ,
373
- address = address. to_string( )
374
- ) ;
375
- let _guard = span. enter ( ) ;
376
- trace ! ( "account: get" ) ;
377
-
378
319
if let Some ( account) = self . account_cache . get ( address) {
379
320
return Ok ( * account) ;
380
321
}
381
322
382
- let account = self
383
- . ipc_provider
384
- . call :: < _ , Option < AccountState > > ( "rbuilder_getAccount" , ( * address, self . block_id ) )
385
- . map_err ( ipc_to_provider_error) ?
386
- . map ( |a| Account {
387
- nonce : a. nonce . try_into ( ) . unwrap ( ) ,
388
- bytecode_hash : a. code_hash . into ( ) ,
389
- balance : a. balance ,
390
- } ) ;
323
+ let account = rpc_call :: < _ , Option < AccountState > > (
324
+ & self . ipc_provider ,
325
+ "rbuilder_getAccount" ,
326
+ ( * address, self . block_id ) ,
327
+ ) ?
328
+ . map ( |a| Account {
329
+ nonce : a
330
+ . nonce
331
+ . try_into ( )
332
+ . expect ( "Nonce received from RPC should fit u64" ) ,
333
+ bytecode_hash : a. code_hash . into ( ) ,
334
+ balance : a. balance ,
335
+ } ) ;
391
336
392
337
self . account_cache . insert ( * address, account) ;
393
338
394
- trace ! ( "account: got" ) ;
395
339
Ok ( account)
396
340
}
397
341
}
@@ -502,30 +446,20 @@ impl RootHasher for StatRootHashCalculator {
502
446
& self ,
503
447
outcome : & reth_provider:: ExecutionOutcome ,
504
448
) -> Result < B256 , crate :: roothash:: RootHashError > {
505
- let span = trace_span ! (
506
- "state_root" ,
507
- id = rand:: random:: <u64 >( ) ,
508
- block = outcome. first_block
509
- ) ;
510
- let _guard = span. enter ( ) ;
511
- trace ! ( "state_root: get" ) ;
512
-
513
449
let account_diff: HashMap < Address , AccountDiff > = outcome
514
450
. bundle
515
451
. state
516
452
. iter ( )
517
453
. map ( |( address, diff) | ( * address, diff. clone ( ) . into ( ) ) )
518
454
. collect ( ) ;
519
455
520
- let hash = self
521
- . remote_provider
522
- . call :: < _ , B256 > (
523
- "rbuilder_calculateStateRoot" ,
524
- ( BlockId :: Hash ( self . parent_hash . into ( ) ) , account_diff) ,
525
- )
526
- . map_err ( |_| crate :: roothash:: RootHashError :: Verification ) ?;
456
+ let hash = rpc_call :: < _ , B256 > (
457
+ & self . remote_provider ,
458
+ "rbuilder_calculateStateRoot" ,
459
+ ( BlockId :: Hash ( self . parent_hash . into ( ) ) , account_diff) ,
460
+ )
461
+ . map_err ( |_| crate :: roothash:: RootHashError :: RpcStateRootFailed ) ?;
527
462
528
- trace ! ( "state_root: got" ) ;
529
463
Ok ( hash)
530
464
}
531
465
}
@@ -574,6 +508,26 @@ impl From<BundleAccount> for AccountDiff {
574
508
}
575
509
}
576
510
}
511
+ fn rpc_call < Param , Resp > (
512
+ ipc_provider : & RpcProvider ,
513
+ rpc_method : impl Into < Cow < ' static , str > > + tracing:: Value ,
514
+ params : Param ,
515
+ ) -> ProviderResult < Resp >
516
+ where
517
+ Param : RpcSend ,
518
+ Resp : DeserializeOwned + derive_more:: Debug ,
519
+ {
520
+ let span = trace_span ! ( "rpc_call" , rpc_method, id = rand:: random:: <u64 >( ) ) ;
521
+ let _guard = span. enter ( ) ;
522
+ trace ! ( "send request" ) ;
523
+
524
+ let resp = ipc_provider
525
+ . call :: < Param , Resp > ( rpc_method, params)
526
+ . map_err ( ipc_to_provider_error) ;
527
+
528
+ trace ! ( "response received" ) ;
529
+ resp
530
+ }
577
531
578
532
fn ipc_to_provider_error ( e : reipc:: errors:: RpcError ) -> ProviderError {
579
533
ProviderError :: Other ( AnyError :: new ( e) )
0 commit comments