diff --git a/core/block_access_list_creation.go b/core/block_access_list_creation.go index 4daa9063ec..be51568e1e 100644 --- a/core/block_access_list_creation.go +++ b/core/block_access_list_creation.go @@ -23,15 +23,16 @@ type BlockAccessListTracer struct { // scopes are in the proceeding indices. // When an execution scope terminates in a non-reverting fashion, the changes are // merged into the access list of the parent scope. - accessList *bal.ConstructionBlockAccessList - txIdx uint16 + accessList *bal.ConstructionBlockAccessList + balIdx uint16 + accessListBuilder *bal.AccessListBuilder } // NewBlockAccessListTracer returns an BlockAccessListTracer and a set of hooks func NewBlockAccessListTracer(startIdx int) (*BlockAccessListTracer, *tracing.Hooks) { balTracer := &BlockAccessListTracer{ accessList: bal.NewConstructionBlockAccessList(), - txIdx: uint16(startIdx), + balIdx: uint16(startIdx), } hooks := &tracing.Hooks{ OnTxEnd: balTracer.TxEndHook, @@ -52,61 +53,62 @@ func NewBlockAccessListTracer(startIdx int) (*BlockAccessListTracer, *tracing.Ho return balTracer, wrappedHooks } -// AccessList returns the constructed access list +// AccessList returns the constructed access list. +// 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.Finalise() + a.accessList.Apply(a.balIdx, diff, reads) + a.accessListBuilder = new(bal.AccessListBuilder) return a.accessList } func (a *BlockAccessListTracer) TxEndHook(receipt *types.Receipt, err error) { - a.txIdx++ + diff, reads := a.accessListBuilder.Finalise() + a.accessList.Apply(a.balIdx, diff, reads) + a.accessListBuilder = new(bal.AccessListBuilder) + a.balIdx++ } func (a *BlockAccessListTracer) TxStartHook(vm *tracing.VMContext, tx *types.Transaction, from common.Address) { - if a.txIdx == 0 { - a.txIdx++ + if a.balIdx == 0 { + diff, reads := a.accessListBuilder.Finalise() + a.accessList.Apply(0, diff, reads) + a.accessListBuilder = new(bal.AccessListBuilder) + a.balIdx++ } } func (a *BlockAccessListTracer) OnEnter(depth int, typ byte, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { - a.callAccessLists = append(a.callAccessLists, bal.NewConstructionBlockAccessList()) + a.accessListBuilder.EnterScope() } func (a *BlockAccessListTracer) OnExit(depth int, output []byte, gasUsed uint64, err error, reverted bool) { - // TODO: handle self-destructed accounts here... - - parentAccessList := a.callAccessLists[len(a.callAccessLists)-2] - scopeAccessList := a.callAccessLists[len(a.callAccessLists)-1] - if reverted { - parentAccessList.MergeReads(scopeAccessList) - } else { - parentAccessList.Merge(scopeAccessList) - } - - a.callAccessLists = a.callAccessLists[:len(a.callAccessLists)-1] + a.accessListBuilder.ExitScope(reverted) } func (a *BlockAccessListTracer) OnCodeChange(addr common.Address, prevCodeHash common.Hash, prevCode []byte, codeHash common.Hash, code []byte, reason tracing.CodeChangeReason) { - a.callAccessLists[len(a.callAccessLists)-1].CodeChange(addr, uint16(a.txIdx), code) + a.accessListBuilder.CodeChange(addr, prevCode, code) } func (a *BlockAccessListTracer) OnBalanceChange(addr common.Address, prevBalance, newBalance *big.Int, _ tracing.BalanceChangeReason) { newU256 := new(uint256.Int).SetBytes(newBalance.Bytes()) prevU256 := new(uint256.Int).SetBytes(prevBalance.Bytes()) - a.callAccessLists[len(a.callAccessLists)-1].BalanceChange(addr, prevU256, newU256) + a.accessListBuilder.BalanceChange(addr, prevU256, newU256) } func (a *BlockAccessListTracer) OnNonceChange(addr common.Address, prev uint64, new uint64, reason tracing.NonceChangeReason) { - a.callAccessLists[len(a.callAccessLists)-1].NonceChange(addr, a.txIdx, new) + a.accessListBuilder.NonceChange(addr, prev, new) } func (a *BlockAccessListTracer) OnColdStorageRead(addr common.Address, key common.Hash) { - a.callAccessLists[len(a.callAccessLists)-1].StorageRead(addr, key) + a.accessListBuilder.StorageRead(addr, key) } func (a *BlockAccessListTracer) OnColdAccountRead(addr common.Address) { - a.callAccessLists[len(a.callAccessLists)-1].AccountRead(addr) + a.accessListBuilder.AccountRead(addr) } func (a *BlockAccessListTracer) OnStorageChange(addr common.Address, slot common.Hash, prev common.Hash, new common.Hash) { - a.callAccessLists[len(a.callAccessLists)-1].StorageWrite(a.txIdx, addr, slot, new) + a.accessListBuilder.StorageWrite(addr, slot, prev, new) } diff --git a/core/types/bal/bal.go b/core/types/bal/bal.go index d3cab7057f..5c7502affa 100644 --- a/core/types/bal/bal.go +++ b/core/types/bal/bal.go @@ -65,8 +65,12 @@ type AccessListBuilder struct { accessesStack []map[common.Address]*constructionAccountAccess } -func (c *AccessListBuilder) StorageRead(key common.Hash) { - c.curIdxChanges.StorageRead(key) +func (c *AccessListBuilder) StorageRead(addr common.Address, key common.Hash) { + panic("not implemented") +} + +func (c *AccessListBuilder) AccountRead(addr common.Address) { + panic("not implemented") } func (c *AccessListBuilder) StorageWrite(address common.Address, key, prevVal, newVal common.Hash) { @@ -87,15 +91,15 @@ func (c *AccessListBuilder) StorageWrite(address common.Address, key, prevVal, n acctAccesses.StorageWrite(key, prevVal, newVal) } -func (c *AccessListBuilder) BalanceChange(prev, cur *uint256.Int) { +func (c *AccessListBuilder) BalanceChange(addr common.Address, prev, cur *uint256.Int) { // TODO } -func (c *AccessListBuilder) CodeChange(prev, cur []byte) { +func (c *AccessListBuilder) CodeChange(addr common.Address, prev, cur []byte) { // TODO } -func (c *AccessListBuilder) NonceChange(prev, cur uint64) { +func (c *AccessListBuilder) NonceChange(addr common.Address, prev, cur uint64) { // TODO } @@ -351,12 +355,6 @@ func (c *constructionAccountAccess) StorageRead(key common.Hash) { } func (c *constructionAccountAccess) StorageWrite(key, prevVal, newVal common.Hash) { - if c.prestate.StorageWrites == nil { - c.prestate.StorageWrites = make(map[common.Hash]common.Hash) - } - if _, ok := c.prestate.StorageWrites[key]; !ok { - c.prestate.StorageWrites[key] = prevVal - } if c.storageMutations == nil { c.storageMutations = make(map[common.Hash]common.Hash) } @@ -369,24 +367,15 @@ func (c *constructionAccountAccess) StorageWrite(key, prevVal, newVal common.Has delete(c.storageReads, key) } -func (c *constructionAccountAccess) BalanceChange(prev, cur *uint256.Int) { - if c.prestate.Balance == nil { - c.prestate.Balance = prev - } +func (c *constructionAccountAccess) BalanceChange(cur *uint256.Int) { c.balance = cur } -func (c *constructionAccountAccess) CodeChange(prev, cur []byte) { - if c.prestate.Code == nil { - c.prestate.Code = prev - } +func (c *constructionAccountAccess) CodeChange(cur []byte) { c.code = cur } -func (c *constructionAccountAccess) NonceChange(prev, cur uint64) { - if c.prestate.Nonce == nil { - c.prestate.Nonce = &prev - } +func (c *constructionAccountAccess) NonceChange(cur uint64) { c.nonce = &cur } @@ -416,6 +405,7 @@ func NewConstructionBlockAccessList() *ConstructionBlockAccessList { } } +/* // move this to access list builder func (c *ConstructionBlockAccessList) DiffAt(i int) *StateDiff { res := &StateDiff{make(map[common.Address]*AccountState)} @@ -451,6 +441,7 @@ func (c *ConstructionBlockAccessList) DiffAt(i int) *StateDiff { return res } + func (c *ConstructionBlockAccessList) StateAccesses() StateAccesses { res := make(StateAccesses) for addr, acct := range c.Accounts { @@ -528,6 +519,7 @@ func (c *ConstructionBlockAccessList) Finalise() { c.curIdx++ } + func mergeStorageWrites(cur, next map[common.Hash]map[uint16]common.Hash) map[common.Hash]map[uint16]common.Hash { for slot, _ := range next { if _, ok := cur[slot]; !ok { @@ -589,6 +581,7 @@ func (c *ConstructionBlockAccessList) Merge(childScope *ConstructionBlockAccessL } } } +*/ // Copy returns a deep copy of the access list. func (c *ConstructionBlockAccessList) Copy() *ConstructionBlockAccessList {