From 101f470cb143fbef16e61773573f74a77c1ea235 Mon Sep 17 00:00:00 2001 From: beer-1 <147697694+beer-1@users.noreply.github.com> Date: Tue, 19 Nov 2024 19:44:08 +0900 Subject: [PATCH] feat: use memstore instead of block wise transient store (#117) * use memstore instead of block wise transient store * add testing * remove unnecessary sdkCtx * rollback log * fix to set key value with account address * fix comments * fix error handling --- app/ibc-hooks/common_test.go | 1 - app/ibc-hooks/receive_test.go | 3 +- app/keepers/keepers.go | 1 - app/keepers/keys.go | 2 +- x/bank/keeper/common_test.go | 1 - x/evm/contracts/counter/Counter.go | 2 +- x/evm/contracts/counter/Counter.sol | 10 +- x/evm/keeper/common_test.go | 1 - x/evm/keeper/context.go | 47 +++--- x/evm/keeper/fuzz_test.go | 26 +-- x/evm/keeper/keeper.go | 31 ---- x/evm/precompiles/cosmos/common_test.go | 13 +- .../precompiles/erc20_registry/common_test.go | 13 +- x/evm/state/common_test.go | 1 - x/evm/state/context.go | 45 ++++++ x/evm/state/keys.go | 11 ++ x/evm/state/memstore.go | 80 ++++++++++ x/evm/state/snapshot.go | 15 +- x/evm/state/statedb.go | 149 +++++++++--------- x/evm/state/statedb_test.go | 8 + x/evm/types/keys.go | 9 +- 21 files changed, 291 insertions(+), 178 deletions(-) create mode 100644 x/evm/state/context.go create mode 100644 x/evm/state/memstore.go diff --git a/app/ibc-hooks/common_test.go b/app/ibc-hooks/common_test.go index fa5d0db..19414fd 100644 --- a/app/ibc-hooks/common_test.go +++ b/app/ibc-hooks/common_test.go @@ -309,7 +309,6 @@ func _createTestInput( ac, appCodec, runtime.NewKVStoreService(keys[evmtypes.StoreKey]), - runtime.NewTransientStoreService(tkeys[evmtypes.TStoreKey]), accountKeeper, bankKeeper, communityPoolKeeper, diff --git a/app/ibc-hooks/receive_test.go b/app/ibc-hooks/receive_test.go index 9f6265b..fb0f764 100644 --- a/app/ibc-hooks/receive_test.go +++ b/app/ibc-hooks/receive_test.go @@ -18,7 +18,6 @@ import ( nfttransfertypes "github.com/initia-labs/initia/x/ibc/nft-transfer/types" evm_hooks "github.com/initia-labs/minievm/app/ibc-hooks" "github.com/initia-labs/minievm/x/evm/contracts/counter" - "github.com/initia-labs/minievm/x/evm/types" evmtypes "github.com/initia-labs/minievm/x/evm/types" ) @@ -111,7 +110,7 @@ func Test_onReceiveIcs20Packet_memo(t *testing.T) { require.Equal(t, uint256.NewInt(1).Bytes32(), [32]byte(queryRes)) // check allowance - erc20Addr, err := types.DenomToContractAddr(ctx, input.EVMKeeper, localDenom) + erc20Addr, err := evmtypes.DenomToContractAddr(ctx, input.EVMKeeper, localDenom) require.NoError(t, err) queryInputBz, err = input.EVMKeeper.ERC20Keeper().GetERC20ABI().Pack("allowance", common.BytesToAddress(intermediateSender.Bytes()), contractAddr) require.NoError(t, err) diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index 89a88aa..d6d2b35 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -553,7 +553,6 @@ func NewAppKeeper( ac, appCodec, runtime.NewKVStoreService(appKeepers.keys[evmtypes.StoreKey]), - runtime.NewTransientStoreService(appKeepers.tkeys[evmtypes.TStoreKey]), accountKeeper, bankKeeper, communityPoolKeeper, diff --git a/app/keepers/keys.go b/app/keepers/keys.go index 54aa290..a2d62a4 100644 --- a/app/keepers/keys.go +++ b/app/keepers/keys.go @@ -57,7 +57,7 @@ func (appKeepers *AppKeepers) GenerateKeys() { ) // Define transient store keys - appKeepers.tkeys = storetypes.NewTransientStoreKeys(evmtypes.TStoreKey, forwardingtypes.TransientStoreKey) + appKeepers.tkeys = storetypes.NewTransientStoreKeys(forwardingtypes.TransientStoreKey) // MemKeys are for information that is stored only in RAM. appKeepers.memKeys = storetypes.NewMemoryStoreKeys(capabilitytypes.MemStoreKey) diff --git a/x/bank/keeper/common_test.go b/x/bank/keeper/common_test.go index 11b2f4b..faf22c3 100644 --- a/x/bank/keeper/common_test.go +++ b/x/bank/keeper/common_test.go @@ -301,7 +301,6 @@ func _createTestInput( ac, appCodec, runtime.NewKVStoreService(keys[evmtypes.StoreKey]), - runtime.NewTransientStoreService(tkeys[evmtypes.TStoreKey]), accountKeeper, bankKeeper, communityPoolKeeper, diff --git a/x/evm/contracts/counter/Counter.go b/x/evm/contracts/counter/Counter.go index bec8530..e7255c8 100644 --- a/x/evm/contracts/counter/Counter.go +++ b/x/evm/contracts/counter/Counter.go @@ -32,7 +32,7 @@ var ( // CounterMetaData contains all meta data concerning the Counter contract. var CounterMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"StringsInsufficientHexLength\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"callback_id\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"callback_received\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldCount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newCount\",\"type\":\"uint256\"}],\"name\":\"increased\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"n\",\"type\":\"uint64\"}],\"name\":\"recursive_called\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"callback_id\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"callback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"exec_msg\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"call_revert\",\"type\":\"bool\"}],\"name\":\"execute_cosmos\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"exec_msg\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"allow_failure\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"callback_id\",\"type\":\"uint64\"}],\"name\":\"execute_cosmos_with_options\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"n\",\"type\":\"uint64\"}],\"name\":\"get_blockhash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"callback_id\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"ibc_ack\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"callback_id\",\"type\":\"uint64\"}],\"name\":\"ibc_timeout\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"increase\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"num\",\"type\":\"uint64\"}],\"name\":\"increase_for_fuzz\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"path\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"req\",\"type\":\"string\"}],\"name\":\"query_cosmos\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"result\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"n\",\"type\":\"uint64\"}],\"name\":\"recursive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60806040526119d5806100115f395ff3fe60806040526004361061009b575f3560e01c8063619368951161006357806361936895146101695780637876da7514610191578063ac7fde5f146101b9578063c31925a7146101f5578063cad235541461021d578063e8927fbc146102595761009b565b806306661abd1461009f5780630d4f1f9d146100c957806324c68fce146100f15780632607baf81461011957806331a503f014610141575b5f80fd5b3480156100aa575f80fd5b506100b3610263565b6040516100c09190610d0b565b60405180910390f35b3480156100d4575f80fd5b506100ef60048036038101906100ea9190610da7565b610268565b005b3480156100fc575f80fd5b5061011760048036038101906101129190610f21565b6102af565b005b348015610124575f80fd5b5061013f600480360381019061013a9190610f7b565b61036f565b005b34801561014c575f80fd5b5061016760048036038101906101629190610f7b565b6103a6565b005b348015610174575f80fd5b5061018f600480360381019061018a9190610f7b565b6103ca565b005b34801561019c575f80fd5b506101b760048036038101906101b29190610fa6565b61051d565b005b3480156101c4575f80fd5b506101df60048036038101906101da9190610f7b565b6105bf565b6040516101ec919061102a565b60405180910390f35b348015610200575f80fd5b5061021b60048036038101906102169190610da7565b6105d3565b005b348015610228575f80fd5b50610243600480360381019061023e9190611043565b610610565b6040516102509190611119565b60405180910390f35b610261610699565b005b5f5481565b8015610294578167ffffffffffffffff165f808282546102889190611166565b925050819055506102ab565b5f808154809291906102a590611199565b91905055505b5050565b60f173ffffffffffffffffffffffffffffffffffffffff1663d46f64e6836040518263ffffffff1660e01b81526004016102e99190611119565b6020604051808303815f875af1158015610305573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061032991906111f4565b50801561036b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103629061128f565b60405180910390fd5b5050565b5f5b8167ffffffffffffffff168167ffffffffffffffff1610156103a257610395610699565b8080600101915050610371565b5050565b8067ffffffffffffffff165f808282546103c09190611166565b9250508190555050565b7f4475bbd12ef452e28d39c4cb77494d85136c2d89ca1354b52188d4aaa8f4ba51816040516103f991906112bc565b60405180910390a15f8167ffffffffffffffff16031561051a5760f173ffffffffffffffffffffffffffffffffffffffff1663d46f64e6610439836106f8565b6040518263ffffffff1660e01b81526004016104559190611119565b6020604051808303815f875af1158015610471573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061049591906111f4565b5060f173ffffffffffffffffffffffffffffffffffffffff1663d46f64e66104bc836106f8565b6040518263ffffffff1660e01b81526004016104d89190611119565b6020604051808303815f875af11580156104f4573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061051891906111f4565b505b50565b60f173ffffffffffffffffffffffffffffffffffffffff16636c4f6bd584604051806040016040528086151581526020018567ffffffffffffffff168152506040518363ffffffff1660e01b8152600401610579929190611320565b6020604051808303815f875af1158015610595573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105b991906111f4565b50505050565b5f8167ffffffffffffffff16409050919050565b7fa019c7431cdfd7ba63501ffa1ba7d8f2a028e447653a5af5a96077e5038e0339828260405161060492919061135d565b60405180910390a15050565b606060f173ffffffffffffffffffffffffffffffffffffffff1663cad2355484846040518363ffffffff1660e01b815260040161064e929190611384565b5f604051808303815f875af1158015610669573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906106919190611427565b905092915050565b5f808154809291906106aa90611199565b91905055507f61996fe196f72cb598c483e896a1221263a28bb630480aa89495f737d4a8e3df60015f546106de919061146e565b5f546040516106ee9291906114a1565b60405180910390a1565b606060f173ffffffffffffffffffffffffffffffffffffffff16636af32a55306040518263ffffffff1660e01b81526004016107349190611507565b5f604051808303815f875af115801561074f573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906107779190611427565b61078030610804565b6107dc636193689560e01b6001866107989190611520565b6040516020016107a891906112bc565b6040516020818303038152906040526040516020016107c89291906115ea565b604051602081830303815290604052610831565b6040516020016107ee93929190611877565b6040516020818303038152906040529050919050565b606061082a8273ffffffffffffffffffffffffffffffffffffffff16601460ff16610ab5565b9050919050565b60605f6002808451610843919061190a565b61084d9190611166565b67ffffffffffffffff81111561086657610865610dfd565b5b6040519080825280601f01601f1916602001820160405280156108985781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000815f815181106108cf576108ce61194b565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106109325761093161194b565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f5b8351811015610aab575f84828151811061097f5761097e61194b565b5b602001015160f81c60f81b60f81c90507f303132333435363738396162636465660000000000000000000000000000000060048260ff16901c60ff16601081106109cc576109cb61194b565b5b1a60f81b83600280850201815181106109e8576109e761194b565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f3031323334353637383961626364656600000000000000000000000000000000600f821660ff1660108110610a4f57610a4e61194b565b5b1a60f81b836002600160028602010181518110610a6f57610a6e61194b565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a905350508080600101915050610962565b5080915050919050565b60605f8390505f6002846002610acb919061190a565b610ad59190611166565b67ffffffffffffffff811115610aee57610aed610dfd565b5b6040519080825280601f01601f191660200182016040528015610b205781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000815f81518110610b5757610b5661194b565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110610bba57610bb961194b565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f6001856002610bf8919061190a565b610c029190611166565b90505b6001811115610ca1577f3031323334353637383961626364656600000000000000000000000000000000600f841660108110610c4457610c4361194b565b5b1a60f81b828281518110610c5b57610c5a61194b565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a905350600483901c925080610c9a90611978565b9050610c05565b505f8214610ce85784846040517fe22e27eb000000000000000000000000000000000000000000000000000000008152600401610cdf9291906114a1565b60405180910390fd5b809250505092915050565b5f819050919050565b610d0581610cf3565b82525050565b5f602082019050610d1e5f830184610cfc565b92915050565b5f604051905090565b5f80fd5b5f80fd5b5f67ffffffffffffffff82169050919050565b610d5181610d35565b8114610d5b575f80fd5b50565b5f81359050610d6c81610d48565b92915050565b5f8115159050919050565b610d8681610d72565b8114610d90575f80fd5b50565b5f81359050610da181610d7d565b92915050565b5f8060408385031215610dbd57610dbc610d2d565b5b5f610dca85828601610d5e565b9250506020610ddb85828601610d93565b9150509250929050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610e3382610ded565b810181811067ffffffffffffffff82111715610e5257610e51610dfd565b5b80604052505050565b5f610e64610d24565b9050610e708282610e2a565b919050565b5f67ffffffffffffffff821115610e8f57610e8e610dfd565b5b610e9882610ded565b9050602081019050919050565b828183375f83830152505050565b5f610ec5610ec084610e75565b610e5b565b905082815260208101848484011115610ee157610ee0610de9565b5b610eec848285610ea5565b509392505050565b5f82601f830112610f0857610f07610de5565b5b8135610f18848260208601610eb3565b91505092915050565b5f8060408385031215610f3757610f36610d2d565b5b5f83013567ffffffffffffffff811115610f5457610f53610d31565b5b610f6085828601610ef4565b9250506020610f7185828601610d93565b9150509250929050565b5f60208284031215610f9057610f8f610d2d565b5b5f610f9d84828501610d5e565b91505092915050565b5f805f60608486031215610fbd57610fbc610d2d565b5b5f84013567ffffffffffffffff811115610fda57610fd9610d31565b5b610fe686828701610ef4565b9350506020610ff786828701610d93565b925050604061100886828701610d5e565b9150509250925092565b5f819050919050565b61102481611012565b82525050565b5f60208201905061103d5f83018461101b565b92915050565b5f806040838503121561105957611058610d2d565b5b5f83013567ffffffffffffffff81111561107657611075610d31565b5b61108285828601610ef4565b925050602083013567ffffffffffffffff8111156110a3576110a2610d31565b5b6110af85828601610ef4565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f6110eb826110b9565b6110f581856110c3565b93506111058185602086016110d3565b61110e81610ded565b840191505092915050565b5f6020820190508181035f83015261113181846110e1565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61117082610cf3565b915061117b83610cf3565b925082820190508082111561119357611192611139565b5b92915050565b5f6111a382610cf3565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036111d5576111d4611139565b5b600182019050919050565b5f815190506111ee81610d7d565b92915050565b5f6020828403121561120957611208610d2d565b5b5f611216848285016111e0565b91505092915050565b7f72657665727420726561736f6e2064756d6d792076616c756520666f722074655f8201527f7374000000000000000000000000000000000000000000000000000000000000602082015250565b5f6112796022836110c3565b91506112848261121f565b604082019050919050565b5f6020820190508181035f8301526112a68161126d565b9050919050565b6112b681610d35565b82525050565b5f6020820190506112cf5f8301846112ad565b92915050565b6112de81610d72565b82525050565b6112ed81610d35565b82525050565b604082015f8201516113075f8501826112d5565b50602082015161131a60208501826112e4565b50505050565b5f6060820190508181035f83015261133881856110e1565b905061134760208301846112f3565b9392505050565b61135781610d72565b82525050565b5f6040820190506113705f8301856112ad565b61137d602083018461134e565b9392505050565b5f6040820190508181035f83015261139c81856110e1565b905081810360208301526113b081846110e1565b90509392505050565b5f6113cb6113c684610e75565b610e5b565b9050828152602081018484840111156113e7576113e6610de9565b5b6113f28482856110d3565b509392505050565b5f82601f83011261140e5761140d610de5565b5b815161141e8482602086016113b9565b91505092915050565b5f6020828403121561143c5761143b610d2d565b5b5f82015167ffffffffffffffff81111561145957611458610d31565b5b611465848285016113fa565b91505092915050565b5f61147882610cf3565b915061148383610cf3565b925082820390508181111561149b5761149a611139565b5b92915050565b5f6040820190506114b45f830185610cfc565b6114c16020830184610cfc565b9392505050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6114f1826114c8565b9050919050565b611501816114e7565b82525050565b5f60208201905061151a5f8301846114f8565b92915050565b5f61152a82610d35565b915061153583610d35565b9250828203905067ffffffffffffffff81111561155557611554611139565b5b92915050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b5f819050919050565b6115a061159b8261155b565b611586565b82525050565b5f81519050919050565b5f81905092915050565b5f6115c4826115a6565b6115ce81856115b0565b93506115de8185602086016110d3565b80840191505092915050565b5f6115f5828561158f565b60048201915061160582846115ba565b91508190509392505050565b5f81905092915050565b7f7b224074797065223a20222f6d696e6965766d2e65766d2e76312e4d736743615f8201527f6c6c222c00000000000000000000000000000000000000000000000000000000602082015250565b5f611675602483611611565b91506116808261161b565b602482019050919050565b7f2273656e646572223a20220000000000000000000000000000000000000000005f82015250565b5f6116bf600b83611611565b91506116ca8261168b565b600b82019050919050565b5f6116df826110b9565b6116e98185611611565b93506116f98185602086016110d3565b80840191505092915050565b7f222c0000000000000000000000000000000000000000000000000000000000005f82015250565b5f611739600283611611565b915061174482611705565b600282019050919050565b7f22636f6e74726163745f61646472223a202200000000000000000000000000005f82015250565b5f611783601283611611565b915061178e8261174f565b601282019050919050565b7f22696e707574223a2022000000000000000000000000000000000000000000005f82015250565b5f6117cd600a83611611565b91506117d882611799565b600a82019050919050565b7f2276616c7565223a202230222c000000000000000000000000000000000000005f82015250565b5f611817600d83611611565b9150611822826117e3565b600d82019050919050565b7f226163636573735f6c697374223a205b5d7d00000000000000000000000000005f82015250565b5f611861601283611611565b915061186c8261182d565b601282019050919050565b5f61188182611669565b915061188c826116b3565b915061189882866116d5565b91506118a38261172d565b91506118ae82611777565b91506118ba82856116d5565b91506118c58261172d565b91506118d0826117c1565b91506118dc82846116d5565b91506118e78261172d565b91506118f28261180b565b91506118fd82611855565b9150819050949350505050565b5f61191482610cf3565b915061191f83610cf3565b925082820261192d81610cf3565b9150828204841483151761194457611943611139565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f61198282610cf3565b91505f820361199457611993611139565b5b60018203905091905056fea26469706673582212206d5cf4b512edb5d7b357c68848de57b6e0c91fa149dd41462cae53686cb7e44d64736f6c63430008190033", + Bin: "0x60806040526119d1806100115f395ff3fe60806040526004361061009b575f3560e01c8063619368951161006357806361936895146101695780637876da7514610191578063ac7fde5f146101b9578063c31925a7146101f5578063cad235541461021d578063e8927fbc146102595761009b565b806306661abd1461009f5780630d4f1f9d146100c957806324c68fce146100f15780632607baf81461011957806331a503f014610141575b5f80fd5b3480156100aa575f80fd5b506100b3610263565b6040516100c09190610d07565b60405180910390f35b3480156100d4575f80fd5b506100ef60048036038101906100ea9190610da3565b610268565b005b3480156100fc575f80fd5b5061011760048036038101906101129190610f1d565b6102af565b005b348015610124575f80fd5b5061013f600480360381019061013a9190610f77565b61036f565b005b34801561014c575f80fd5b5061016760048036038101906101629190610f77565b6103a2565b005b348015610174575f80fd5b5061018f600480360381019061018a9190610f77565b6103c6565b005b34801561019c575f80fd5b506101b760048036038101906101b29190610fa2565b610519565b005b3480156101c4575f80fd5b506101df60048036038101906101da9190610f77565b6105bb565b6040516101ec9190611026565b60405180910390f35b348015610200575f80fd5b5061021b60048036038101906102169190610da3565b6105cf565b005b348015610228575f80fd5b50610243600480360381019061023e919061103f565b61060c565b6040516102509190611115565b60405180910390f35b610261610695565b005b5f5481565b8015610294578167ffffffffffffffff165f808282546102889190611162565b925050819055506102ab565b5f808154809291906102a590611195565b91905055505b5050565b60f173ffffffffffffffffffffffffffffffffffffffff1663d46f64e6836040518263ffffffff1660e01b81526004016102e99190611115565b6020604051808303815f875af1158015610305573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061032991906111f0565b50801561036b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103629061128b565b60405180910390fd5b5050565b5f8167ffffffffffffffff16031561039f57610389610695565b61039e60018261039991906112a9565b61036f565b5b50565b8067ffffffffffffffff165f808282546103bc9190611162565b9250508190555050565b7f4475bbd12ef452e28d39c4cb77494d85136c2d89ca1354b52188d4aaa8f4ba51816040516103f591906112f3565b60405180910390a15f8167ffffffffffffffff1603156105165760f173ffffffffffffffffffffffffffffffffffffffff1663d46f64e6610435836106f4565b6040518263ffffffff1660e01b81526004016104519190611115565b6020604051808303815f875af115801561046d573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061049191906111f0565b5060f173ffffffffffffffffffffffffffffffffffffffff1663d46f64e66104b8836106f4565b6040518263ffffffff1660e01b81526004016104d49190611115565b6020604051808303815f875af11580156104f0573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061051491906111f0565b505b50565b60f173ffffffffffffffffffffffffffffffffffffffff16636c4f6bd584604051806040016040528086151581526020018567ffffffffffffffff168152506040518363ffffffff1660e01b8152600401610575929190611357565b6020604051808303815f875af1158015610591573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105b591906111f0565b50505050565b5f8167ffffffffffffffff16409050919050565b7fa019c7431cdfd7ba63501ffa1ba7d8f2a028e447653a5af5a96077e5038e03398282604051610600929190611394565b60405180910390a15050565b606060f173ffffffffffffffffffffffffffffffffffffffff1663cad2355484846040518363ffffffff1660e01b815260040161064a9291906113bb565b5f604051808303815f875af1158015610665573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f8201168201806040525081019061068d919061145e565b905092915050565b5f808154809291906106a690611195565b91905055507f61996fe196f72cb598c483e896a1221263a28bb630480aa89495f737d4a8e3df60015f546106da91906114a5565b5f546040516106ea9291906114d8565b60405180910390a1565b606060f173ffffffffffffffffffffffffffffffffffffffff16636af32a55306040518263ffffffff1660e01b8152600401610730919061153e565b5f604051808303815f875af115801561074b573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190610773919061145e565b61077c30610800565b6107d8636193689560e01b60018661079491906112a9565b6040516020016107a491906112f3565b6040516020818303038152906040526040516020016107c49291906115e6565b60405160208183030381529060405261082d565b6040516020016107ea93929190611873565b6040516020818303038152906040529050919050565b60606108268273ffffffffffffffffffffffffffffffffffffffff16601460ff16610ab1565b9050919050565b60605f600280845161083f9190611906565b6108499190611162565b67ffffffffffffffff81111561086257610861610df9565b5b6040519080825280601f01601f1916602001820160405280156108945781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000815f815181106108cb576108ca611947565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061092e5761092d611947565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f5b8351811015610aa7575f84828151811061097b5761097a611947565b5b602001015160f81c60f81b60f81c90507f303132333435363738396162636465660000000000000000000000000000000060048260ff16901c60ff16601081106109c8576109c7611947565b5b1a60f81b83600280850201815181106109e4576109e3611947565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f3031323334353637383961626364656600000000000000000000000000000000600f821660ff1660108110610a4b57610a4a611947565b5b1a60f81b836002600160028602010181518110610a6b57610a6a611947565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535050808060010191505061095e565b5080915050919050565b60605f8390505f6002846002610ac79190611906565b610ad19190611162565b67ffffffffffffffff811115610aea57610ae9610df9565b5b6040519080825280601f01601f191660200182016040528015610b1c5781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000815f81518110610b5357610b52611947565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110610bb657610bb5611947565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f6001856002610bf49190611906565b610bfe9190611162565b90505b6001811115610c9d577f3031323334353637383961626364656600000000000000000000000000000000600f841660108110610c4057610c3f611947565b5b1a60f81b828281518110610c5757610c56611947565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a905350600483901c925080610c9690611974565b9050610c01565b505f8214610ce45784846040517fe22e27eb000000000000000000000000000000000000000000000000000000008152600401610cdb9291906114d8565b60405180910390fd5b809250505092915050565b5f819050919050565b610d0181610cef565b82525050565b5f602082019050610d1a5f830184610cf8565b92915050565b5f604051905090565b5f80fd5b5f80fd5b5f67ffffffffffffffff82169050919050565b610d4d81610d31565b8114610d57575f80fd5b50565b5f81359050610d6881610d44565b92915050565b5f8115159050919050565b610d8281610d6e565b8114610d8c575f80fd5b50565b5f81359050610d9d81610d79565b92915050565b5f8060408385031215610db957610db8610d29565b5b5f610dc685828601610d5a565b9250506020610dd785828601610d8f565b9150509250929050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610e2f82610de9565b810181811067ffffffffffffffff82111715610e4e57610e4d610df9565b5b80604052505050565b5f610e60610d20565b9050610e6c8282610e26565b919050565b5f67ffffffffffffffff821115610e8b57610e8a610df9565b5b610e9482610de9565b9050602081019050919050565b828183375f83830152505050565b5f610ec1610ebc84610e71565b610e57565b905082815260208101848484011115610edd57610edc610de5565b5b610ee8848285610ea1565b509392505050565b5f82601f830112610f0457610f03610de1565b5b8135610f14848260208601610eaf565b91505092915050565b5f8060408385031215610f3357610f32610d29565b5b5f83013567ffffffffffffffff811115610f5057610f4f610d2d565b5b610f5c85828601610ef0565b9250506020610f6d85828601610d8f565b9150509250929050565b5f60208284031215610f8c57610f8b610d29565b5b5f610f9984828501610d5a565b91505092915050565b5f805f60608486031215610fb957610fb8610d29565b5b5f84013567ffffffffffffffff811115610fd657610fd5610d2d565b5b610fe286828701610ef0565b9350506020610ff386828701610d8f565b925050604061100486828701610d5a565b9150509250925092565b5f819050919050565b6110208161100e565b82525050565b5f6020820190506110395f830184611017565b92915050565b5f806040838503121561105557611054610d29565b5b5f83013567ffffffffffffffff81111561107257611071610d2d565b5b61107e85828601610ef0565b925050602083013567ffffffffffffffff81111561109f5761109e610d2d565b5b6110ab85828601610ef0565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f6110e7826110b5565b6110f181856110bf565b93506111018185602086016110cf565b61110a81610de9565b840191505092915050565b5f6020820190508181035f83015261112d81846110dd565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61116c82610cef565b915061117783610cef565b925082820190508082111561118f5761118e611135565b5b92915050565b5f61119f82610cef565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036111d1576111d0611135565b5b600182019050919050565b5f815190506111ea81610d79565b92915050565b5f6020828403121561120557611204610d29565b5b5f611212848285016111dc565b91505092915050565b7f72657665727420726561736f6e2064756d6d792076616c756520666f722074655f8201527f7374000000000000000000000000000000000000000000000000000000000000602082015250565b5f6112756022836110bf565b91506112808261121b565b604082019050919050565b5f6020820190508181035f8301526112a281611269565b9050919050565b5f6112b382610d31565b91506112be83610d31565b9250828203905067ffffffffffffffff8111156112de576112dd611135565b5b92915050565b6112ed81610d31565b82525050565b5f6020820190506113065f8301846112e4565b92915050565b61131581610d6e565b82525050565b61132481610d31565b82525050565b604082015f82015161133e5f85018261130c565b506020820151611351602085018261131b565b50505050565b5f6060820190508181035f83015261136f81856110dd565b905061137e602083018461132a565b9392505050565b61138e81610d6e565b82525050565b5f6040820190506113a75f8301856112e4565b6113b46020830184611385565b9392505050565b5f6040820190508181035f8301526113d381856110dd565b905081810360208301526113e781846110dd565b90509392505050565b5f6114026113fd84610e71565b610e57565b90508281526020810184848401111561141e5761141d610de5565b5b6114298482856110cf565b509392505050565b5f82601f83011261144557611444610de1565b5b81516114558482602086016113f0565b91505092915050565b5f6020828403121561147357611472610d29565b5b5f82015167ffffffffffffffff8111156114905761148f610d2d565b5b61149c84828501611431565b91505092915050565b5f6114af82610cef565b91506114ba83610cef565b92508282039050818111156114d2576114d1611135565b5b92915050565b5f6040820190506114eb5f830185610cf8565b6114f86020830184610cf8565b9392505050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611528826114ff565b9050919050565b6115388161151e565b82525050565b5f6020820190506115515f83018461152f565b92915050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b5f819050919050565b61159c61159782611557565b611582565b82525050565b5f81519050919050565b5f81905092915050565b5f6115c0826115a2565b6115ca81856115ac565b93506115da8185602086016110cf565b80840191505092915050565b5f6115f1828561158b565b60048201915061160182846115b6565b91508190509392505050565b5f81905092915050565b7f7b224074797065223a20222f6d696e6965766d2e65766d2e76312e4d736743615f8201527f6c6c222c00000000000000000000000000000000000000000000000000000000602082015250565b5f61167160248361160d565b915061167c82611617565b602482019050919050565b7f2273656e646572223a20220000000000000000000000000000000000000000005f82015250565b5f6116bb600b8361160d565b91506116c682611687565b600b82019050919050565b5f6116db826110b5565b6116e5818561160d565b93506116f58185602086016110cf565b80840191505092915050565b7f222c0000000000000000000000000000000000000000000000000000000000005f82015250565b5f61173560028361160d565b915061174082611701565b600282019050919050565b7f22636f6e74726163745f61646472223a202200000000000000000000000000005f82015250565b5f61177f60128361160d565b915061178a8261174b565b601282019050919050565b7f22696e707574223a2022000000000000000000000000000000000000000000005f82015250565b5f6117c9600a8361160d565b91506117d482611795565b600a82019050919050565b7f2276616c7565223a202230222c000000000000000000000000000000000000005f82015250565b5f611813600d8361160d565b915061181e826117df565b600d82019050919050565b7f226163636573735f6c697374223a205b5d7d00000000000000000000000000005f82015250565b5f61185d60128361160d565b915061186882611829565b601282019050919050565b5f61187d82611665565b9150611888826116af565b915061189482866116d1565b915061189f82611729565b91506118aa82611773565b91506118b682856116d1565b91506118c182611729565b91506118cc826117bd565b91506118d882846116d1565b91506118e382611729565b91506118ee82611807565b91506118f982611851565b9150819050949350505050565b5f61191082610cef565b915061191b83610cef565b925082820261192981610cef565b915082820484148315176119405761193f611135565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f61197e82610cef565b91505f82036119905761198f611135565b5b60018203905091905056fea264697066735822122002fdd746520e9ea3c08dc13379c91b06f0b678812e4f33dd24725e9a9771685d64736f6c63430008190033", } // CounterABI is the input ABI used to generate the binding from. diff --git a/x/evm/contracts/counter/Counter.sol b/x/evm/contracts/counter/Counter.sol index 71c1459..1bcea61 100644 --- a/x/evm/contracts/counter/Counter.sol +++ b/x/evm/contracts/counter/Counter.sol @@ -14,15 +14,17 @@ contract Counter is IIBCAsyncCallback { constructor() payable {} - function increase_for_fuzz(uint64 num) external { - for (uint64 i = 0; i < num; i++) { - increase(); + function increase_for_fuzz(uint64 num) public { + if (num == 0) { + return; } + + increase(); + increase_for_fuzz(num - 1); } function increase() public payable { count++; - emit increased(count - 1, count); } diff --git a/x/evm/keeper/common_test.go b/x/evm/keeper/common_test.go index 1673422..6dbd950 100644 --- a/x/evm/keeper/common_test.go +++ b/x/evm/keeper/common_test.go @@ -262,7 +262,6 @@ func _createTestInput( ac, appCodec, runtime.NewKVStoreService(keys[evmtypes.StoreKey]), - runtime.NewTransientStoreService(tkeys[evmtypes.TStoreKey]), accountKeeper, bankKeeper, communityPoolKeeper, diff --git a/x/evm/keeper/context.go b/x/evm/keeper/context.go index 18eefb0..8720544 100644 --- a/x/evm/keeper/context.go +++ b/x/evm/keeper/context.go @@ -27,11 +27,8 @@ import ( func (k Keeper) NewStateDB(ctx context.Context, evm *vm.EVM, fee types.Fee) (*evmstate.StateDB, error) { return evmstate.NewStateDB( // delegate gas meter to the EVM - sdk.UnwrapSDKContext(ctx).WithGasMeter(storetypes.NewInfiniteGasMeter()), k.Logger(ctx), - k.accountKeeper, k.VMStore, k.TransientVMStore, k.TransientCreated, - k.TransientSelfDestruct, k.TransientLogs, k.TransientLogSize, - k.TransientAccessList, k.TransientRefund, k.execIndex, - evm, k.ERC20Keeper().GetERC20ABI(), fee.Contract(), + sdk.UnwrapSDKContext(ctx).WithGasMeter(storetypes.NewInfiniteGasMeter()), k.cdc, k.Logger(ctx), + k.accountKeeper, k.VMStore, evm, k.ERC20Keeper().GetERC20ABI(), fee.Contract(), ) } @@ -164,8 +161,11 @@ func (k Keeper) CreateEVM(ctx context.Context, caller common.Address, tracer *tr return ctx, nil, err } - evm := &vm.EVM{} - blockContext, err := k.buildBlockContext(ctx, evm, fee) + chainConfig := types.DefaultChainConfig(ctx) + vmConfig := vm.Config{Tracer: tracer, ExtraEips: extraEIPs, NumRetainBlockHashes: ¶ms.NumRetainBlockHashes} + + // use dummy block context for chain rules in EVM creation + dummyBlockContext, err := k.buildBlockContext(ctx, nil, fee) if err != nil { return ctx, nil, err } @@ -173,27 +173,30 @@ func (k Keeper) CreateEVM(ctx context.Context, caller common.Address, tracer *tr if err != nil { return ctx, nil, err } - stateDB, err := k.NewStateDB(ctx, evm, fee) + + // NOTE: need to check if the EVM is correctly initialized with empty context and stateDB + evm := vm.NewEVM( + dummyBlockContext, + txContext, + nil, + chainConfig, + vmConfig, + ) + // customize EVM contexts and stateDB and precompiles + evm.Context, err = k.buildBlockContext(ctx, evm, fee) if err != nil { return ctx, nil, err } - - chainConfig := types.DefaultChainConfig(ctx) - rules := chainConfig.Rules(blockContext.BlockNumber, blockContext.Random != nil, blockContext.Time) - vmConfig := vm.Config{Tracer: tracer, ExtraEips: extraEIPs, NumRetainBlockHashes: ¶ms.NumRetainBlockHashes} - precompiles, err := k.precompiles(rules, stateDB) + evm.StateDB, err = k.NewStateDB(ctx, evm, fee) if err != nil { return ctx, nil, err } - - *evm = *vm.NewEVMWithPrecompiles( - blockContext, - txContext, - stateDB, - chainConfig, - vmConfig, - precompiles, - ) + rules := chainConfig.Rules(evm.Context.BlockNumber, evm.Context.Random != nil, evm.Context.Time) + precompiles, err := k.precompiles(rules, evm.StateDB.(types.StateDB)) + if err != nil { + return ctx, nil, err + } + evm.SetPrecompiles(precompiles) if tracer != nil { // register vm context to tracer diff --git a/x/evm/keeper/fuzz_test.go b/x/evm/keeper/fuzz_test.go index e0b3db0..ed18643 100644 --- a/x/evm/keeper/fuzz_test.go +++ b/x/evm/keeper/fuzz_test.go @@ -1,9 +1,7 @@ package keeper_test import ( - "bytes" "sync" - "sync/atomic" "testing" storetypes "cosmossdk.io/store/types" @@ -11,7 +9,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - coretypes "github.com/ethereum/go-ethereum/core/types" "github.com/holiman/uint256" "github.com/stretchr/testify/require" @@ -48,9 +45,6 @@ func Fuzz_Concurrent_Counter(f *testing.F) { inputBz, err := parsed.Pack("increase_for_fuzz", uint64(numCount)) require.NoError(t, err) - atomicBloomBytes := atomic.Pointer[[]byte]{} - atomicBloomBytes.Store(nil) - var wg sync.WaitGroup cacheCtxes := make([]sdk.Context, numThread) for i := uint8(0); i < numThread; i++ { @@ -65,9 +59,7 @@ func Fuzz_Concurrent_Counter(f *testing.F) { res, logs, err := input.EVMKeeper.EVMCall(ctx, caller, contractAddr, inputBz, nil, nil) require.NoError(t, err) require.Empty(t, res) - bloomBytes := coretypes.LogsBloom(logs.ToEthLogs()) - prev := atomicBloomBytes.Swap(&bloomBytes) - require.True(t, prev == nil || bytes.Equal(*prev, bloomBytes)) + assertLogs(t, contractAddr, logs) }(cacheCtx) } wg.Wait() @@ -75,11 +67,25 @@ func Fuzz_Concurrent_Counter(f *testing.F) { for i := uint8(0); i < numThread; i++ { count := getCount(t, cacheCtxes[i], input, contractAddr) require.Equal(t, uint256.NewInt(uint64(numCount)), count) - require.NotEmpty(t, atomicBloomBytes.Load()) } }) } +func assertLogs(t *testing.T, contractAddr common.Address, logs []types.Log) { + for i := range logs { + require.Equal(t, contractAddr.Hex(), logs[i].Address) + dataBz, err := hexutil.Decode(logs[i].Data) + require.NoError(t, err) + require.Len(t, dataBz, 64) + before := new(uint256.Int).SetBytes(dataBz[:32]) + after := new(uint256.Int).SetBytes(dataBz[32:]) + + require.NoError(t, err) + require.Equal(t, uint256.NewInt(uint64(i)), before) + require.Equal(t, uint256.NewInt(uint64(i+1)), after) + } +} + func getCount(t *testing.T, ctx sdk.Context, input TestKeepers, contractAddr common.Address) *uint256.Int { parsed, err := counter.CounterMetaData.GetAbi() require.NoError(t, err) diff --git a/x/evm/keeper/keeper.go b/x/evm/keeper/keeper.go index 5d69733..317fd81 100644 --- a/x/evm/keeper/keeper.go +++ b/x/evm/keeper/keeper.go @@ -48,20 +48,6 @@ type Keeper struct { Params collections.Item[types.Params] VMStore collections.Map[[]byte, []byte] - // execIndex is unique index for each execution, which is used - // unique key for transient stores. - execIndex *atomic.Uint64 - - // transient store - TSchema collections.Schema - TransientVMStore collections.Map[collections.Pair[uint64, []byte], []byte] - TransientLogs collections.Map[collections.Pair[uint64, uint64], types.Log] - TransientLogSize collections.Map[uint64, uint64] - TransientRefund collections.Map[uint64, uint64] - TransientCreated collections.KeySet[collections.Pair[uint64, []byte]] - TransientSelfDestruct collections.KeySet[collections.Pair[uint64, []byte]] - TransientAccessList collections.KeySet[collections.Pair[uint64, []byte]] - // erc20 stores of users ERC20FactoryAddr collections.Item[[]byte] ERC20WrapperAddr collections.Item[[]byte] @@ -86,7 +72,6 @@ func NewKeeper( ac address.Codec, cdc codec.Codec, storeService corestoretypes.KVStoreService, - transientService corestoretypes.TransientStoreService, accountKeeper types.AccountKeeper, bankKeeper types.BankKeeper, communityPoolKeeper types.CommunityPoolKeeper, @@ -99,7 +84,6 @@ func NewKeeper( queryCosmosWhitelist types.QueryCosmosWhitelist, ) *Keeper { sb := collections.NewSchemaBuilder(storeService) - tsb := collections.NewSchemaBuilderFromAccessor(transientService.OpenTransientStore) if evmConfig.ContractSimulationGasLimit == 0 { evmConfig.ContractSimulationGasLimit = evmconfig.DefaultContractSimulationGasLimit @@ -132,16 +116,6 @@ func NewKeeper( Params: collections.NewItem(sb, types.ParamsKey, "params", codec.CollValue[types.Params](cdc)), VMStore: collections.NewMap(sb, types.VMStorePrefix, "vm_store", collections.BytesKey, collections.BytesValue), - execIndex: execIndex, - - TransientVMStore: collections.NewMap(tsb, types.TransientVMStorePrefix, "transient_vm_store", collections.PairKeyCodec(collections.Uint64Key, collections.BytesKey), collections.BytesValue), - TransientCreated: collections.NewKeySet(tsb, types.TransientCreatedPrefix, "transient_created", collections.PairKeyCodec(collections.Uint64Key, collections.BytesKey)), - TransientSelfDestruct: collections.NewKeySet(tsb, types.TransientSelfDestructPrefix, "transient_self_destruct", collections.PairKeyCodec(collections.Uint64Key, collections.BytesKey)), - TransientLogs: collections.NewMap(tsb, types.TransientLogsPrefix, "transient_logs", collections.PairKeyCodec(collections.Uint64Key, collections.Uint64Key), codec.CollValue[types.Log](cdc)), - TransientLogSize: collections.NewMap(tsb, types.TransientLogSizePrefix, "transient_log_size", collections.Uint64Key, collections.Uint64Value), - TransientAccessList: collections.NewKeySet(tsb, types.TransientAccessListPrefix, "transient_access_list", collections.PairKeyCodec(collections.Uint64Key, collections.BytesKey)), - TransientRefund: collections.NewMap(tsb, types.TransientRefundPrefix, "transient_refund", collections.Uint64Key, collections.Uint64Value), - ERC20WrapperAddr: collections.NewItem(sb, types.ERC20WrapperAddrKey, "erc20_wrapper_addr", collections.BytesValue), ERC20FactoryAddr: collections.NewItem(sb, types.ERC20FactoryAddrKey, "erc20_factory_addr", collections.BytesValue), ERC20s: collections.NewKeySet(sb, types.ERC20sPrefix, "erc20s", collections.BytesKey), @@ -164,13 +138,8 @@ func NewKeeper( if err != nil { panic(err) } - tSchema, err := tsb.Build() - if err != nil { - panic(err) - } k.Schema = schema - k.TSchema = tSchema k.erc20StoresKeeper = NewERC20StoresKeeper(k) k.erc20Keeper, err = NewERC20Keeper(k) if err != nil { diff --git a/x/evm/precompiles/cosmos/common_test.go b/x/evm/precompiles/cosmos/common_test.go index 1849cff..ea20cb1 100644 --- a/x/evm/precompiles/cosmos/common_test.go +++ b/x/evm/precompiles/cosmos/common_test.go @@ -24,14 +24,15 @@ import ( var _ evmtypes.StateDB = &MockStateDB{} type MockStateDB struct { - ctx sdk.Context - initialCtx sdk.Context + ctx state.Context + initialCtx state.Context // Snapshot stack snaps []*state.Snapshot } -func NewMockStateDB(ctx sdk.Context) *MockStateDB { +func NewMockStateDB(sdkCtx sdk.Context) *MockStateDB { + ctx := state.NewContext(sdkCtx) return &MockStateDB{ ctx: ctx, initialCtx: ctx, @@ -73,15 +74,15 @@ func (m *MockStateDB) RevertToSnapshot(i int) { // ContextOfSnapshot implements types.StateDB. func (m *MockStateDB) ContextOfSnapshot(i int) sdk.Context { if i == -1 { - return m.initialCtx + return m.initialCtx.Context } - return m.snaps[i].Context() + return m.snaps[i].Context().Context } // Context implements types.StateDB. func (m *MockStateDB) Context() sdk.Context { - return m.ctx + return m.ctx.Context } //////////////////////// MOCKED METHODS //////////////////////// diff --git a/x/evm/precompiles/erc20_registry/common_test.go b/x/evm/precompiles/erc20_registry/common_test.go index 8a8f09a..b384de9 100644 --- a/x/evm/precompiles/erc20_registry/common_test.go +++ b/x/evm/precompiles/erc20_registry/common_test.go @@ -18,14 +18,15 @@ import ( var _ evmtypes.StateDB = &MockStateDB{} type MockStateDB struct { - ctx sdk.Context - initialCtx sdk.Context + ctx state.Context + initialCtx state.Context // Snapshot stack snaps []*state.Snapshot } -func NewMockStateDB(ctx sdk.Context) *MockStateDB { +func NewMockStateDB(sdkCtx sdk.Context) *MockStateDB { + ctx := state.NewContext(sdkCtx) return &MockStateDB{ ctx: ctx, initialCtx: ctx, @@ -67,15 +68,15 @@ func (m *MockStateDB) RevertToSnapshot(i int) { // ContextOfSnapshot implements types.StateDB. func (m *MockStateDB) ContextOfSnapshot(i int) sdk.Context { if i == -1 { - return m.initialCtx + return m.initialCtx.Context } - return m.snaps[i].Context() + return m.snaps[i].Context().Context } // Context implements types.StateDB. func (m *MockStateDB) Context() sdk.Context { - return m.ctx + return m.ctx.Context } //////////////////////// MOCKED METHODS //////////////////////// diff --git a/x/evm/state/common_test.go b/x/evm/state/common_test.go index f779984..dab485f 100644 --- a/x/evm/state/common_test.go +++ b/x/evm/state/common_test.go @@ -261,7 +261,6 @@ func _createTestInput( ac, appCodec, runtime.NewKVStoreService(keys[evmtypes.StoreKey]), - runtime.NewTransientStoreService(tkeys[evmtypes.TStoreKey]), accountKeeper, bankKeeper, communityPoolKeeper, diff --git a/x/evm/state/context.go b/x/evm/state/context.go new file mode 100644 index 0000000..c989ea9 --- /dev/null +++ b/x/evm/state/context.go @@ -0,0 +1,45 @@ +package state + +import ( + storetypes "cosmossdk.io/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type Context struct { + sdk.Context + + memStore storetypes.MultiStore + memStoreKey storetypes.StoreKey +} + +func NewContext(ctx sdk.Context) Context { + memStore, memStoreKey := newMemStore() + return Context{ + Context: ctx, + memStore: memStore, + memStoreKey: memStoreKey, + } +} + +func (c Context) WithSDKContext(sdkCtx sdk.Context) Context { + c.Context = sdkCtx + return c +} + +func (c Context) WithMemStore(memStore storetypes.MultiStore) Context { + c.memStore = memStore + return c +} + +func (c Context) CacheContext() (cc Context, writeCache func()) { + cacheCtx, commit := c.Context.CacheContext() + cacheMemStore := c.memStore.CacheMultiStore() + + cc = c.WithSDKContext(cacheCtx).WithMemStore(cacheMemStore) + writeCache = func() { + commit() + cacheMemStore.Write() + } + + return cc, writeCache +} diff --git a/x/evm/state/keys.go b/x/evm/state/keys.go index 1919804..1b256b8 100644 --- a/x/evm/state/keys.go +++ b/x/evm/state/keys.go @@ -37,3 +37,14 @@ func uint64ToBytes(v uint64) []byte { func bytesToUint64(bz []byte) uint64 { return binary.BigEndian.Uint64(bz) } + +// Keys for memStore +var ( + memStoreVMStorePrefix = []byte{0x01} // prefix for memStore vm store + memStoreCreatedPrefix = []byte{0x02} // prefix for memStore created accounts + memStoreSelfDestructPrefix = []byte{0x03} // prefix for memStore self destruct accounts + memStoreLogsPrefix = []byte{0x04} // prefix for memStore logs + memStoreLogSizePrefix = []byte{0x05} // prefix for memStore log size + memStoreAccessListPrefix = []byte{0x06} // prefix for memStore access list + memStoreRefundPrefix = []byte{0x07} // prefix for memStore refund +) diff --git a/x/evm/state/memstore.go b/x/evm/state/memstore.go new file mode 100644 index 0000000..6f8f6c0 --- /dev/null +++ b/x/evm/state/memstore.go @@ -0,0 +1,80 @@ +package state + +import ( + "fmt" + + corestoretypes "cosmossdk.io/core/store" + "cosmossdk.io/log" + "cosmossdk.io/store" + storemetrics "cosmossdk.io/store/metrics" + storetypes "cosmossdk.io/store/types" + dbm "github.com/cosmos/cosmos-db" +) + +const ( + storeKey = "stateDB" +) + +func newMemStore() (storetypes.MultiStore, storetypes.StoreKey) { + memStoreKey := storetypes.NewMemoryStoreKey(storeKey) + memStore := store.NewCommitMultiStore(dbm.NewMemDB(), log.NewNopLogger(), storemetrics.NewNoOpMetrics()) + memStore.MountStoreWithDB(memStoreKey, storetypes.StoreTypeMemory, nil) + if err := memStore.LoadLatestVersion(); err != nil { + panic(fmt.Sprintf("failed to initialize memory store: %v", err)) + } + + return memStore, memStoreKey +} + +// CoreKVStore is a wrapper of Core/Store kvstore interface +// Remove after https://github.com/cosmos/cosmos-sdk/issues/14714 is closed +type coreKVStore struct { + kvStore storetypes.KVStore +} + +// NewKVStore returns a wrapper of Core/Store kvstore interface +// Remove once store migrates to core/store kvstore interface +func newKVStore(store storetypes.KVStore) corestoretypes.KVStore { + return coreKVStore{kvStore: store} +} + +// Get returns nil iff key doesn't exist. Errors on nil key. +func (store coreKVStore) Get(key []byte) ([]byte, error) { + return store.kvStore.Get(key), nil +} + +// Has checks if a key exists. Errors on nil key. +func (store coreKVStore) Has(key []byte) (bool, error) { + return store.kvStore.Has(key), nil +} + +// Set sets the key. Errors on nil key or value. +func (store coreKVStore) Set(key, value []byte) error { + store.kvStore.Set(key, value) + return nil +} + +// Delete deletes the key. Errors on nil key. +func (store coreKVStore) Delete(key []byte) error { + store.kvStore.Delete(key) + return nil +} + +// Iterator iterates over a domain of keys in ascending order. End is exclusive. +// Start must be less than end, or the Iterator is invalid. +// Iterator must be closed by caller. +// To iterate over entire domain, use store.Iterator(nil, nil) +// CONTRACT: No writes may happen within a domain while an iterator exists over it. +// Exceptionally allowed for cachekv.Store, safe to write in the modules. +func (store coreKVStore) Iterator(start, end []byte) (store.Iterator, error) { + return store.kvStore.Iterator(start, end), nil +} + +// ReverseIterator iterates over a domain of keys in descending order. End is exclusive. +// Start must be less than end, or the Iterator is invalid. +// Iterator must be closed by caller. +// CONTRACT: No writes may happen within a domain while an iterator exists over it. +// Exceptionally allowed for cachekv.Store, safe to write in the modules. +func (store coreKVStore) ReverseIterator(start, end []byte) (store.Iterator, error) { + return store.kvStore.ReverseIterator(start, end), nil +} diff --git a/x/evm/state/snapshot.go b/x/evm/state/snapshot.go index 51a246a..f6edb54 100644 --- a/x/evm/state/snapshot.go +++ b/x/evm/state/snapshot.go @@ -1,19 +1,12 @@ package state -import ( - "context" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - type Snapshot struct { - ctx sdk.Context + ctx Context commit func() } -func NewSnapshot(ctx context.Context) *Snapshot { - sdkCtx := sdk.UnwrapSDKContext(ctx) - cacheCtx, commit := sdkCtx.CacheContext() +func NewSnapshot(ctx Context) *Snapshot { + cacheCtx, commit := ctx.CacheContext() return &Snapshot{ ctx: cacheCtx, commit: commit, @@ -25,6 +18,6 @@ func (s *Snapshot) Commit() { } // for mock testing -func (s *Snapshot) Context() sdk.Context { +func (s *Snapshot) Context() Context { return s.ctx } diff --git a/x/evm/state/statedb.go b/x/evm/state/statedb.go index 1c6fd49..3613a91 100644 --- a/x/evm/state/statedb.go +++ b/x/evm/state/statedb.go @@ -1,15 +1,17 @@ package state import ( + "context" "errors" "fmt" "math/big" - "sync/atomic" "github.com/holiman/uint256" "cosmossdk.io/collections" + corestoretypes "cosmossdk.io/core/store" "cosmossdk.io/log" + "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/ethereum/go-ethereum/accounts/abi" @@ -28,20 +30,22 @@ import ( var _ vm.StateDB = &StateDB{} type StateDB struct { - ctx sdk.Context - initialCtx sdk.Context + ctx Context + initialCtx Context logger log.Logger accountKeeper evmtypes.AccountKeeper - vmStore collections.Map[[]byte, []byte] - transientVMStore collections.Map[collections.Pair[uint64, []byte], []byte] - transientCreated collections.KeySet[collections.Pair[uint64, []byte]] - transientSelfDestruct collections.KeySet[collections.Pair[uint64, []byte]] - transientLogs collections.Map[collections.Pair[uint64, uint64], evmtypes.Log] - transientLogSize collections.Map[uint64, uint64] - transientAccessList collections.KeySet[collections.Pair[uint64, []byte]] - transientRefund collections.Map[uint64, uint64] - execIndex uint64 + vmStore collections.Map[[]byte, []byte] + + // transient memory store for the current execution + memStoreVMStore collections.Map[[]byte, []byte] + memStoreCreated collections.KeySet[[]byte] + memStoreSelfDestruct collections.KeySet[[]byte] + memStoreLogs collections.Map[uint64, evmtypes.Log] + memStoreLogSize collections.Item[uint64] + memStoreAccessList collections.KeySet[[]byte] + memStoreRefund collections.Item[uint64] + schema collections.Schema evm *vm.EVM erc20ABI *abi.ABI @@ -56,55 +60,59 @@ const ( ) func NewStateDB( - ctx sdk.Context, + sdkCtx sdk.Context, + cdc codec.Codec, logger log.Logger, accountKeeper evmtypes.AccountKeeper, // store params vmStore collections.Map[[]byte, []byte], - transientVMStore collections.Map[collections.Pair[uint64, []byte], []byte], - transientCreated collections.KeySet[collections.Pair[uint64, []byte]], - transientSelfDestruct collections.KeySet[collections.Pair[uint64, []byte]], - transientLogs collections.Map[collections.Pair[uint64, uint64], evmtypes.Log], - transientLogSize collections.Map[uint64, uint64], - transientAccessList collections.KeySet[collections.Pair[uint64, []byte]], - transientRefund collections.Map[uint64, uint64], - execIndex *atomic.Uint64, // erc20 params evm *vm.EVM, erc20ABI *abi.ABI, feeContractAddr common.Address, ) (*StateDB, error) { - eidx := execIndex.Add(1) - - err := transientLogSize.Set(ctx, eidx, 0) - if err != nil { - return nil, err - } - err = transientRefund.Set(ctx, eidx, 0) - if err != nil { - return nil, err - } - + sb := collections.NewSchemaBuilderFromAccessor( + func(ctx context.Context) corestoretypes.KVStore { + stateCtx := ctx.(Context) + return newKVStore(stateCtx.memStore.GetKVStore(stateCtx.memStoreKey)) + }, + ) + + ctx := NewContext(sdkCtx) s := &StateDB{ ctx: ctx, initialCtx: ctx, logger: logger, accountKeeper: accountKeeper, - vmStore: vmStore, - transientVMStore: transientVMStore, - transientCreated: transientCreated, - transientSelfDestruct: transientSelfDestruct, - transientLogs: transientLogs, - transientLogSize: transientLogSize, - transientAccessList: transientAccessList, - transientRefund: transientRefund, - execIndex: eidx, + vmStore: vmStore, + + memStoreVMStore: collections.NewMap(sb, memStoreVMStorePrefix, "mem_store_vm_store", collections.BytesKey, collections.BytesValue), + memStoreCreated: collections.NewKeySet(sb, memStoreCreatedPrefix, "mem_store_created", collections.BytesKey), + memStoreSelfDestruct: collections.NewKeySet(sb, memStoreSelfDestructPrefix, "mem_store_self_destruct", collections.BytesKey), + memStoreLogs: collections.NewMap(sb, memStoreLogsPrefix, "mem_store_logs", collections.Uint64Key, codec.CollValue[evmtypes.Log](cdc)), + memStoreLogSize: collections.NewItem(sb, memStoreLogSizePrefix, "mem_store_log_size", collections.Uint64Value), + memStoreAccessList: collections.NewKeySet(sb, memStoreAccessListPrefix, "mem_store_access_list", collections.BytesKey), + memStoreRefund: collections.NewItem(sb, memStoreRefundPrefix, "mem_store_refund", collections.Uint64Value), evm: evm, erc20ABI: erc20ABI, feeContractAddr: feeContractAddr, } + schema, err := sb.Build() + if err != nil { + return nil, err + } + s.schema = schema + + err = s.memStoreLogSize.Set(ctx, 0) + if err != nil { + return nil, err + } + err = s.memStoreRefund.Set(ctx, 0) + if err != nil { + return nil, err + } return s, nil } @@ -176,12 +184,12 @@ func (s *StateDB) GetBalance(addr common.Address) *uint256.Int { // AddRefund implements vm.StateDB. func (s *StateDB) AddRefund(gas uint64) { - refund, err := s.transientRefund.Get(s.ctx, s.execIndex) + refund, err := s.memStoreRefund.Get(s.ctx) if err != nil { panic(err) } - err = s.transientRefund.Set(s.ctx, s.execIndex, refund+gas) + err = s.memStoreRefund.Set(s.ctx, refund+gas) if err != nil { panic(err) } @@ -189,7 +197,7 @@ func (s *StateDB) AddRefund(gas uint64) { // SubRefund implements vm.StateDB. func (s *StateDB) SubRefund(gas uint64) { - refund, err := s.transientRefund.Get(s.ctx, s.execIndex) + refund, err := s.memStoreRefund.Get(s.ctx) if err != nil { panic(err) } @@ -198,7 +206,7 @@ func (s *StateDB) SubRefund(gas uint64) { panic(fmt.Sprintf("Refund counter below zero (gas: %d > refund: %d)", gas, refund)) } - err = s.transientRefund.Set(s.ctx, s.execIndex, refund-gas) + err = s.memStoreRefund.Set(s.ctx, refund-gas) if err != nil { panic(err) } @@ -206,7 +214,7 @@ func (s *StateDB) SubRefund(gas uint64) { // AddAddressToAccessList adds the given address to the access list func (s *StateDB) AddAddressToAccessList(addr common.Address) { - err := s.transientAccessList.Set(s.ctx, collections.Join(s.execIndex, addr.Bytes())) + err := s.memStoreAccessList.Set(s.ctx, addr.Bytes()) if err != nil { panic(err) } @@ -219,7 +227,7 @@ func (s *StateDB) AddSlotToAccessList(addr common.Address, slot common.Hash) { s.AddAddressToAccessList(addr) } - err := s.transientAccessList.Set(s.ctx, collections.Join(s.execIndex, append(addr.Bytes(), slot[:]...))) + err := s.memStoreAccessList.Set(s.ctx, append(addr.Bytes(), slot[:]...)) if err != nil { panic(err) } @@ -227,7 +235,7 @@ func (s *StateDB) AddSlotToAccessList(addr common.Address, slot common.Hash) { // AddressInAccessList returns true if the given address is in the access list func (s *StateDB) AddressInAccessList(addr common.Address) bool { - ok, err := s.transientAccessList.Has(s.ctx, collections.Join(s.execIndex, addr.Bytes())) + ok, err := s.memStoreAccessList.Has(s.ctx, addr.Bytes()) if err != nil { panic(err) } @@ -237,14 +245,14 @@ func (s *StateDB) AddressInAccessList(addr common.Address) bool { // SlotInAccessList returns true if the given (address, slot)-tuple is in the access list func (s *StateDB) SlotInAccessList(addr common.Address, slot common.Hash) (addressOk bool, slotOk bool) { - ok, err := s.transientAccessList.Has(s.ctx, collections.Join(s.execIndex, addr.Bytes())) + ok, err := s.memStoreAccessList.Has(s.ctx, addr.Bytes()) if err != nil { panic(err) } else if !ok { return false, false } - ok, err = s.transientAccessList.Has(s.ctx, collections.Join(s.execIndex, append(addr.Bytes(), slot[:]...))) + ok, err = s.memStoreAccessList.Has(s.ctx, append(addr.Bytes(), slot[:]...)) if err != nil { panic(err) } @@ -260,7 +268,7 @@ func (s *StateDB) CreateAccount(addr common.Address) { // CreateContract creates a contract account with the given address func (s *StateDB) CreateContract(contractAddr common.Address) { - if err := s.transientCreated.Set(s.ctx, collections.Join(s.execIndex, contractAddr.Bytes())); err != nil { + if err := s.memStoreCreated.Set(s.ctx, contractAddr.Bytes()); err != nil { panic(err) } @@ -441,7 +449,7 @@ func (s *StateDB) SetNonce(addr common.Address, nonce uint64) { // GetRefund returns the refund func (s *StateDB) GetRefund() uint64 { - refund, err := s.transientRefund.Get(s.ctx, s.execIndex) + refund, err := s.memStoreRefund.Get(s.ctx) if err != nil { panic(err) } @@ -470,7 +478,7 @@ func (s *StateDB) GetState(addr common.Address, slot common.Hash) common.Hash { func (s *StateDB) HasSelfDestructed(addr common.Address) bool { acc := s.getAccount(addr) if acc != nil { - ok, err := s.transientSelfDestruct.Has(s.ctx, collections.Join(s.execIndex, addr.Bytes())) + ok, err := s.memStoreSelfDestruct.Has(s.ctx, addr.Bytes()) if err != nil { panic(err) } @@ -493,7 +501,7 @@ func (s *StateDB) SelfDestruct(addr common.Address) { } // mark the account as self-destructed - if err := s.transientSelfDestruct.Set(s.ctx, collections.Join(s.execIndex, addr.Bytes())); err != nil { + if err := s.memStoreSelfDestruct.Set(s.ctx, addr.Bytes()); err != nil { panic(err) } @@ -508,7 +516,7 @@ func (s *StateDB) Selfdestruct6780(addr common.Address) { return } - ok, err := s.transientCreated.Has(s.ctx, collections.Join(s.execIndex, addr.Bytes())) + ok, err := s.memStoreCreated.Has(s.ctx, addr.Bytes()) if err != nil { panic(err) } else if ok { @@ -523,21 +531,20 @@ func (s *StateDB) SetState(addr common.Address, slot common.Hash, value common.H } } -// SetTransientState sets transient storage for a given account. +// SetTransientState sets memStore storage for a given account. func (s *StateDB) SetTransientState(addr common.Address, key, value common.Hash) { prev := s.GetTransientState(addr, key) if prev == value { return } - - if err := s.transientVMStore.Set(s.ctx, collections.Join(s.execIndex, key[:]), value[:]); err != nil { + if err := s.memStoreVMStore.Set(s.ctx, append(addr.Bytes(), key.Bytes()...), value[:]); err != nil { panic(err) } } -// GetTransientState gets transient storage for a given account. +// GetTransientState gets memStore storage for a given account. func (s *StateDB) GetTransientState(addr common.Address, key common.Hash) common.Hash { - data, err := s.transientVMStore.Get(s.ctx, collections.Join(s.execIndex, key[:])) + data, err := s.memStoreVMStore.Get(s.ctx, append(addr.Bytes(), key.Bytes()...)) if err != nil && errors.Is(err, collections.ErrNotFound) { return common.Hash{} } else if err != nil { @@ -582,15 +589,15 @@ func (s *StateDB) RevertToSnapshot(i int) { // ContextOfSnapshot returns the context of the snapshot with the given id func (s *StateDB) ContextOfSnapshot(i int) sdk.Context { if i == -1 { - return s.initialCtx + return s.initialCtx.Context } - return s.snaps[i].ctx + return s.snaps[i].ctx.Context } // Context returns the current context func (s *StateDB) Context() sdk.Context { - return s.ctx + return s.ctx.Context } // Prepare handles the preparatory steps for executing a state transition with. @@ -632,8 +639,8 @@ func (s *StateDB) Prepare(rules params.Rules, sender common.Address, coinbase co func (s *StateDB) Commit() error { // clear destructed accounts - err := s.transientSelfDestruct.Walk(s.ctx, collections.NewPrefixedPairRange[uint64, []byte](s.execIndex), func(key collections.Pair[uint64, []byte]) (stop bool, err error) { - addr := common.BytesToAddress(key.K2()) + err := s.memStoreSelfDestruct.Walk(s.ctx, nil, func(key []byte) (stop bool, err error) { + addr := common.BytesToAddress(key) // If ether was sent to account post-selfdestruct it is burnt. if bal := s.GetBalance(addr); bal.Sign() != 0 { @@ -663,24 +670,24 @@ func (s *StateDB) Commit() error { // AddLog implements vm.StateDB. func (s *StateDB) AddLog(log *types.Log) { - logSize, err := s.transientLogSize.Get(s.ctx, s.execIndex) + logSize, err := s.memStoreLogSize.Get(s.ctx) if err != nil { panic(err) } - err = s.transientLogSize.Set(s.ctx, s.execIndex, logSize+1) + err = s.memStoreLogSize.Set(s.ctx, logSize+1) if err != nil { panic(err) } - err = s.transientLogs.Set(s.ctx, collections.Join(s.execIndex, logSize), evmtypes.NewLog(log)) + err = s.memStoreLogs.Set(s.ctx, logSize, evmtypes.NewLog(log)) if err != nil { panic(err) } } func (s *StateDB) Logs() evmtypes.Logs { - logSize, err := s.transientLogSize.Get(s.ctx, s.execIndex) + logSize, err := s.memStoreLogSize.Get(s.ctx) if err != nil { panic(err) } else if logSize == 0 { @@ -688,8 +695,8 @@ func (s *StateDB) Logs() evmtypes.Logs { } logs := make([]evmtypes.Log, logSize) - err = s.transientLogs.Walk(s.ctx, collections.NewPrefixedPairRange[uint64, uint64](s.execIndex), func(key collections.Pair[uint64, uint64], log evmtypes.Log) (stop bool, err error) { - logs[key.K2()] = log + err = s.memStoreLogs.Walk(s.ctx, nil, func(key uint64, log evmtypes.Log) (stop bool, err error) { + logs[key] = log return false, nil }) if err != nil { diff --git a/x/evm/state/statedb_test.go b/x/evm/state/statedb_test.go index 2093084..5622c4e 100644 --- a/x/evm/state/statedb_test.go +++ b/x/evm/state/statedb_test.go @@ -88,6 +88,14 @@ func Test_SnapshotRevert(t *testing.T) { // take more snapshots stateDB.Snapshot() stateDB.SubRefund(10) + require.Equal(t, uint64(90), stateDB.GetBalance(common.BytesToAddress(addr1)).Uint64()) + require.Equal(t, uint64(80), stateDB.GetRefund()) + require.Equal(t, evmtypes.NewLogs([]*coretypes.Log{log1, log2}), stateDB.Logs()[:2]) + require.True(t, stateDB.AddressInAccessList(common.BytesToAddress(addr1))) + require.True(t, stateDB.AddressInAccessList(common.BytesToAddress(addr2))) + require.Equal(t, common.BytesToHash([]byte("value2")), stateDB.GetState(common.BytesToAddress(addr1), common.BytesToHash([]byte("key")))) + require.Equal(t, common.BytesToHash([]byte("value2")), stateDB.GetState(common.BytesToAddress(addr2), common.BytesToHash([]byte("key")))) + stateDB.Snapshot() stateDB.SubBalance(common.BytesToAddress(addr1), uint256.NewInt(10), tracing.BalanceDecreaseSelfdestructBurn) diff --git a/x/evm/types/keys.go b/x/evm/types/keys.go index ee25eeb..b679453 100644 --- a/x/evm/types/keys.go +++ b/x/evm/types/keys.go @@ -20,14 +20,7 @@ const ( // Keys for move store // Items are stored with the following key: values var ( - VMStorePrefix = []byte{0x21} // prefix for vm - TransientVMStorePrefix = []byte{0x22} // prefix for transient vm store - TransientCreatedPrefix = []byte{0x23} // prefix for transient created accounts - TransientSelfDestructPrefix = []byte{0x24} // prefix for transient self destruct accounts - TransientLogsPrefix = []byte{0x25} // prefix for transient logs - TransientLogSizePrefix = []byte{0x26} // prefix for transient log size - TransientAccessListPrefix = []byte{0x27} // prefix for transient access list - TransientRefundPrefix = []byte{0x28} // prefix for transient refund + VMStorePrefix = []byte{0x21} // prefix for vm ERC20sPrefix = []byte{0x31} // prefix for erc20 stores ERC20StoresPrefix = []byte{0x32} // prefix for erc20 stores