From 73f262630aa91597fb1c6ce412ef15183cc44dd3 Mon Sep 17 00:00:00 2001 From: Diego Essaya Date: Thu, 13 Jul 2023 11:00:50 -0300 Subject: [PATCH] refactor: tidy up evm subrealm access --- packages/evm/jsonrpc/evmchain.go | 11 ++----- packages/vm/core/evm/evmimpl/external.go | 9 ++--- packages/vm/core/evm/evmimpl/impl.go | 10 +++--- packages/vm/core/evm/evmimpl/internal.go | 16 ++++----- .../vm/core/evm/evmimpl/iscmagic_state.go | 15 +++++---- packages/vm/core/evm/evmimpl/state.go | 26 --------------- packages/vm/core/evm/evmimpl/stateaccess.go | 8 ++--- packages/vm/core/evm/interface.go | 8 ++--- packages/vm/core/evm/state.go | 33 +++++++++++++++++++ packages/vm/vmimpl/gas.go | 1 - 10 files changed, 68 insertions(+), 69 deletions(-) delete mode 100644 packages/vm/core/evm/evmimpl/state.go create mode 100644 packages/vm/core/evm/state.go diff --git a/packages/evm/jsonrpc/evmchain.go b/packages/evm/jsonrpc/evmchain.go index 79fe6d0f77..4faede9343 100644 --- a/packages/evm/jsonrpc/evmchain.go +++ b/packages/evm/jsonrpc/evmchain.go @@ -699,7 +699,7 @@ func blockchainDB(chainState state.State) *emulator.BlockchainDB { gasFeePolicy := governance.MustGetGasFeePolicy(govPartition) blockKeepAmount := governance.GetBlockKeepAmount(govPartition) return emulator.NewBlockchainDB( - buffered.NewBufferedKVStore(evmStateSubrealmR(chainState)), + buffered.NewBufferedKVStore(evm.EmulatorStateSubrealmR(evm.ContractPartitionR(chainState))), gas.EVMBlockGasLimit(gasLimits, &gasFeePolicy.EVMGasRatio), blockKeepAmount, ) @@ -708,18 +708,11 @@ func blockchainDB(chainState state.State) *emulator.BlockchainDB { func stateDB(chainState state.State) *emulator.StateDB { accountsPartition := subrealm.NewReadOnly(chainState, kv.Key(accounts.Contract.Hname().Bytes())) return emulator.NewStateDB( - buffered.NewBufferedKVStore(evmStateSubrealmR(chainState)), + buffered.NewBufferedKVStore(evm.EmulatorStateSubrealmR(evm.ContractPartitionR(chainState))), newL2Balance(accountsPartition), ) } -func evmStateSubrealmR(chainState state.State) kv.KVStoreReader { - return subrealm.NewReadOnly( - chainState, - kv.Key(evm.Contract.Hname().Bytes())+evm.KeyEVMState, - ) -} - type l2BalanceR struct { accounts kv.KVStoreReader } diff --git a/packages/vm/core/evm/evmimpl/external.go b/packages/vm/core/evm/evmimpl/external.go index df3346bc87..5a44953884 100644 --- a/packages/vm/core/evm/evmimpl/external.go +++ b/packages/vm/core/evm/evmimpl/external.go @@ -6,17 +6,18 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/iotaledger/wasp/packages/kv" + "github.com/iotaledger/wasp/packages/vm/core/evm" "github.com/iotaledger/wasp/packages/vm/core/evm/emulator" ) -func Nonce(state kv.KVStoreReader, addr common.Address) uint64 { - evmState := evmStateSubrealmR(state) +func Nonce(evmPartition kv.KVStoreReader, addr common.Address) uint64 { + evmState := evm.EmulatorStateSubrealmR(evmPartition) stateDBStore := emulator.StateDBSubrealmR(evmState) return emulator.GetNonce(stateDBStore, addr) } -func CheckNonce(state kv.KVStore, addr common.Address, nonce uint64) error { - expected := Nonce(state, addr) +func CheckNonce(evmPartition kv.KVStore, addr common.Address, nonce uint64) error { + expected := Nonce(evmPartition, addr) if nonce != expected { return fmt.Errorf("Invalid nonce, expected %d, got %d", expected, nonce) } diff --git a/packages/vm/core/evm/evmimpl/impl.go b/packages/vm/core/evm/evmimpl/impl.go index a9aba90c8d..4f5d8b80da 100644 --- a/packages/vm/core/evm/evmimpl/impl.go +++ b/packages/vm/core/evm/evmimpl/impl.go @@ -43,7 +43,7 @@ var Processor = evm.Contract.Processor(nil, evm.FuncGetChainID.WithHandler(getChainID), ) -func SetInitialState(state kv.KVStore, evmChainID uint16) { +func SetInitialState(evmPartition kv.KVStore, evmChainID uint16) { // add the standard ISC contract at arbitrary address 0x1074... genesisAlloc := core.GenesisAlloc{} deployMagicContractOnGenesis(genesisAlloc) @@ -54,7 +54,7 @@ func SetInitialState(state kv.KVStore, evmChainID uint16) { Storage: map[common.Hash]common.Hash{}, Balance: nil, } - addToPrivileged(state, iscmagic.ERC20BaseTokensAddress) + addToPrivileged(evmPartition, iscmagic.ERC20BaseTokensAddress) // add the standard ERC721 contract genesisAlloc[iscmagic.ERC721NFTsAddress] = core.GenesisAccount{ @@ -62,13 +62,13 @@ func SetInitialState(state kv.KVStore, evmChainID uint16) { Storage: map[common.Hash]common.Hash{}, Balance: nil, } - addToPrivileged(state, iscmagic.ERC721NFTsAddress) + addToPrivileged(evmPartition, iscmagic.ERC721NFTsAddress) // chain always starts with default gas fee & limits configuration gasLimits := gas.LimitsDefault gasRatio := gas.DefaultFeePolicy().EVMGasRatio emulator.Init( - evmStateSubrealm(state), + evm.EmulatorStateSubrealm(evmPartition), evmChainID, emulator.GasLimits{ Block: gas.EVMBlockGasLimit(gasLimits, &gasRatio), @@ -359,7 +359,7 @@ func registerERC721NFTCollection(ctx isc.Sandbox) dict.Dict { func getChainID(ctx isc.SandboxView) dict.Dict { chainID := emulator.GetChainIDFromBlockChainDBState( emulator.BlockchainDBSubrealmR( - evmStateSubrealmR(ctx.StateR()), + evm.EmulatorStateSubrealmR(ctx.StateR()), ), ) return result(codec.EncodeUint16(chainID)) diff --git a/packages/vm/core/evm/evmimpl/internal.go b/packages/vm/core/evm/evmimpl/internal.go index ce31a7efad..50c687d6e0 100644 --- a/packages/vm/core/evm/evmimpl/internal.go +++ b/packages/vm/core/evm/evmimpl/internal.go @@ -27,8 +27,8 @@ import ( // MintBlock "mints" the Ethereum block after all requests in the ISC // block have been processed. // IMPORTANT: Must only be called from the ISC VM -func MintBlock(state kv.KVStore, chainInfo *isc.ChainInfo, blockTimestamp time.Time) { - createBlockchainDB(state, chainInfo).MintBlock(timestamp(blockTimestamp)) +func MintBlock(evmPartition kv.KVStore, chainInfo *isc.ChainInfo, blockTimestamp time.Time) { + createBlockchainDB(evmPartition, chainInfo).MintBlock(timestamp(blockTimestamp)) } func getTracer(ctx isc.Sandbox) tracers.Tracer { @@ -42,7 +42,7 @@ func getTracer(ctx isc.Sandbox) tracers.Tracer { func createEmulator(ctx isc.Sandbox) *emulator.EVMEmulator { chainInfo := ctx.ChainInfo() return emulator.NewEVMEmulator( - evmStateSubrealm(ctx.State()), + evm.EmulatorStateSubrealm(ctx.State()), timestamp(ctx.Timestamp()), gasLimits(chainInfo), chainInfo.BlockKeepAmount, @@ -51,13 +51,13 @@ func createEmulator(ctx isc.Sandbox) *emulator.EVMEmulator { ) } -func createBlockchainDB(state kv.KVStore, chainInfo *isc.ChainInfo) *emulator.BlockchainDB { - return emulator.NewBlockchainDB(evmStateSubrealm(state), gasLimits(chainInfo).Block, chainInfo.BlockKeepAmount) +func createBlockchainDB(evmPartition kv.KVStore, chainInfo *isc.ChainInfo) *emulator.BlockchainDB { + return emulator.NewBlockchainDB(evm.EmulatorStateSubrealm(evmPartition), gasLimits(chainInfo).Block, chainInfo.BlockKeepAmount) } // IMPORTANT: Must only be called from the ISC VM (when the request is done executing) func AddFailedTx( - state kv.KVStore, + evmPartition kv.KVStore, chainInfo *isc.ChainInfo, tx *types.Transaction, receipt *types.Receipt, @@ -68,9 +68,9 @@ func AddFailedTx( if receipt == nil { panic("nil receipt") } - createBlockchainDB(state, chainInfo).AddTransaction(tx, receipt) + createBlockchainDB(evmPartition, chainInfo).AddTransaction(tx, receipt) // we must also increment the nonce manually since the original request was reverted - emulator.NewStateDB(evmStateSubrealm(state), nil).IncNonce(evmutil.MustGetSender(tx)) + emulator.NewStateDB(evm.EmulatorStateSubrealm(evmPartition), nil).IncNonce(evmutil.MustGetSender(tx)) } func gasLimits(chainInfo *isc.ChainInfo) emulator.GasLimits { diff --git a/packages/vm/core/evm/evmimpl/iscmagic_state.go b/packages/vm/core/evm/evmimpl/iscmagic_state.go index 3bd36e1b19..e8935428ab 100644 --- a/packages/vm/core/evm/evmimpl/iscmagic_state.go +++ b/packages/vm/core/evm/evmimpl/iscmagic_state.go @@ -15,6 +15,7 @@ import ( "github.com/iotaledger/wasp/packages/isc" "github.com/iotaledger/wasp/packages/kv" "github.com/iotaledger/wasp/packages/vm/core/errors/coreerrors" + "github.com/iotaledger/wasp/packages/vm/core/evm" "github.com/iotaledger/wasp/packages/vm/core/evm/iscmagic" ) @@ -30,12 +31,12 @@ func keyPrivileged(addr common.Address) kv.Key { } func isCallerPrivileged(ctx isc.SandboxBase, addr common.Address) bool { - state := iscMagicSubrealmR(ctx.StateR()) + state := evm.ISCMagicSubrealmR(ctx.StateR()) return state.Has(keyPrivileged(addr)) } func addToPrivileged(s kv.KVStore, addr common.Address) { - state := iscMagicSubrealm(s) + state := evm.ISCMagicSubrealm(s) state.Set(keyPrivileged(addr), []byte{1}) } @@ -45,7 +46,7 @@ func keyAllowance(from, to common.Address) kv.Key { } func getAllowance(ctx isc.SandboxBase, from, to common.Address) *isc.Assets { - state := iscMagicSubrealmR(ctx.StateR()) + state := evm.ISCMagicSubrealmR(ctx.StateR()) key := keyAllowance(from, to) return isc.MustAssetsFromBytes(state.Get(key)) } @@ -84,7 +85,7 @@ func addToAllowance(ctx isc.Sandbox, from, to common.Address, add *isc.Assets) { } func withAllowance(ctx isc.Sandbox, from, to common.Address, f func(*isc.Assets)) { - state := iscMagicSubrealm(ctx.State()) + state := evm.ISCMagicSubrealm(ctx.State()) key := keyAllowance(from, to) allowance := isc.MustAssetsFromBytes(state.Get(key)) f(allowance) @@ -94,7 +95,7 @@ func withAllowance(ctx isc.Sandbox, from, to common.Address, f func(*isc.Assets) var errFundsNotAllowed = coreerrors.Register("remaining allowance insufficient").Create() func subtractFromAllowance(ctx isc.Sandbox, from, to common.Address, taken *isc.Assets) *isc.Assets { - state := iscMagicSubrealm(ctx.State()) + state := evm.ISCMagicSubrealm(ctx.State()) key := keyAllowance(from, to) remaining := isc.MustAssetsFromBytes(state.Get(key)) @@ -121,12 +122,12 @@ func keyERC20ExternalNativeTokensAddress(nativeTokenID iotago.NativeTokenID) kv. } func addERC20ExternalNativeTokensAddress(ctx isc.Sandbox, nativeTokenID iotago.NativeTokenID, addr common.Address) { - state := iscMagicSubrealm(ctx.State()) + state := evm.ISCMagicSubrealm(ctx.State()) state.Set(keyERC20ExternalNativeTokensAddress(nativeTokenID), addr.Bytes()) } func getERC20ExternalNativeTokensAddress(ctx isc.SandboxBase, nativeTokenID iotago.NativeTokenID) (ret common.Address, ok bool) { - state := iscMagicSubrealmR(ctx.StateR()) + state := evm.ISCMagicSubrealmR(ctx.StateR()) b := state.Get(keyERC20ExternalNativeTokensAddress(nativeTokenID)) if b == nil { return ret, false diff --git a/packages/vm/core/evm/evmimpl/state.go b/packages/vm/core/evm/evmimpl/state.go deleted file mode 100644 index 1920e7a5a6..0000000000 --- a/packages/vm/core/evm/evmimpl/state.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2020 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -package evmimpl - -import ( - "github.com/iotaledger/wasp/packages/kv" - "github.com/iotaledger/wasp/packages/kv/subrealm" - "github.com/iotaledger/wasp/packages/vm/core/evm" -) - -func evmStateSubrealm(state kv.KVStore) kv.KVStore { - return subrealm.New(state, evm.KeyEVMState) -} - -func evmStateSubrealmR(state kv.KVStoreReader) kv.KVStoreReader { - return subrealm.NewReadOnly(state, evm.KeyEVMState) -} - -func iscMagicSubrealm(state kv.KVStore) kv.KVStore { - return subrealm.New(state, evm.KeyISCMagic) -} - -func iscMagicSubrealmR(state kv.KVStoreReader) kv.KVStoreReader { - return subrealm.NewReadOnly(state, evm.KeyISCMagic) -} diff --git a/packages/vm/core/evm/evmimpl/stateaccess.go b/packages/vm/core/evm/evmimpl/stateaccess.go index 353ceaac28..fad398fcb6 100644 --- a/packages/vm/core/evm/evmimpl/stateaccess.go +++ b/packages/vm/core/evm/evmimpl/stateaccess.go @@ -4,19 +4,17 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/iotaledger/wasp/packages/kv" - "github.com/iotaledger/wasp/packages/kv/subrealm" "github.com/iotaledger/wasp/packages/vm/core/evm" ) type StateAccess struct { - state kv.KVStoreReader + evmPartition kv.KVStoreReader } func NewStateAccess(store kv.KVStoreReader) *StateAccess { - contractState := subrealm.NewReadOnly(store, kv.Key(evm.Contract.Hname().Bytes())) - return &StateAccess{state: contractState} + return &StateAccess{evmPartition: evm.ContractPartitionR(store)} } func (sa *StateAccess) Nonce(addr common.Address) uint64 { - return Nonce(sa.state, addr) + return Nonce(sa.evmPartition, addr) } diff --git a/packages/vm/core/evm/interface.go b/packages/vm/core/evm/interface.go index 24bc82120d..2eecca6cec 100644 --- a/packages/vm/core/evm/interface.go +++ b/packages/vm/core/evm/interface.go @@ -59,9 +59,9 @@ const ( var GasPrice = big.NewInt(0) const ( - // KeyEVMState is the subrealm prefix for the EVM state, used by the emulator - KeyEVMState = "s" + // keyEmulatorState is the subrealm prefix for the data stored by the emulator (StateDB + BlockchainDB) + keyEmulatorState = "s" - // KeyISCMagic is the subrealm prefix for the ISC magic contract - KeyISCMagic = "m" + // keyISCMagic is the subrealm prefix for the ISC magic contract + keyISCMagic = "m" ) diff --git a/packages/vm/core/evm/state.go b/packages/vm/core/evm/state.go new file mode 100644 index 0000000000..30b10ee7db --- /dev/null +++ b/packages/vm/core/evm/state.go @@ -0,0 +1,33 @@ +// Copyright 2020 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +package evm + +import ( + "github.com/iotaledger/wasp/packages/kv" + "github.com/iotaledger/wasp/packages/kv/subrealm" +) + +func ContractPartition(chainState kv.KVStore) kv.KVStore { + return subrealm.New(chainState, kv.Key(Contract.Hname().Bytes())) +} + +func ContractPartitionR(chainState kv.KVStoreReader) kv.KVStoreReader { + return subrealm.NewReadOnly(chainState, kv.Key(Contract.Hname().Bytes())) +} + +func EmulatorStateSubrealm(evmPartition kv.KVStore) kv.KVStore { + return subrealm.New(evmPartition, keyEmulatorState) +} + +func EmulatorStateSubrealmR(evmPartition kv.KVStoreReader) kv.KVStoreReader { + return subrealm.NewReadOnly(evmPartition, keyEmulatorState) +} + +func ISCMagicSubrealm(evmPartition kv.KVStore) kv.KVStore { + return subrealm.New(evmPartition, keyISCMagic) +} + +func ISCMagicSubrealmR(evmPartition kv.KVStoreReader) kv.KVStoreReader { + return subrealm.NewReadOnly(evmPartition, keyISCMagic) +} diff --git a/packages/vm/vmimpl/gas.go b/packages/vm/vmimpl/gas.go index da687808c8..2a7024f74e 100644 --- a/packages/vm/vmimpl/gas.go +++ b/packages/vm/vmimpl/gas.go @@ -29,7 +29,6 @@ func (reqctx *requestContext) GasBurn(burnCode gas.BurnCode, par ...uint64) { if reqctx.gas.burned > reqctx.gas.budgetAdjusted { reqctx.gas.burned = reqctx.gas.budgetAdjusted // do not charge more than the limit set by the request - // debug.PrintStack() panic(vm.ErrGasBudgetExceeded) }