diff --git a/core/block_access_list_creation.go b/core/block_access_list_creation.go index 257fa5ce01..84033b741b 100644 --- a/core/block_access_list_creation.go +++ b/core/block_access_list_creation.go @@ -26,13 +26,17 @@ type BlockAccessListTracer struct { accessList *bal.ConstructionBlockAccessList balIdx uint16 accessListBuilder *bal.AccessListBuilder + + idxMutations *bal.StateDiff + idxReads bal.StateAccesses } // NewBlockAccessListTracer returns an BlockAccessListTracer and a set of hooks func NewBlockAccessListTracer(startIdx int) (*BlockAccessListTracer, *tracing.Hooks) { balTracer := &BlockAccessListTracer{ - accessList: bal.NewConstructionBlockAccessList(), - balIdx: uint16(startIdx), + accessList: bal.NewConstructionBlockAccessList(), + balIdx: uint16(startIdx), + accessListBuilder: bal.NewAccessListBuilder(), } hooks := &tracing.Hooks{ OnTxEnd: balTracer.TxEndHook, @@ -57,25 +61,28 @@ func NewBlockAccessListTracer(startIdx int) (*BlockAccessListTracer, *tracing.Ho // It is assumed that this is only called after all the block state changes // have been executed and the block has been finalized. func (a *BlockAccessListTracer) AccessList() *bal.ConstructionBlockAccessList { - diff, reads := a.accessListBuilder.FinaliseIdxChanges() - a.accessList.Apply(a.balIdx, diff, reads) - a.accessListBuilder = new(bal.AccessListBuilder) return a.accessList } +func (a *BlockAccessListTracer) Finalise() { + a.idxMutations, a.idxReads = a.accessListBuilder.FinaliseIdxChanges() + a.accessList.Apply(a.balIdx, a.idxMutations, a.idxReads) + a.accessListBuilder = new(bal.AccessListBuilder) +} + // TODO: I don't like that AccessList and this do slightly different things, // and that they mutate the access list builder (not apparent in the naming of the methods) // // ^ idea: add Finalize() which returns the diff/accesses, also accumulating them in the BAL. // AccessList just returns the constructed BAL. func (a *BlockAccessListTracer) IdxChanges() (*bal.StateDiff, bal.StateAccesses) { - return a.accessListBuilder.FinaliseIdxChanges() + return a.idxMutations, a.idxReads } func (a *BlockAccessListTracer) TxEndHook(receipt *types.Receipt, err error) { - diff, reads := a.accessListBuilder.FinaliseIdxChanges() - a.accessList.Apply(a.balIdx, diff, reads) - a.accessListBuilder = new(bal.AccessListBuilder) + a.idxMutations, a.idxReads = a.accessListBuilder.FinaliseIdxChanges() + a.accessList.Apply(a.balIdx, a.idxMutations, a.idxReads) + a.accessListBuilder = bal.NewAccessListBuilder() a.balIdx++ } @@ -83,7 +90,7 @@ func (a *BlockAccessListTracer) TxStartHook(vm *tracing.VMContext, tx *types.Tra if a.balIdx == 0 { diff, reads := a.accessListBuilder.FinaliseIdxChanges() a.accessList.Apply(0, diff, reads) - a.accessListBuilder = new(bal.AccessListBuilder) + a.accessListBuilder = bal.NewAccessListBuilder() a.balIdx++ } } diff --git a/core/parallel_state_processor.go b/core/parallel_state_processor.go index a59bd75e68..dabed4bbe2 100644 --- a/core/parallel_state_processor.go +++ b/core/parallel_state_processor.go @@ -124,6 +124,7 @@ func (p *ParallelStateProcessor) prepareExecResult(block *types.Block, allStateR p.chain.engine.Finalize(p.chain, header, tracingStateDB, block.Body()) // invoke FinaliseIdxChanges so that withdrawals are accounted for in the state diff postTxState.Finalise(true) + balTracer.Finalise() diff, stateReads := balTracer.IdxChanges() allStateReads.Merge(stateReads) @@ -292,7 +293,6 @@ func (p *ParallelStateProcessor) execTx(block *types.Block, tx *types.Transactio // Process performs EVM execution and state root computation for a block which is known // to contain an access list. func (p *ParallelStateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (*ProcessResultWithMetrics, error) { - fmt.Printf("process block with bal\n%s\n", block.Body().AccessList.String()) var ( header = block.Header() resCh = make(chan *ProcessResultWithMetrics) @@ -332,6 +332,9 @@ func (p *ParallelStateProcessor) Process(block *types.Block, statedb *state.Stat ProcessParentBlockHash(block.ParentHash(), evm) } + // TODO: weird that I have to manually call finalize here + balTracer.Finalise() + diff, stateReads := balTracer.IdxChanges() if err := statedb.BlockAccessList().ValidateStateDiff(0, diff); err != nil { return nil, err diff --git a/core/types/bal/bal.go b/core/types/bal/bal.go index 5e9f2565d6..e89e8d83b8 100644 --- a/core/types/bal/bal.go +++ b/core/types/bal/bal.go @@ -65,12 +65,21 @@ type AccessListBuilder struct { accessesStack []map[common.Address]*constructionAccountAccess } +func NewAccessListBuilder() *AccessListBuilder { + return &AccessListBuilder{ + make(map[common.Address]*AccountState), + []map[common.Address]*constructionAccountAccess{ + make(map[common.Address]*constructionAccountAccess), + }, + } +} + func (c *AccessListBuilder) StorageRead(addr common.Address, key common.Hash) { - panic("not implemented") + //panic("not implemented") } func (c *AccessListBuilder) AccountRead(addr common.Address) { - panic("not implemented") + //panic("not implemented") } func (c *AccessListBuilder) StorageWrite(address common.Address, key, prevVal, newVal common.Hash) { @@ -232,6 +241,9 @@ func (c *ConstructionBlockAccessList) Apply(idx uint16, diff *StateDiff, accesse acctChanges.StorageWrites = make(map[common.Hash]map[uint16]common.Hash) } for key, val := range stateDiff.StorageWrites { + if _, ok := acctChanges.StorageWrites[key]; !ok { + acctChanges.StorageWrites[key] = make(map[uint16]common.Hash) + } acctChanges.StorageWrites[key][idx] = val } }