@@ -158,6 +158,8 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
158
158
}, nil
159
159
}
160
160
161
+ // ProcessWithAccessList performs EVM execution and state root computation for a block which is known
162
+ // to contain an access list.
161
163
func (p * StateProcessor ) ProcessWithAccessList (block * types.Block , statedb * state.StateDB , cfg vm.Config ) (chan * ProcessResultWithMetrics , error ) {
162
164
var (
163
165
header = block .Header ()
@@ -179,12 +181,12 @@ func (p *StateProcessor) ProcessWithAccessList(block *types.Block, statedb *stat
179
181
rootCalcErrCh := make (chan error ) // used for communicating if the state root calculation doesn't match the reported root
180
182
pStart := time .Now ()
181
183
var (
182
- tPreprocess time.Duration
184
+ tPreprocess time.Duration // time to create a set of prestates for parallel transaction execution
183
185
tVerifyStart time.Time
184
- tVerify time.Duration
186
+ tVerify time.Duration // time to compute and verify the state root
185
187
tExecStart time.Time
186
- tExec time.Duration
187
- tPostprocess time.Duration
188
+ tExec time.Duration // time to execute block transactions
189
+ tPostprocess time.Duration // time to perform post-transaction execution system calls and withdrawals.
188
190
)
189
191
190
192
// called by resultHandler when all transactions have successfully executed.
@@ -252,9 +254,6 @@ func (p *StateProcessor) ProcessWithAccessList(block *types.Block, statedb *stat
252
254
finalDiff := postTxState .Finalise (true )
253
255
computedDiff .Merge (finalDiff )
254
256
255
- // TODO: at each step, we should only be comparing the "intermediate" state diffs
256
- // not the entire state diff up until that point.
257
-
258
257
if err := bal .ValidateStateDiff (expectedStateDiff , computedDiff ); err != nil {
259
258
return & ProcessResult {
260
259
Error : fmt .Errorf ("post-transaction-execution state transition produced a different diff that what was reported in the BAL" ),
@@ -340,12 +339,12 @@ func (p *StateProcessor) ProcessWithAccessList(block *types.Block, statedb *stat
340
339
execTx := func (ctx context2.Context , tx * types.Transaction , idx int , db * state.StateDB , prestateDiff , expectedDiff * bal.StateDiff ) * txExecResult {
341
340
db .ApplyPrestate (prestateDiff )
342
341
// if an error with another transaction rendered the block invalid, don't proceed with executing this one
343
- // TODO: also interrupt any currently-executing transactions if one failed.
344
342
select {
345
343
case <- ctx .Done ():
346
344
return & txExecResult {err : ctx .Err ()}
347
345
default :
348
346
}
347
+ // TODO: also interrupt any currently-executing transactions if one failed.
349
348
var tracingStateDB = vm .StateDB (db )
350
349
if hooks := cfg .Tracer ; hooks != nil {
351
350
tracingStateDB = state .NewHookedState (db , hooks )
@@ -362,7 +361,7 @@ func (p *StateProcessor) ProcessWithAccessList(block *types.Block, statedb *stat
362
361
db .SetTxSender (sender )
363
362
db .SetTxContext (tx .Hash (), idx )
364
363
365
- evm .StateDB = db // TODO: unsure if need to set this here since the evm should maintain a reference to the db but I recall that adding this fixed some broken tests
364
+ evm .StateDB = db
366
365
gp := new (GasPool )
367
366
gp .SetGas (block .GasLimit ())
368
367
var gasUsed uint64
@@ -398,47 +397,47 @@ func (p *StateProcessor) ProcessWithAccessList(block *types.Block, statedb *stat
398
397
context = NewEVMBlockContext (header , p .chain , nil )
399
398
evm := vm .NewEVM (context , tracingStateDB , p .config , cfg )
400
399
401
- // process beacon-root and parent block system contracts.
402
- // do not include the storage writes in the BAL:
403
- // * beacon root will be provided as a standalone field in the BAL
404
- // * parent block hash is already in the header field of the block
405
-
400
+ // convert the BAL entries into an ordered list of state diffs per index
406
401
intermediateStateDiffs := bal .BuildStateDiffs (block .Body ().AccessList , len (block .Transactions ()))
407
402
preTxDiff := intermediateStateDiffs [0 ]
408
403
409
- totalDiff := bal.StateDiff {make (map [common.Address ]* bal.AccountState )}
410
- var totalDiffs []* bal.StateDiff
411
- for _ , diff := range intermediateStateDiffs {
412
- totalDiff .Merge (diff .Copy ()) // TODO: it shouldn't be necessary to Copy here
413
- totalDiffs = append (totalDiffs , totalDiff .Copy ())
414
- }
415
- statedb .InstantiateWithStateDiffs (& totalDiff )
416
-
417
- computedDiff := & bal.StateDiff {make (map [common.Address ]* bal.AccountState )}
404
+ // validate the correctness of pre-transaction execution state changes
405
+ computedPreTxDiff := & bal.StateDiff {make (map [common.Address ]* bal.AccountState )}
418
406
if beaconRoot := block .BeaconRoot (); beaconRoot != nil {
419
- computedDiff .Merge (ProcessBeaconBlockRoot (* beaconRoot , evm ))
407
+ computedPreTxDiff .Merge (ProcessBeaconBlockRoot (* beaconRoot , evm ))
420
408
}
421
409
if p .config .IsPrague (block .Number (), block .Time ()) || p .config .IsVerkle (block .Number (), block .Time ()) {
422
- computedDiff .Merge (ProcessParentBlockHash (block .ParentHash (), evm ))
410
+ computedPreTxDiff .Merge (ProcessParentBlockHash (block .ParentHash (), evm ))
423
411
}
424
-
425
- if err := bal .ValidateStateDiff (preTxDiff , computedDiff ); err != nil {
412
+ if err := bal .ValidateStateDiff (preTxDiff , computedPreTxDiff ); err != nil {
426
413
return nil , err
427
414
}
428
415
429
- var txPrestates []* state.StateDB
416
+ // compute the aggregate state diff of the block
417
+ totalDiff := bal.StateDiff {make (map [common.Address ]* bal.AccountState )}
418
+ var totalDiffs []* bal.StateDiff
419
+ for _ , diff := range intermediateStateDiffs {
420
+ totalDiff .Merge (diff .Copy ()) // TODO: it shouldn't be necessary to Copy here
421
+ totalDiffs = append (totalDiffs , totalDiff .Copy ())
422
+ }
430
423
431
- // Iterate over and process the individual transactions
424
+ // instantiate a set of StateDBs to be used for executing each transaction in parallel
425
+ statedb .InstantiateWithStateDiffs (& totalDiff )
426
+ var txPrestates []* state.StateDB
432
427
for range block .Transactions () {
433
428
state := statedb .Copy ()
434
429
txPrestates = append (txPrestates , state )
435
430
}
431
+
432
+ // compute the post-tx state prestate (before applying final block system calls and eip-4895 withdrawals)
436
433
postTxState := statedb .Copy ()
437
- postTxState .ApplyStateDiff (totalDiffs [len (totalDiffs )- 2 ])
434
+ postTxState .ApplyPrestate (totalDiffs [len (totalDiffs )- 2 ])
438
435
postTxState .Finalise (true )
439
436
440
437
tPreprocess = time .Since (pStart )
441
438
439
+ // execute transactions and state root calculation in parallel
440
+
442
441
tExecStart = time .Now ()
443
442
go resultHandler (intermediateStateDiffs [len (block .Transactions ())+ 1 ], postTxState )
444
443
var workers errgroup.Group
@@ -455,7 +454,6 @@ func (p *StateProcessor) ProcessWithAccessList(block *types.Block, statedb *stat
455
454
456
455
statedb .ApplyStateDiff (& totalDiff )
457
456
statedb .Finalise (true )
458
- //fmt.Printf("total diff is\n%s\napplied diff is\n%s\n", totalDiff.String(), appliedDiff.String())
459
457
go calcAndVerifyRoot (statedb .Copy (), block , rootCalcErrCh )
460
458
461
459
return resCh , nil
0 commit comments