diff --git a/x/evm/state/accesslist.go b/x/evm/state/accesslist.go index 268abba2be..b7d3cf296f 100644 --- a/x/evm/state/accesslist.go +++ b/x/evm/state/accesslist.go @@ -6,6 +6,9 @@ import ( "github.com/ethereum/go-ethereum/params" ) +// all custom precompiles have an address greater than or equal to this address +var CustomPrecompileStartingAddr = common.HexToAddress("0x0000000000000000000000000000000000001001") + // Forked from go-ethereum, except journaling logic which is unnecessary with cacheKV type accessList struct { @@ -13,41 +16,46 @@ type accessList struct { Slots []map[common.Hash]struct{} } -// deep copy so that changes to a new snapshot won't affect older ones -func (al *accessList) Copy() *accessList { - newAl := &accessList{Addresses: make(map[common.Address]int, len(al.Addresses)), Slots: make([]map[common.Hash]struct{}, 0, len(al.Slots))} - for a, i := range al.Addresses { - newAl.Addresses[a] = i +func (s *DBImpl) AddressInAccessList(addr common.Address) bool { + s.k.PrepareReplayedAddr(s.ctx, addr) + _, ok := s.getCurrentAccessList().Addresses[addr] + if ok { + return true } - for i, slot := range al.Slots { - newAl.Slots = append(newAl.Slots, make(map[common.Hash]struct{}, len(slot))) - for h := range slot { - newAl.Slots[i][h] = struct{}{} + for _, ts := range s.tempStatesHist { + if _, ok := ts.transientAccessLists.Addresses[addr]; ok { + return true } } - return newAl -} - -func (s *DBImpl) AddressInAccessList(addr common.Address) bool { - s.k.PrepareReplayedAddr(s.ctx, addr) - _, ok := s.getAccessList().Addresses[addr] - return ok + return false } func (s *DBImpl) SlotInAccessList(addr common.Address, slot common.Hash) (addressOk bool, slotOk bool) { s.k.PrepareReplayedAddr(s.ctx, addr) - al := s.getAccessList() - idx, ok := al.Addresses[addr] - if ok && idx != -1 { + al := s.getCurrentAccessList() + idx, addrOk := al.Addresses[addr] + if addrOk && idx != -1 { _, slotOk := al.Slots[idx][slot] - return ok, slotOk + if slotOk { + return true, true + } } - return ok, false + for _, ts := range s.tempStatesHist { + idx, ok := ts.transientAccessLists.Addresses[addr] + addrOk = addrOk || ok + if ok && idx != -1 { + _, slotOk := ts.transientAccessLists.Slots[idx][slot] + if slotOk { + return true, true + } + } + } + return addrOk, false } func (s *DBImpl) AddAddressToAccessList(addr common.Address) { s.k.PrepareReplayedAddr(s.ctx, addr) - al := s.getAccessList() + al := s.getCurrentAccessList() defer s.saveAccessList(al) if _, present := al.Addresses[addr]; present { return @@ -57,7 +65,7 @@ func (s *DBImpl) AddAddressToAccessList(addr common.Address) { func (s *DBImpl) AddSlotToAccessList(addr common.Address, slot common.Hash) { s.k.PrepareReplayedAddr(s.ctx, addr) - al := s.getAccessList() + al := s.getCurrentAccessList() defer s.saveAccessList(al) idx, addrPresent := al.Addresses[addr] if !addrPresent || idx == -1 { @@ -87,6 +95,10 @@ func (s *DBImpl) Prepare(_ params.Rules, sender, coinbase common.Address, dest * // If it's a create-tx, the destination will be added inside evm.create } for _, addr := range precompiles { + // skip any custom precompile + if addr.Cmp(CustomPrecompileStartingAddr) >= 0 { + continue + } s.AddAddressToAccessList(addr) } for _, el := range txAccesses { @@ -98,7 +110,7 @@ func (s *DBImpl) Prepare(_ params.Rules, sender, coinbase common.Address, dest * s.AddAddressToAccessList(coinbase) } -func (s *DBImpl) getAccessList() *accessList { +func (s *DBImpl) getCurrentAccessList() *accessList { return s.tempStateCurrent.transientAccessLists } diff --git a/x/evm/state/keys.go b/x/evm/state/keys.go index f99ec0769e..6404c13663 100644 --- a/x/evm/state/keys.go +++ b/x/evm/state/keys.go @@ -9,9 +9,8 @@ var ( // If evm module balance is higher than this value at the end of // the transaction, we need to burn from module balance in order // for this number to align. - GasRefundKey = []byte{0x01} - LogsKey = []byte{0x02} - AccessListKey = []byte{0x03} + GasRefundKey = []byte{0x01} + LogsKey = []byte{0x02} ) /* diff --git a/x/evm/state/state.go b/x/evm/state/state.go index 300ece3cad..7d88551767 100644 --- a/x/evm/state/state.go +++ b/x/evm/state/state.go @@ -97,7 +97,7 @@ func (s *DBImpl) Snapshot() int { s.snapshottedCtxs = append(s.snapshottedCtxs, s.ctx) s.ctx = newCtx s.tempStatesHist = append(s.tempStatesHist, s.tempStateCurrent) - s.tempStateCurrent = NewTemporaryState(s.tempStateCurrent.transientAccessLists.Copy()) + s.tempStateCurrent = NewTemporaryState() return len(s.snapshottedCtxs) - 1 } diff --git a/x/evm/state/statedb.go b/x/evm/state/statedb.go index d80c9bafd9..672d1f4d2d 100644 --- a/x/evm/state/statedb.go +++ b/x/evm/state/statedb.go @@ -46,7 +46,7 @@ func NewDBImpl(ctx sdk.Context, k EVMKeeper, simulation bool) *DBImpl { snapshottedCtxs: []sdk.Context{}, coinbaseAddress: GetCoinbaseAddress(ctx.TxIndex()), simulation: simulation, - tempStateCurrent: NewTemporaryState(&accessList{Addresses: make(map[common.Address]int), Slots: []map[common.Hash]struct{}{}}), + tempStateCurrent: NewTemporaryState(), coinbaseEvmAddress: feeCollector, } s.Snapshot() // take an initial snapshot for GetCommitted @@ -131,7 +131,7 @@ func (s *DBImpl) Copy() vm.StateDB { return &DBImpl{ ctx: newCtx, snapshottedCtxs: append(s.snapshottedCtxs, s.ctx), - tempStateCurrent: NewTemporaryState(s.tempStateCurrent.transientAccessLists.Copy()), + tempStateCurrent: NewTemporaryState(), tempStatesHist: append(s.tempStatesHist, s.tempStateCurrent), k: s.k, coinbaseAddress: s.coinbaseAddress, @@ -203,13 +203,13 @@ type TemporaryState struct { surplus sdk.Int // in wei } -func NewTemporaryState(al *accessList) *TemporaryState { +func NewTemporaryState() *TemporaryState { return &TemporaryState{ logs: []*ethtypes.Log{}, transientStates: make(map[string]map[string]common.Hash), transientAccounts: make(map[string][]byte), transientModuleStates: make(map[string][]byte), - transientAccessLists: al, + transientAccessLists: &accessList{Addresses: make(map[common.Address]int), Slots: []map[common.Hash]struct{}{}}, surplus: utils.Sdk0, } }