From f07f8ac9d9e90de6a7451a63519f30687601fa73 Mon Sep 17 00:00:00 2001 From: beer-1 <147697694+beer-1@users.noreply.github.com> Date: Fri, 15 Nov 2024 18:08:22 +0900 Subject: [PATCH 1/6] feat: add missing opchild ante (#113) * add missing opchild ante * add checking --- app/ante/ante.go | 19 +++++++++++++------ app/blocksdk.go | 2 +- go.mod | 4 ++-- go.sum | 8 ++++---- integration-tests/go.mod | 4 ++-- integration-tests/go.sum | 6 ++---- 6 files changed, 24 insertions(+), 19 deletions(-) diff --git a/app/ante/ante.go b/app/ante/ante.go index 3be51e4..12c846b 100644 --- a/app/ante/ante.go +++ b/app/ante/ante.go @@ -11,7 +11,7 @@ import ( ibckeeper "github.com/cosmos/ibc-go/v8/modules/core/keeper" opchildante "github.com/initia-labs/OPinit/x/opchild/ante" - opchildtypes "github.com/initia-labs/OPinit/x/opchild/types" + opchildkeeper "github.com/initia-labs/OPinit/x/opchild/keeper" "github.com/initia-labs/initia/app/ante/accnum" "github.com/initia-labs/initia/app/ante/sigverify" evmante "github.com/initia-labs/minievm/x/evm/ante" @@ -28,8 +28,8 @@ type HandlerOptions struct { ante.HandlerOptions Codec codec.BinaryCodec IBCkeeper *ibckeeper.Keeper - OPChildKeeper opchildtypes.AnteKeeper - AuctionKeeper auctionkeeper.Keeper + OPChildKeeper *opchildkeeper.Keeper + AuctionKeeper *auctionkeeper.Keeper EVMKeeper EVMKeeper TxEncoder sdk.TxEncoder @@ -44,18 +44,24 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { if options.AccountKeeper == nil { return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "account keeper is required for ante builder") } - if options.BankKeeper == nil { return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "bank keeper is required for ante builder") } - if options.SignModeHandler == nil { return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "sign mode handler is required for ante builder") } - if options.EVMKeeper == nil { return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "EVM keeper is required for ante builder") } + if options.IBCkeeper == nil { + return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "IBC keeper is required for ante builder") + } + if options.OPChildKeeper == nil { + return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "OPChild keeper is required for ante builder") + } + if options.AuctionKeeper == nil { + return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "Auction keeper is required for ante builder") + } sigGasConsumer := options.SigGasConsumer if sigGasConsumer == nil { @@ -100,6 +106,7 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { evmante.NewIncrementSequenceDecorator(options.AccountKeeper), ibcante.NewRedundantRelayDecorator(options.IBCkeeper), auctionante.NewAuctionDecorator(options.AuctionKeeper, options.TxEncoder, options.MevLane), + opchildante.NewRedundantBridgeDecorator(options.OPChildKeeper), } return sdk.ChainAnteDecorators(anteDecorators...), nil diff --git a/app/blocksdk.go b/app/blocksdk.go index 342bebd..ee22e56 100644 --- a/app/blocksdk.go +++ b/app/blocksdk.go @@ -97,7 +97,7 @@ func setupBlockSDK( Codec: app.appCodec, OPChildKeeper: app.OPChildKeeper, TxEncoder: app.txConfig.TxEncoder(), - AuctionKeeper: *app.AuctionKeeper, + AuctionKeeper: app.AuctionKeeper, MevLane: mevLane, FreeLane: freeLane, EVMKeeper: app.EVMKeeper, diff --git a/go.mod b/go.mod index b9ea061..8995c74 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/hashicorp/go-metrics v0.5.3 github.com/hashicorp/golang-lru/v2 v2.0.7 github.com/holiman/uint256 v1.3.1 - github.com/initia-labs/OPinit v0.5.7 + github.com/initia-labs/OPinit v0.6.0 github.com/initia-labs/initia v0.6.1 github.com/initia-labs/kvindexer v0.1.9 github.com/initia-labs/kvindexer/submodules/block v0.1.0 @@ -178,7 +178,7 @@ require ( github.com/iancoleman/strcase v0.3.0 // indirect github.com/improbable-eng/grpc-web v0.15.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/initia-labs/OPinit/api v0.5.7 // indirect + github.com/initia-labs/OPinit/api v0.6.0 // indirect github.com/initia-labs/kvindexer/submodules/tx v0.1.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect diff --git a/go.sum b/go.sum index fd2a25e..a04a9af 100644 --- a/go.sum +++ b/go.sum @@ -1433,10 +1433,10 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/initia-labs/OPinit v0.5.7 h1:25G0o2VXcO4EXzh9afdTdsXl1PTdYG9VMUx4efmWCuM= -github.com/initia-labs/OPinit v0.5.7/go.mod h1:lx1amLMszculwPu8ln+btJno38UV28fd2nP7XC88ZeE= -github.com/initia-labs/OPinit/api v0.5.7 h1:jghTmrrDEmowrqSpy7iL7IW9xJh40rn/S1y/LrwPkyE= -github.com/initia-labs/OPinit/api v0.5.7/go.mod h1:gHK6DEWb3/DqQD5LjKirUx9jilAh2UioXanoQdgqVfU= +github.com/initia-labs/OPinit v0.6.0 h1:V9jQf8+PjNctLX31FHMGUsk6fpnygVJO1WYzCmBMzkU= +github.com/initia-labs/OPinit v0.6.0/go.mod h1:gDpCh4Zx94mihwgzP/PLav8eVHLroZBu3dFyzCy8iIs= +github.com/initia-labs/OPinit/api v0.6.0 h1:Q3hDHpTd9EqlDfY/OryCKIwuXYWJxGJdGfJicV1RjL4= +github.com/initia-labs/OPinit/api v0.6.0/go.mod h1:gHK6DEWb3/DqQD5LjKirUx9jilAh2UioXanoQdgqVfU= github.com/initia-labs/cometbft v0.0.0-20241113064430-a371e2dc387f h1:PpYBvJ0L58bAgH7KwS/7GBEUphLnhf4fnTLua9uOov8= github.com/initia-labs/cometbft v0.0.0-20241113064430-a371e2dc387f/go.mod h1:y7+6kPknafzWlkSMCekzXC81wpRf1pcVAUnO0wRy9lQ= github.com/initia-labs/cometbft-client v0.0.0-20240924071428-ef115cefa07e h1:k+pg63SFozCAK4LZFSiZtof6z69Tlu0O/Zftj1aAwes= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 9d3df7b..ce5fbb6 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -146,8 +146,8 @@ require ( github.com/iancoleman/strcase v0.3.0 // indirect github.com/improbable-eng/grpc-web v0.15.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/initia-labs/OPinit v0.5.7 // indirect - github.com/initia-labs/OPinit/api v0.5.7 // indirect + github.com/initia-labs/OPinit v0.6.0 // indirect + github.com/initia-labs/OPinit/api v0.6.0 // indirect github.com/initia-labs/kvindexer v0.1.9 // indirect github.com/initia-labs/kvindexer/submodules/block v0.1.0 // indirect github.com/initia-labs/kvindexer/submodules/evm-tx v0.1.2 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 8ffed47..1a6d8bf 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1393,10 +1393,8 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/initia-labs/OPinit v0.5.7 h1:25G0o2VXcO4EXzh9afdTdsXl1PTdYG9VMUx4efmWCuM= -github.com/initia-labs/OPinit v0.5.7/go.mod h1:lx1amLMszculwPu8ln+btJno38UV28fd2nP7XC88ZeE= -github.com/initia-labs/OPinit/api v0.5.7 h1:jghTmrrDEmowrqSpy7iL7IW9xJh40rn/S1y/LrwPkyE= -github.com/initia-labs/OPinit/api v0.5.7/go.mod h1:gHK6DEWb3/DqQD5LjKirUx9jilAh2UioXanoQdgqVfU= +github.com/initia-labs/OPinit v0.6.0 h1:V9jQf8+PjNctLX31FHMGUsk6fpnygVJO1WYzCmBMzkU= +github.com/initia-labs/OPinit/api v0.6.0 h1:Q3hDHpTd9EqlDfY/OryCKIwuXYWJxGJdGfJicV1RjL4= github.com/initia-labs/cometbft v0.0.0-20241113064430-a371e2dc387f h1:PpYBvJ0L58bAgH7KwS/7GBEUphLnhf4fnTLua9uOov8= github.com/initia-labs/cometbft v0.0.0-20241113064430-a371e2dc387f/go.mod h1:y7+6kPknafzWlkSMCekzXC81wpRf1pcVAUnO0wRy9lQ= github.com/initia-labs/evm v0.0.0-20241108055119-3d312736d7fb h1:oyH9gg/4f7uMCIJYnSpp7wa1NrGjSMsXTtypUfrsPLU= From aef44304bd191eeae884a29f9d807bc993574827 Mon Sep 17 00:00:00 2001 From: beer-1 <147697694+beer-1@users.noreply.github.com> Date: Sat, 16 Nov 2024 18:48:17 +0900 Subject: [PATCH 2/6] fix to pass mut in stead of reading it again (#114) --- jsonrpc/backend/backend.go | 6 +++--- jsonrpc/backend/tx.go | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/jsonrpc/backend/backend.go b/jsonrpc/backend/backend.go index 4f39d85..d724588 100644 --- a/jsonrpc/backend/backend.go +++ b/jsonrpc/backend/backend.go @@ -192,7 +192,7 @@ type AccMut struct { // acquireAccMut acquires the mutex for the account with the given senderHex // and increments the reference count. If the mutex does not exist, it is created. -func (b *JSONRPCBackend) acquireAccMut(senderHex string) { +func (b *JSONRPCBackend) acquireAccMut(senderHex string) *AccMut { // critical section for rc and create b.mut.Lock() accMut, ok := b.accMuts[senderHex] @@ -205,13 +205,13 @@ func (b *JSONRPCBackend) acquireAccMut(senderHex string) { // critical section end accMut.mut.Lock() + return accMut } // releaseAccMut releases the mutex for the account with the given senderHex // and decrements the reference count. If the reference count reaches zero, // the mutex is deleted. -func (b *JSONRPCBackend) releaseAccMut(senderHex string) { - accMut := b.accMuts[senderHex] +func (b *JSONRPCBackend) releaseAccMut(senderHex string, accMut *AccMut) { accMut.mut.Unlock() // critical section for rc and delete diff --git a/jsonrpc/backend/tx.go b/jsonrpc/backend/tx.go index 4be23ec..b1d8f9b 100644 --- a/jsonrpc/backend/tx.go +++ b/jsonrpc/backend/tx.go @@ -71,8 +71,8 @@ func (b *JSONRPCBackend) SendTx(tx *coretypes.Transaction) error { senderHex := hexutil.Encode(sender.Bytes()) // hold mutex for each sender - b.acquireAccMut(senderHex) - defer b.releaseAccMut(senderHex) + accMut := b.acquireAccMut(senderHex) + defer b.releaseAccMut(senderHex, accMut) checkCtx := b.app.GetContextForCheckTx(nil) if acc := b.app.AccountKeeper.GetAccount(checkCtx, sender); acc != nil { From b441435b01e565a24a67475db831d961ecd528ac Mon Sep 17 00:00:00 2001 From: beer-1 <147697694+beer-1@users.noreply.github.com> Date: Tue, 19 Nov 2024 14:12:06 +0900 Subject: [PATCH 3/6] feat: add concurrency tests (#109) * add concurrency tests * use new gas meter * clone slice to aviod concurrent write * fix ignore path * fix ignore path --- .codecov.yml | 3 +- .gitignore | 1 + Makefile | 3 + x/evm/contracts/counter/Counter.go | 25 +++++++- x/evm/contracts/counter/Counter.sol | 8 ++- x/evm/keeper/context_test.go | 2 +- x/evm/keeper/fuzz_test.go | 94 +++++++++++++++++++++++++++++ x/evm/keeper/precompiles.go | 4 +- 8 files changed, 134 insertions(+), 6 deletions(-) create mode 100644 x/evm/keeper/fuzz_test.go diff --git a/.codecov.yml b/.codecov.yml index 9fb7588..66c3d3d 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -35,4 +35,5 @@ ignore: - "**/test_utils.go" - "**/module.go" - "x/ibc/testing" - - "**/contracts" + - "x/evm/contracts" + - "**/*.sol" diff --git a/.gitignore b/.gitignore index 5a8a8f3..c06d791 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,7 @@ mytestnet coverage.txt profile.out sim_log_file +testdata # Vagrant .vagrant/ diff --git a/Makefile b/Makefile index 0170163..03dc0bb 100644 --- a/Makefile +++ b/Makefile @@ -201,6 +201,9 @@ contracts-gen: $(CONTRACTS_DIR)/* benchmark: @go test -timeout 20m -mod=readonly -bench=. ./... +fuzz: + @go test --timeout 2m -mod=readonly -fuzz=Fuzz ./x/evm/keeper + .PHONY: test test-all test-cover test-unit test-race benchmark contracts-gen ############################################################################### diff --git a/x/evm/contracts/counter/Counter.go b/x/evm/contracts/counter/Counter.go index e62d85a..bec8530 100644 --- a/x/evm/contracts/counter/Counter.go +++ b/x/evm/contracts/counter/Counter.go @@ -31,8 +31,8 @@ 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\":\"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: "0x608060405261196b806100115f395ff3fe608060405260043610610090575f3560e01c80637876da75116100585780637876da751461015e578063ac7fde5f14610186578063c31925a7146101c2578063cad23554146101ea578063e8927fbc1461022657610090565b806306661abd146100945780630d4f1f9d146100be57806324c68fce146100e657806331a503f01461010e5780636193689514610136575b5f80fd5b34801561009f575f80fd5b506100a8610230565b6040516100b59190610ca1565b60405180910390f35b3480156100c9575f80fd5b506100e460048036038101906100df9190610d3d565b610235565b005b3480156100f1575f80fd5b5061010c60048036038101906101079190610eb7565b61027c565b005b348015610119575f80fd5b50610134600480360381019061012f9190610f11565b61033c565b005b348015610141575f80fd5b5061015c60048036038101906101579190610f11565b610360565b005b348015610169575f80fd5b50610184600480360381019061017f9190610f3c565b6104b3565b005b348015610191575f80fd5b506101ac60048036038101906101a79190610f11565b610555565b6040516101b99190610fc0565b60405180910390f35b3480156101cd575f80fd5b506101e860048036038101906101e39190610d3d565b610569565b005b3480156101f5575f80fd5b50610210600480360381019061020b9190610fd9565b6105a6565b60405161021d91906110af565b60405180910390f35b61022e61062f565b005b5f5481565b8015610261578167ffffffffffffffff165f8082825461025591906110fc565b92505081905550610278565b5f808154809291906102729061112f565b91905055505b5050565b60f173ffffffffffffffffffffffffffffffffffffffff1663d46f64e6836040518263ffffffff1660e01b81526004016102b691906110af565b6020604051808303815f875af11580156102d2573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102f6919061118a565b508015610338576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161032f90611225565b60405180910390fd5b5050565b8067ffffffffffffffff165f8082825461035691906110fc565b9250508190555050565b7f4475bbd12ef452e28d39c4cb77494d85136c2d89ca1354b52188d4aaa8f4ba518160405161038f9190611252565b60405180910390a15f8167ffffffffffffffff1603156104b05760f173ffffffffffffffffffffffffffffffffffffffff1663d46f64e66103cf8361068e565b6040518263ffffffff1660e01b81526004016103eb91906110af565b6020604051808303815f875af1158015610407573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061042b919061118a565b5060f173ffffffffffffffffffffffffffffffffffffffff1663d46f64e66104528361068e565b6040518263ffffffff1660e01b815260040161046e91906110af565b6020604051808303815f875af115801561048a573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104ae919061118a565b505b50565b60f173ffffffffffffffffffffffffffffffffffffffff16636c4f6bd584604051806040016040528086151581526020018567ffffffffffffffff168152506040518363ffffffff1660e01b815260040161050f9291906112b6565b6020604051808303815f875af115801561052b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061054f919061118a565b50505050565b5f8167ffffffffffffffff16409050919050565b7fa019c7431cdfd7ba63501ffa1ba7d8f2a028e447653a5af5a96077e5038e0339828260405161059a9291906112f3565b60405180910390a15050565b606060f173ffffffffffffffffffffffffffffffffffffffff1663cad2355484846040518363ffffffff1660e01b81526004016105e492919061131a565b5f604051808303815f875af11580156105ff573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f8201168201806040525081019061062791906113bd565b905092915050565b5f808154809291906106409061112f565b91905055507f61996fe196f72cb598c483e896a1221263a28bb630480aa89495f737d4a8e3df60015f546106749190611404565b5f54604051610684929190611437565b60405180910390a1565b606060f173ffffffffffffffffffffffffffffffffffffffff16636af32a55306040518263ffffffff1660e01b81526004016106ca919061149d565b5f604051808303815f875af11580156106e5573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f8201168201806040525081019061070d91906113bd565b6107163061079a565b610772636193689560e01b60018661072e91906114b6565b60405160200161073e9190611252565b60405160208183030381529060405260405160200161075e929190611580565b6040516020818303038152906040526107c7565b6040516020016107849392919061180d565b6040516020818303038152906040529050919050565b60606107c08273ffffffffffffffffffffffffffffffffffffffff16601460ff16610a4b565b9050919050565b60605f60028084516107d991906118a0565b6107e391906110fc565b67ffffffffffffffff8111156107fc576107fb610d93565b5b6040519080825280601f01601f19166020018201604052801561082e5781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000815f81518110610865576108646118e1565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106108c8576108c76118e1565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f5b8351811015610a41575f848281518110610915576109146118e1565b5b602001015160f81c60f81b60f81c90507f303132333435363738396162636465660000000000000000000000000000000060048260ff16901c60ff1660108110610962576109616118e1565b5b1a60f81b836002808502018151811061097e5761097d6118e1565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f3031323334353637383961626364656600000000000000000000000000000000600f821660ff16601081106109e5576109e46118e1565b5b1a60f81b836002600160028602010181518110610a0557610a046118e1565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505080806001019150506108f8565b5080915050919050565b60605f8390505f6002846002610a6191906118a0565b610a6b91906110fc565b67ffffffffffffffff811115610a8457610a83610d93565b5b6040519080825280601f01601f191660200182016040528015610ab65781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000815f81518110610aed57610aec6118e1565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110610b5057610b4f6118e1565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f6001856002610b8e91906118a0565b610b9891906110fc565b90505b6001811115610c37577f3031323334353637383961626364656600000000000000000000000000000000600f841660108110610bda57610bd96118e1565b5b1a60f81b828281518110610bf157610bf06118e1565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a905350600483901c925080610c309061190e565b9050610b9b565b505f8214610c7e5784846040517fe22e27eb000000000000000000000000000000000000000000000000000000008152600401610c75929190611437565b60405180910390fd5b809250505092915050565b5f819050919050565b610c9b81610c89565b82525050565b5f602082019050610cb45f830184610c92565b92915050565b5f604051905090565b5f80fd5b5f80fd5b5f67ffffffffffffffff82169050919050565b610ce781610ccb565b8114610cf1575f80fd5b50565b5f81359050610d0281610cde565b92915050565b5f8115159050919050565b610d1c81610d08565b8114610d26575f80fd5b50565b5f81359050610d3781610d13565b92915050565b5f8060408385031215610d5357610d52610cc3565b5b5f610d6085828601610cf4565b9250506020610d7185828601610d29565b9150509250929050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610dc982610d83565b810181811067ffffffffffffffff82111715610de857610de7610d93565b5b80604052505050565b5f610dfa610cba565b9050610e068282610dc0565b919050565b5f67ffffffffffffffff821115610e2557610e24610d93565b5b610e2e82610d83565b9050602081019050919050565b828183375f83830152505050565b5f610e5b610e5684610e0b565b610df1565b905082815260208101848484011115610e7757610e76610d7f565b5b610e82848285610e3b565b509392505050565b5f82601f830112610e9e57610e9d610d7b565b5b8135610eae848260208601610e49565b91505092915050565b5f8060408385031215610ecd57610ecc610cc3565b5b5f83013567ffffffffffffffff811115610eea57610ee9610cc7565b5b610ef685828601610e8a565b9250506020610f0785828601610d29565b9150509250929050565b5f60208284031215610f2657610f25610cc3565b5b5f610f3384828501610cf4565b91505092915050565b5f805f60608486031215610f5357610f52610cc3565b5b5f84013567ffffffffffffffff811115610f7057610f6f610cc7565b5b610f7c86828701610e8a565b9350506020610f8d86828701610d29565b9250506040610f9e86828701610cf4565b9150509250925092565b5f819050919050565b610fba81610fa8565b82525050565b5f602082019050610fd35f830184610fb1565b92915050565b5f8060408385031215610fef57610fee610cc3565b5b5f83013567ffffffffffffffff81111561100c5761100b610cc7565b5b61101885828601610e8a565b925050602083013567ffffffffffffffff81111561103957611038610cc7565b5b61104585828601610e8a565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f6110818261104f565b61108b8185611059565b935061109b818560208601611069565b6110a481610d83565b840191505092915050565b5f6020820190508181035f8301526110c78184611077565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61110682610c89565b915061111183610c89565b9250828201905080821115611129576111286110cf565b5b92915050565b5f61113982610c89565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361116b5761116a6110cf565b5b600182019050919050565b5f8151905061118481610d13565b92915050565b5f6020828403121561119f5761119e610cc3565b5b5f6111ac84828501611176565b91505092915050565b7f72657665727420726561736f6e2064756d6d792076616c756520666f722074655f8201527f7374000000000000000000000000000000000000000000000000000000000000602082015250565b5f61120f602283611059565b915061121a826111b5565b604082019050919050565b5f6020820190508181035f83015261123c81611203565b9050919050565b61124c81610ccb565b82525050565b5f6020820190506112655f830184611243565b92915050565b61127481610d08565b82525050565b61128381610ccb565b82525050565b604082015f82015161129d5f85018261126b565b5060208201516112b0602085018261127a565b50505050565b5f6060820190508181035f8301526112ce8185611077565b90506112dd6020830184611289565b9392505050565b6112ed81610d08565b82525050565b5f6040820190506113065f830185611243565b61131360208301846112e4565b9392505050565b5f6040820190508181035f8301526113328185611077565b905081810360208301526113468184611077565b90509392505050565b5f61136161135c84610e0b565b610df1565b90508281526020810184848401111561137d5761137c610d7f565b5b611388848285611069565b509392505050565b5f82601f8301126113a4576113a3610d7b565b5b81516113b484826020860161134f565b91505092915050565b5f602082840312156113d2576113d1610cc3565b5b5f82015167ffffffffffffffff8111156113ef576113ee610cc7565b5b6113fb84828501611390565b91505092915050565b5f61140e82610c89565b915061141983610c89565b9250828203905081811115611431576114306110cf565b5b92915050565b5f60408201905061144a5f830185610c92565b6114576020830184610c92565b9392505050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6114878261145e565b9050919050565b6114978161147d565b82525050565b5f6020820190506114b05f83018461148e565b92915050565b5f6114c082610ccb565b91506114cb83610ccb565b9250828203905067ffffffffffffffff8111156114eb576114ea6110cf565b5b92915050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b5f819050919050565b611536611531826114f1565b61151c565b82525050565b5f81519050919050565b5f81905092915050565b5f61155a8261153c565b6115648185611546565b9350611574818560208601611069565b80840191505092915050565b5f61158b8285611525565b60048201915061159b8284611550565b91508190509392505050565b5f81905092915050565b7f7b224074797065223a20222f6d696e6965766d2e65766d2e76312e4d736743615f8201527f6c6c222c00000000000000000000000000000000000000000000000000000000602082015250565b5f61160b6024836115a7565b9150611616826115b1565b602482019050919050565b7f2273656e646572223a20220000000000000000000000000000000000000000005f82015250565b5f611655600b836115a7565b915061166082611621565b600b82019050919050565b5f6116758261104f565b61167f81856115a7565b935061168f818560208601611069565b80840191505092915050565b7f222c0000000000000000000000000000000000000000000000000000000000005f82015250565b5f6116cf6002836115a7565b91506116da8261169b565b600282019050919050565b7f22636f6e74726163745f61646472223a202200000000000000000000000000005f82015250565b5f6117196012836115a7565b9150611724826116e5565b601282019050919050565b7f22696e707574223a2022000000000000000000000000000000000000000000005f82015250565b5f611763600a836115a7565b915061176e8261172f565b600a82019050919050565b7f2276616c7565223a202230222c000000000000000000000000000000000000005f82015250565b5f6117ad600d836115a7565b91506117b882611779565b600d82019050919050565b7f226163636573735f6c697374223a205b5d7d00000000000000000000000000005f82015250565b5f6117f76012836115a7565b9150611802826117c3565b601282019050919050565b5f611817826115ff565b915061182282611649565b915061182e828661166b565b9150611839826116c3565b91506118448261170d565b9150611850828561166b565b915061185b826116c3565b915061186682611757565b9150611872828461166b565b915061187d826116c3565b9150611888826117a1565b9150611893826117eb565b9150819050949350505050565b5f6118aa82610c89565b91506118b583610c89565b92508282026118c381610c89565b915082820484148315176118da576118d96110cf565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f61191882610c89565b91505f820361192a576119296110cf565b5b60018203905091905056fea26469706673582212209825f0abe28a695e86dafdc3f7ab5e12d0b3fe9000ec5c28d7c9370eae0d684c64736f6c63430008190033", + 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", } // CounterABI is the input ABI used to generate the binding from. @@ -390,6 +390,27 @@ func (_Counter *CounterTransactorSession) Increase() (*types.Transaction, error) return _Counter.Contract.Increase(&_Counter.TransactOpts) } +// IncreaseForFuzz is a paid mutator transaction binding the contract method 0x2607baf8. +// +// Solidity: function increase_for_fuzz(uint64 num) returns() +func (_Counter *CounterTransactor) IncreaseForFuzz(opts *bind.TransactOpts, num uint64) (*types.Transaction, error) { + return _Counter.contract.Transact(opts, "increase_for_fuzz", num) +} + +// IncreaseForFuzz is a paid mutator transaction binding the contract method 0x2607baf8. +// +// Solidity: function increase_for_fuzz(uint64 num) returns() +func (_Counter *CounterSession) IncreaseForFuzz(num uint64) (*types.Transaction, error) { + return _Counter.Contract.IncreaseForFuzz(&_Counter.TransactOpts, num) +} + +// IncreaseForFuzz is a paid mutator transaction binding the contract method 0x2607baf8. +// +// Solidity: function increase_for_fuzz(uint64 num) returns() +func (_Counter *CounterTransactorSession) IncreaseForFuzz(num uint64) (*types.Transaction, error) { + return _Counter.Contract.IncreaseForFuzz(&_Counter.TransactOpts, num) +} + // QueryCosmos is a paid mutator transaction binding the contract method 0xcad23554. // // Solidity: function query_cosmos(string path, string req) returns(string result) diff --git a/x/evm/contracts/counter/Counter.sol b/x/evm/contracts/counter/Counter.sol index 12c7281..71c1459 100644 --- a/x/evm/contracts/counter/Counter.sol +++ b/x/evm/contracts/counter/Counter.sol @@ -14,7 +14,13 @@ contract Counter is IIBCAsyncCallback { constructor() payable {} - function increase() external payable { + function increase_for_fuzz(uint64 num) external { + for (uint64 i = 0; i < num; i++) { + increase(); + } + } + + function increase() public payable { count++; emit increased(count - 1, count); diff --git a/x/evm/keeper/context_test.go b/x/evm/keeper/context_test.go index f174d9d..0f8ca3f 100644 --- a/x/evm/keeper/context_test.go +++ b/x/evm/keeper/context_test.go @@ -118,7 +118,7 @@ func Test_Call(t *testing.T) { res, logs, err := input.EVMKeeper.EVMCall(ctx, caller, contractAddr, inputBz, uint256.NewInt(100), nil) require.NoError(t, err) require.Empty(t, res) - require.NotEmpty(t, logs) + require.Len(t, logs, int(2)) // check balance balance, err := input.EVMKeeper.ERC20Keeper().GetBalance(ctx, contractAddr.Bytes(), sdk.DefaultBondDenom) diff --git a/x/evm/keeper/fuzz_test.go b/x/evm/keeper/fuzz_test.go new file mode 100644 index 0000000..e0b3db0 --- /dev/null +++ b/x/evm/keeper/fuzz_test.go @@ -0,0 +1,94 @@ +package keeper_test + +import ( + "bytes" + "sync" + "sync/atomic" + "testing" + + storetypes "cosmossdk.io/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + + "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" + + "github.com/initia-labs/minievm/x/evm/contracts/counter" + "github.com/initia-labs/minievm/x/evm/types" +) + +func Fuzz_Concurrent_Counter(f *testing.F) { + f.Add(uint8(100), uint8(100)) + f.Fuzz(func(t *testing.T, numThread uint8, numCount uint8) { + if numThread == 0 || numCount == 0 { + t.Skip("skip invalid input") + } + + ctx, input := createDefaultTestInput(t) + _, _, addr := keyPubAddr() + + counterBz, err := hexutil.Decode(counter.CounterBin) + require.NoError(t, err) + + caller := common.BytesToAddress(addr.Bytes()) + retBz, contractAddr, _, err := input.EVMKeeper.EVMCreate(ctx, caller, counterBz, nil, nil) + require.NoError(t, err) + require.NotEmpty(t, retBz) + require.Len(t, contractAddr, 20) + + parsed, err := counter.CounterMetaData.GetAbi() + require.NoError(t, err) + + count := getCount(t, ctx, input, contractAddr) + require.Equal(t, uint256.NewInt(0), count) + + 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++ { + wg.Add(1) + cacheCtx, _ := ctx.CacheContext() + cacheCtx = cacheCtx.WithGasMeter(storetypes.NewInfiniteGasMeter()) + cacheCtxes[i] = cacheCtx + go func(ctx sdk.Context) { + defer wg.Done() + + // call with value + 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)) + }(cacheCtx) + } + wg.Wait() + + 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 getCount(t *testing.T, ctx sdk.Context, input TestKeepers, contractAddr common.Address) *uint256.Int { + parsed, err := counter.CounterMetaData.GetAbi() + require.NoError(t, err) + + queryInputBz, err := parsed.Pack("count") + require.NoError(t, err) + + queryRes, err := input.EVMKeeper.EVMStaticCall(ctx, types.StdAddress, contractAddr, queryInputBz, nil) + require.NoError(t, err) + + return uint256.NewInt(0).SetBytes32(queryRes) +} diff --git a/x/evm/keeper/precompiles.go b/x/evm/keeper/precompiles.go index b1afc76..150f2dd 100644 --- a/x/evm/keeper/precompiles.go +++ b/x/evm/keeper/precompiles.go @@ -1,6 +1,8 @@ package keeper import ( + "slices" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/params" @@ -42,6 +44,6 @@ func (k *Keeper) precompiles(rules params.Rules, stateDB types.StateDB) (vm.Prec // PrecompileAddrs returns the precompile addresses for the EVM. func (k *Keeper) precompileAddrs(rules params.Rules) []common.Address { - addrs := append(vm.ActivePrecompiles(rules), types.CosmosPrecompileAddress, types.ERC20RegistryPrecompileAddress) + addrs := append(slices.Clone(vm.ActivePrecompiles(rules)), types.CosmosPrecompileAddress, types.ERC20RegistryPrecompileAddress) return addrs } From d4298cf5d67395edece611d583ef16985c987fea Mon Sep 17 00:00:00 2001 From: beer-1 <147697694+beer-1@users.noreply.github.com> Date: Tue, 19 Nov 2024 14:12:20 +0900 Subject: [PATCH 4/6] fix: use statedb context at get_hash (#112) * rename go-ethereum version to actual version * use statedb context at get_hash --- go.mod | 2 +- integration-tests/go.mod | 2 +- x/evm/keeper/context.go | 13 +++++-------- x/evm/precompiles/cosmos/common_test.go | 5 +++++ x/evm/precompiles/erc20_registry/common_test.go | 5 +++++ x/evm/state/statedb.go | 16 ++++++++-------- x/evm/types/expected_keeper.go | 1 + 7 files changed, 26 insertions(+), 18 deletions(-) diff --git a/go.mod b/go.mod index 8995c74..4853541 100644 --- a/go.mod +++ b/go.mod @@ -28,7 +28,7 @@ require ( github.com/cosmos/ibc-apps/modules/rate-limiting/v8 v8.0.0 github.com/cosmos/ibc-go/modules/capability v1.0.1 github.com/cosmos/ibc-go/v8 v8.5.0 - github.com/ethereum/go-ethereum v1.14.9 + github.com/ethereum/go-ethereum v1.14.11 github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.4 github.com/gorilla/mux v1.8.1 diff --git a/integration-tests/go.mod b/integration-tests/go.mod index ce5fbb6..3f0a0ad 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -9,7 +9,7 @@ require ( github.com/cometbft/cometbft v0.38.12 github.com/cosmos/cosmos-sdk v0.50.10 github.com/cosmos/ibc-go/v8 v8.5.0 - github.com/ethereum/go-ethereum v1.14.9 + github.com/ethereum/go-ethereum v1.14.11 github.com/initia-labs/initia v0.6.1 github.com/initia-labs/minievm v0.5.2 github.com/stretchr/testify v1.9.0 diff --git a/x/evm/keeper/context.go b/x/evm/keeper/context.go index 0243ed4..18eefb0 100644 --- a/x/evm/keeper/context.go +++ b/x/evm/keeper/context.go @@ -24,7 +24,7 @@ import ( "github.com/initia-labs/minievm/x/evm/types" ) -func (k Keeper) NewStateDB(ctx context.Context, evm callableEVM, fee types.Fee) (*evmstate.StateDB, error) { +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), @@ -44,12 +44,7 @@ func (k Keeper) computeGasLimit(sdkCtx sdk.Context) uint64 { return gasLimit } -type callableEVM interface { - Call(vm.ContractRef, common.Address, []byte, uint64, *uint256.Int) ([]byte, uint64, error) - StaticCall(vm.ContractRef, common.Address, []byte, uint64) ([]byte, uint64, error) -} - -func (k Keeper) buildBlockContext(ctx context.Context, evm callableEVM, fee types.Fee) (vm.BlockContext, error) { +func (k Keeper) buildBlockContext(ctx context.Context, evm *vm.EVM, fee types.Fee) (vm.BlockContext, error) { sdkCtx := sdk.UnwrapSDKContext(ctx) headerHash := sdkCtx.HeaderHash() if len(headerHash) == 0 { @@ -116,7 +111,9 @@ func (k Keeper) buildBlockContext(ctx context.Context, evm callableEVM, fee type } }, GetHash: func(n uint64) common.Hash { - bz, err := k.EVMBlockHashes.Get(sdkCtx, n) + // use snapshot context to get block hash + ctx := evm.StateDB.(types.StateDB).Context() + bz, err := k.EVMBlockHashes.Get(ctx, n) if err != nil { return common.Hash{} } diff --git a/x/evm/precompiles/cosmos/common_test.go b/x/evm/precompiles/cosmos/common_test.go index f52d9e2..1849cff 100644 --- a/x/evm/precompiles/cosmos/common_test.go +++ b/x/evm/precompiles/cosmos/common_test.go @@ -79,6 +79,11 @@ func (m *MockStateDB) ContextOfSnapshot(i int) sdk.Context { return m.snaps[i].Context() } +// Context implements types.StateDB. +func (m *MockStateDB) Context() sdk.Context { + return m.ctx +} + //////////////////////// MOCKED METHODS //////////////////////// // AddAddressToAccessList implements types.StateDB. diff --git a/x/evm/precompiles/erc20_registry/common_test.go b/x/evm/precompiles/erc20_registry/common_test.go index dba0ab6..8a8f09a 100644 --- a/x/evm/precompiles/erc20_registry/common_test.go +++ b/x/evm/precompiles/erc20_registry/common_test.go @@ -73,6 +73,11 @@ func (m *MockStateDB) ContextOfSnapshot(i int) sdk.Context { return m.snaps[i].Context() } +// Context implements types.StateDB. +func (m *MockStateDB) Context() sdk.Context { + return m.ctx +} + //////////////////////// MOCKED METHODS //////////////////////// // AddAddressToAccessList implements types.StateDB. diff --git a/x/evm/state/statedb.go b/x/evm/state/statedb.go index bf92b6c..1c6fd49 100644 --- a/x/evm/state/statedb.go +++ b/x/evm/state/statedb.go @@ -25,11 +25,6 @@ import ( evmtypes "github.com/initia-labs/minievm/x/evm/types" ) -type callableEVM interface { - Call(vm.ContractRef, common.Address, []byte, uint64, *uint256.Int) ([]byte, uint64, error) - StaticCall(vm.ContractRef, common.Address, []byte, uint64) ([]byte, uint64, error) -} - var _ vm.StateDB = &StateDB{} type StateDB struct { @@ -48,7 +43,7 @@ type StateDB struct { transientRefund collections.Map[uint64, uint64] execIndex uint64 - evm callableEVM + evm *vm.EVM erc20ABI *abi.ABI feeContractAddr common.Address // feeDenom contract address @@ -75,7 +70,7 @@ func NewStateDB( transientRefund collections.Map[uint64, uint64], execIndex *atomic.Uint64, // erc20 params - evm callableEVM, + evm *vm.EVM, erc20ABI *abi.ABI, feeContractAddr common.Address, ) (*StateDB, error) { @@ -130,7 +125,6 @@ func (s *StateDB) AddBalance(addr common.Address, amount *uint256.Int, _ tracing s.logger.Warn("failed to mint token", "error", err) panic(err) } - } // SubBalance burn coins from the account with addr @@ -585,6 +579,7 @@ func (s *StateDB) RevertToSnapshot(i int) { s.snaps = s.snaps[:i] } +// 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 @@ -593,6 +588,11 @@ func (s *StateDB) ContextOfSnapshot(i int) sdk.Context { return s.snaps[i].ctx } +// Context returns the current context +func (s *StateDB) Context() sdk.Context { + return s.ctx +} + // Prepare handles the preparatory steps for executing a state transition with. // This method must be invoked before state transition. // diff --git a/x/evm/types/expected_keeper.go b/x/evm/types/expected_keeper.go index cc53e25..be205f6 100644 --- a/x/evm/types/expected_keeper.go +++ b/x/evm/types/expected_keeper.go @@ -88,6 +88,7 @@ type IERC721Keeper interface { type StateDB interface { vm.StateDB ContextOfSnapshot(i int) sdk.Context + Context() sdk.Context } type GRPCRouter interface { 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 5/6] 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 From 9bcc1daf0e54076d481db5b7feb28d7cc81b3d28 Mon Sep 17 00:00:00 2001 From: beer-1 <147697694+beer-1@users.noreply.github.com> Date: Tue, 19 Nov 2024 21:47:21 +0900 Subject: [PATCH 6/6] feat: update ante handler to allow authz message (#116) * bump opinit to v0.6.1 * set bank keeper to authz keeper * update upgrade handler --- app/keepers/keepers.go | 1 + app/upgrade.go | 101 ++++++++++++++++++++------------------- go.mod | 2 +- go.sum | 4 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 2 +- 6 files changed, 59 insertions(+), 53 deletions(-) diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index d6d2b35..e54d5a2 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -284,6 +284,7 @@ func NewAppKeeper( appKeepers.FeeGrantKeeper = &feeGrantKeeper authzKeeper := authzkeeper.NewKeeper(runtime.NewKVStoreService(appKeepers.keys[authzkeeper.StoreKey]), appCodec, bApp.MsgServiceRouter(), appKeepers.AccountKeeper) + authzKeeper = authzKeeper.SetBankKeeper(appKeepers.BankKeeper) appKeepers.AuthzKeeper = &authzKeeper groupConfig := group.DefaultConfig() diff --git a/app/upgrade.go b/app/upgrade.go index f9ca920..6429fd4 100644 --- a/app/upgrade.go +++ b/app/upgrade.go @@ -22,7 +22,7 @@ import ( opchildtypes "github.com/initia-labs/OPinit/x/opchild/types" ) -const upgradeName = "0.6.5" +const upgradeName = "0.6.6" // RegisterUpgradeHandlers returns upgrade handlers func (app *MinitiaApp) RegisterUpgradeHandlers(cfg module.Configurator) { @@ -47,63 +47,68 @@ func (app *MinitiaApp) RegisterUpgradeHandlers(cfg module.Configurator) { //////////////////////////// MINIEVM /////////////////////////////////// - // deploy and store erc20 factory contract address - if err := app.EVMKeeper.DeployERC20Factory(ctx); err != nil && + // deploy and store erc20 wrapper contract address + if err := app.EVMKeeper.DeployERC20Wrapper(ctx); err != nil && // ignore contract address collision error (contract already deployed) !strings.Contains(err.Error(), vm.ErrContractAddressCollision.Error()) { return nil, err } - // deploy and store erc20 wrapper contract address - if err := app.EVMKeeper.DeployERC20Wrapper(ctx); err != nil && + // deploy and store erc20 factory contract address + if err := app.EVMKeeper.DeployERC20Factory(ctx); err != nil && // ignore contract address collision error (contract already deployed) !strings.Contains(err.Error(), vm.ErrContractAddressCollision.Error()) { return nil, err - } - - code := hexutil.MustDecode(erc20.Erc20MetaData.Bin) - - // runtime code - initCodeOP := common.Hex2Bytes("5ff3fe") - initCodePos := bytes.Index(code, initCodeOP) - code = code[initCodePos+3:] - - // code hash - codeHash := crypto.Keccak256Hash(code).Bytes() - - // iterate all erc20 contracts and replace contract code to new version - err = app.EVMKeeper.ERC20s.Walk(ctx, nil, func(contractAddr []byte) (bool, error) { - acc := app.AccountKeeper.GetAccount(ctx, contractAddr) - if acc == nil { - return true, fmt.Errorf("account not found for contract address %s", contractAddr) - } - - contractAcc, ok := acc.(*evmtypes.ContractAccount) - if !ok { - return true, fmt.Errorf("account is not a contract account for contract address %s", contractAddr) - } - - contractAcc.CodeHash = codeHash - app.AccountKeeper.SetAccount(ctx, contractAcc) - - // set code - codeKey := append(contractAddr, append(state.CodeKeyPrefix, codeHash...)...) - err := app.EVMKeeper.VMStore.Set(ctx, codeKey, code) + } else if err == nil { + // update erc20 contracts only if erc20 factory contract has been deployed without error. + // + // address collision error is ignored because it means that the contract has already been deployed + // and the erc20 contracts have already been updated. + // + code := hexutil.MustDecode(erc20.Erc20MetaData.Bin) + + // runtime code + initCodeOP := common.Hex2Bytes("5ff3fe") + initCodePos := bytes.Index(code, initCodeOP) + code = code[initCodePos+3:] + + // code hash + codeHash := crypto.Keccak256Hash(code).Bytes() + + // iterate all erc20 contracts and replace contract code to new version + err = app.EVMKeeper.ERC20s.Walk(ctx, nil, func(contractAddr []byte) (bool, error) { + acc := app.AccountKeeper.GetAccount(ctx, contractAddr) + if acc == nil { + return true, fmt.Errorf("account not found for contract address %s", contractAddr) + } + + contractAcc, ok := acc.(*evmtypes.ContractAccount) + if !ok { + return true, fmt.Errorf("account is not a contract account for contract address %s", contractAddr) + } + + contractAcc.CodeHash = codeHash + app.AccountKeeper.SetAccount(ctx, contractAcc) + + // set code + codeKey := append(contractAddr, append(state.CodeKeyPrefix, codeHash...)...) + err := app.EVMKeeper.VMStore.Set(ctx, codeKey, code) + if err != nil { + return true, err + } + + // set code size + codeSizeKey := append(contractAddr, append(state.CodeSizeKeyPrefix, codeHash...)...) + err = app.EVMKeeper.VMStore.Set(ctx, codeSizeKey, uint64ToBytes(uint64(len(code)))) + if err != nil { + return true, err + } + + return false, nil + }) if err != nil { - return true, err + return nil, err } - - // set code size - codeSizeKey := append(contractAddr, append(state.CodeSizeKeyPrefix, codeHash...)...) - err = app.EVMKeeper.VMStore.Set(ctx, codeSizeKey, uint64ToBytes(uint64(len(code)))) - if err != nil { - return true, err - } - - return false, nil - }) - if err != nil { - return nil, err } return versionMap, nil diff --git a/go.mod b/go.mod index 4853541..c92459d 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/hashicorp/go-metrics v0.5.3 github.com/hashicorp/golang-lru/v2 v2.0.7 github.com/holiman/uint256 v1.3.1 - github.com/initia-labs/OPinit v0.6.0 + github.com/initia-labs/OPinit v0.6.1 github.com/initia-labs/initia v0.6.1 github.com/initia-labs/kvindexer v0.1.9 github.com/initia-labs/kvindexer/submodules/block v0.1.0 diff --git a/go.sum b/go.sum index a04a9af..827dcf7 100644 --- a/go.sum +++ b/go.sum @@ -1433,8 +1433,8 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/initia-labs/OPinit v0.6.0 h1:V9jQf8+PjNctLX31FHMGUsk6fpnygVJO1WYzCmBMzkU= -github.com/initia-labs/OPinit v0.6.0/go.mod h1:gDpCh4Zx94mihwgzP/PLav8eVHLroZBu3dFyzCy8iIs= +github.com/initia-labs/OPinit v0.6.1 h1:G9ebeYeqPlV9Z2s3JdSWfwQAUgIM+nhkcA8xSJUMR7M= +github.com/initia-labs/OPinit v0.6.1/go.mod h1:gDpCh4Zx94mihwgzP/PLav8eVHLroZBu3dFyzCy8iIs= github.com/initia-labs/OPinit/api v0.6.0 h1:Q3hDHpTd9EqlDfY/OryCKIwuXYWJxGJdGfJicV1RjL4= github.com/initia-labs/OPinit/api v0.6.0/go.mod h1:gHK6DEWb3/DqQD5LjKirUx9jilAh2UioXanoQdgqVfU= github.com/initia-labs/cometbft v0.0.0-20241113064430-a371e2dc387f h1:PpYBvJ0L58bAgH7KwS/7GBEUphLnhf4fnTLua9uOov8= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 3f0a0ad..127e5ec 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -146,7 +146,7 @@ require ( github.com/iancoleman/strcase v0.3.0 // indirect github.com/improbable-eng/grpc-web v0.15.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/initia-labs/OPinit v0.6.0 // indirect + github.com/initia-labs/OPinit v0.6.1 // indirect github.com/initia-labs/OPinit/api v0.6.0 // indirect github.com/initia-labs/kvindexer v0.1.9 // indirect github.com/initia-labs/kvindexer/submodules/block v0.1.0 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 1a6d8bf..37c8801 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1393,7 +1393,7 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/initia-labs/OPinit v0.6.0 h1:V9jQf8+PjNctLX31FHMGUsk6fpnygVJO1WYzCmBMzkU= +github.com/initia-labs/OPinit v0.6.1 h1:G9ebeYeqPlV9Z2s3JdSWfwQAUgIM+nhkcA8xSJUMR7M= github.com/initia-labs/OPinit/api v0.6.0 h1:Q3hDHpTd9EqlDfY/OryCKIwuXYWJxGJdGfJicV1RjL4= github.com/initia-labs/cometbft v0.0.0-20241113064430-a371e2dc387f h1:PpYBvJ0L58bAgH7KwS/7GBEUphLnhf4fnTLua9uOov8= github.com/initia-labs/cometbft v0.0.0-20241113064430-a371e2dc387f/go.mod h1:y7+6kPknafzWlkSMCekzXC81wpRf1pcVAUnO0wRy9lQ=