diff --git a/contracts/celo_backend.go b/contracts/celo_backend.go index b6e8e1e008..8c454cf8cd 100644 --- a/contracts/celo_backend.go +++ b/contracts/celo_backend.go @@ -48,8 +48,14 @@ func (b *CeloBackend) CallContract(ctx context.Context, call ethereum.CallMsg, b txCtx := vm.TxContext{} vmConfig := vm.Config{} - readOnlyStateDB := ReadOnlyStateDB{StateDB: b.State} - evm := vm.NewEVM(blockCtx, txCtx, &readOnlyStateDB, b.ChainConfig, vmConfig) + // We can use b.State here without copying or making a snapshot because + // StaticCall won't change the state. It reverts on all state modifying + // operations. + // The "touch" that is caused by a StaticCall is not relevant because + // no Celo chain contains empty accounts. Per EIP-7523, all chains that + // had the Spurious Dragon fork enabled at genesis don't have empty + // accounts, making touches irrelevant. + evm := vm.NewEVM(blockCtx, txCtx, b.State, b.ChainConfig, vmConfig) ret, _, err := evm.StaticCall(vm.AccountRef(evm.Origin), *call.To, call.Data, call.Gas) return ret, err diff --git a/contracts/read_only_statedb.go b/contracts/read_only_statedb.go deleted file mode 100644 index 146f544fa3..0000000000 --- a/contracts/read_only_statedb.go +++ /dev/null @@ -1,131 +0,0 @@ -package contracts - -import ( - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/params" - "github.com/holiman/uint256" -) - -// ReadOnlyStateDB wraps a StateDB to prevent modifications. Using it without copying it is safe. -// -// Only the following methods will be passed through to the original StateDB: -// -// GetState(common.Address, common.Hash) common.Hash -// GetCodeHash(common.Address) common.Hash -// GetCode(common.Address) []byte -// GetCodeSize(common.Address) int -// GetBalance(common.Address) *uint256.Int -// Exists(common.Address) bool -// Empty(common.Address) bool -// -// Gas calculations based on ReadOnlyStateDB will be wrong because the accessed storage slots and addresses are not tracked. -type ReadOnlyStateDB struct { - vm.StateDB -} - -func (r *ReadOnlyStateDB) CreateAccount(common.Address) { - panic("not implemented") -} - -func (r *ReadOnlyStateDB) SubBalance(common.Address, *uint256.Int) { - panic("not implemented") -} - -func (r *ReadOnlyStateDB) AddBalance(_ common.Address, amount *uint256.Int) { - if amount.Cmp(new(uint256.Int)) == 0 { - // Adding zero is safe, so we can return here - return - } - panic("not implemented") -} - -func (r *ReadOnlyStateDB) GetNonce(common.Address) uint64 { - panic("not implemented") -} - -func (r *ReadOnlyStateDB) SetNonce(common.Address, uint64) { - panic("not implemented") -} - -func (r *ReadOnlyStateDB) SetCode(common.Address, []byte) { - panic("not implemented") -} - -func (r *ReadOnlyStateDB) AddRefund(uint64) { - panic("not implemented") -} - -func (r *ReadOnlyStateDB) SubRefund(uint64) { - panic("not implemented") -} - -func (r *ReadOnlyStateDB) GetRefund() uint64 { - panic("not implemented") -} - -func (r *ReadOnlyStateDB) GetCommittedState(common.Address, common.Hash) common.Hash { - panic("not implemented") -} - -func (r *ReadOnlyStateDB) SetState(common.Address, common.Hash, common.Hash) { - panic("not implemented") -} - -func (r *ReadOnlyStateDB) GetTransientState(addr common.Address, key common.Hash) common.Hash { - panic("not implemented") -} - -func (r *ReadOnlyStateDB) SetTransientState(addr common.Address, key, value common.Hash) { - panic("not implemented") -} - -func (r *ReadOnlyStateDB) SelfDestruct(common.Address) { - panic("not implemented") -} - -func (r *ReadOnlyStateDB) HasSelfDestructed(common.Address) bool { - panic("not implemented") -} - -func (r *ReadOnlyStateDB) Selfdestruct6780(common.Address) { - panic("not implemented") -} - -func (r *ReadOnlyStateDB) AddressInAccessList(addr common.Address) bool { - // We don't track access lists - return false -} - -func (r *ReadOnlyStateDB) SlotInAccessList(addr common.Address, slot common.Hash) (addressOk bool, slotOk bool) { - // We don't track access lists - return false, false -} - -func (r *ReadOnlyStateDB) AddAddressToAccessList(addr common.Address) { -} - -func (r *ReadOnlyStateDB) AddSlotToAccessList(addr common.Address, slot common.Hash) { -} - -func (r *ReadOnlyStateDB) Prepare(rules params.Rules, sender, coinbase common.Address, dest *common.Address, precompiles []common.Address, txAccesses types.AccessList) { - panic("not implemented") -} - -func (r *ReadOnlyStateDB) RevertToSnapshot(int) { - // No changes can be done, so reverting is a noop. -} - -func (r *ReadOnlyStateDB) Snapshot() int { - // We use id 0 for the single state this immutable StateDB can have. - return 0 -} - -func (r *ReadOnlyStateDB) AddLog(*types.Log) { - panic("not implemented") -} - -func (r *ReadOnlyStateDB) AddPreimage(common.Hash, []byte) { - panic("not implemented") -}