From d5ae01d830224933656d364c7c94ed0c378ace3b Mon Sep 17 00:00:00 2001 From: mmsqe Date: Tue, 26 Sep 2023 09:12:56 +0800 Subject: [PATCH 01/26] add cb larger maxCallbackGas --- app/app.go | 8 ++++++-- go.mod | 3 +++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/app/app.go b/app/app.go index 37ae47cd2c..55059c2185 100644 --- a/app/app.go +++ b/app/app.go @@ -98,6 +98,7 @@ import ( upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client" upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + ibccallbacks "github.com/cosmos/ibc-go/modules/apps/callbacks" ibcfee "github.com/cosmos/ibc-go/v7/modules/apps/29-fee" ibcfeekeeper "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/keeper" ibcfeetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" @@ -655,8 +656,11 @@ func New( icaAuthModule := icaauth.NewAppModule(appCodec, app.ICAAuthKeeper) icaAuthIBCModule := icaauth.NewIBCModule(app.ICAAuthKeeper) - icaControllerIBCModule := icacontroller.NewIBCMiddleware(icaAuthIBCModule, app.ICAControllerKeeper) - icaControllerStack := ibcfee.NewIBCMiddleware(icaControllerIBCModule, app.IBCFeeKeeper) + var icaControllerStack porttypes.IBCModule + icaControllerStack = icacontroller.NewIBCMiddleware(icaAuthIBCModule, app.ICAControllerKeeper) + icaControllerStack = ibcfee.NewIBCMiddleware(icaControllerStack, app.IBCFeeKeeper) + const maxCallbackGas = uint64(1000000) + icaControllerStack = ibccallbacks.NewIBCMiddleware(icaControllerStack, app.IBCFeeKeeper, app.CronosKeeper, maxCallbackGas) // Create static IBC router, add transfer route, then set and seal it ibcRouter := porttypes.NewRouter() diff --git a/go.mod b/go.mod index f65581b887..a9cb77baa5 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/cosmos/cosmos-proto v1.0.0-beta.2 github.com/cosmos/cosmos-sdk v0.47.5 github.com/cosmos/gogoproto v1.4.10 + github.com/cosmos/ibc-go/modules/apps/callbacks v0.0.0-20230925162011-0364aae96f03 github.com/cosmos/ibc-go/v7 v7.3.1-0.20230920070810-c3261472c815 github.com/crypto-org-chain/cronos/store v0.0.4 github.com/crypto-org-chain/cronos/versiondb v0.0.0-00010101000000-000000000000 @@ -226,6 +227,8 @@ replace ( github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0 github.com/cometbft/cometbft-db => github.com/crypto-org-chain/cometbft-db v0.0.0-20230921030527-0d47d7537e32 github.com/cosmos/cosmos-sdk => github.com/crypto-org-chain/cosmos-sdk v0.46.0-beta2.0.20230905040840-b3af5590283b + // github.com/cosmos/ibc-go/modules/apps/callbacks => github.com/cosmos/ibc-go/modules/apps/callbacks v0.0.0-0.20230920070810-c3261472c815 + github.com/cosmos/ibc-go/modules/apps/callbacks => ../ibc-go/modules/apps/callbacks github.com/crypto-org-chain/cronos/memiavl => ./memiavl github.com/crypto-org-chain/cronos/store => ./store github.com/crypto-org-chain/cronos/versiondb => ./versiondb From 6ce558b9df435cf67ddd6125e1fb0444a5b3df2a Mon Sep 17 00:00:00 2001 From: mmsqe Date: Tue, 26 Sep 2023 09:14:01 +0800 Subject: [PATCH 02/26] add interface --- x/cronos/keeper/keeper.go | 66 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/x/cronos/keeper/keeper.go b/x/cronos/keeper/keeper.go index d59b2005a6..cf3f7d6b8a 100644 --- a/x/cronos/keeper/keeper.go +++ b/x/cronos/keeper/keeper.go @@ -15,6 +15,9 @@ import ( storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" "github.com/crypto-org-chain/cronos/v2/x/cronos/types" "github.com/ethereum/go-ethereum/common" // this line is used by starport scaffolding # ibc/keeper/import @@ -276,3 +279,66 @@ func (k Keeper) RegisterOrUpdateTokenMapping(ctx sdk.Context, msg *types.MsgUpda return nil } + +// IBCOnAcknowledgementPacketCallback returns nil if the gas meter has greater than +// or equal to 500_000 gas remaining. +// This function oog panics if the gas remaining is less than 500_000. +// This function errors if the authAddress is MockCallbackUnauthorizedAddress. +func (k Keeper) IBCOnAcknowledgementPacketCallback( + ctx sdk.Context, + packet channeltypes.Packet, + acknowledgement []byte, + relayer sdk.AccAddress, + contractAddress, + packetSenderAddress string, +) error { + // return k.processMockCallback(ctx, callbacktypes.CallbackTypeAcknowledgementPacket, packetSenderAddress) + return nil +} + +// IBCOnTimeoutPacketCallback returns nil if the gas meter has greater than +// or equal to 500_000 gas remaining. +// This function oog panics if the gas remaining is less than 500_000. +// This function errors if the authAddress is MockCallbackUnauthorizedAddress. +func (k Keeper) IBCOnTimeoutPacketCallback( + ctx sdk.Context, + packet channeltypes.Packet, + relayer sdk.AccAddress, + contractAddress, + packetSenderAddress string, +) error { + // return k.processMockCallback(ctx, callbacktypes.CallbackTypeTimeoutPacket, packetSenderAddress) + return nil +} + +// IBCReceivePacketCallback returns nil if the gas meter has greater than +// or equal to 500_000 gas remaining. +// This function oog panics if the gas remaining is less than 500_000. +// This function errors if the authAddress is MockCallbackUnauthorizedAddress. +func (k Keeper) IBCReceivePacketCallback( + ctx sdk.Context, + packet ibcexported.PacketI, + ack ibcexported.Acknowledgement, + contractAddress string, +) error { + // return k.processMockCallback(ctx, callbacktypes.CallbackTypeReceivePacket, "") + return nil +} + +// IBCPacketSendCallback returns nil if the gas meter has greater than +// or equal to 500_000 gas remaining. +// This function oog panics if the gas remaining is less than 500_000. +// This function errors if the authAddress is MockCallbackUnauthorizedAddress. +func (k Keeper) IBCSendPacketCallback( + ctx sdk.Context, + sourcePort string, + sourceChannel string, + timeoutHeight clienttypes.Height, + timeoutTimestamp uint64, + packetData []byte, + contractAddress, + packetSenderAddress string, +) error { + // return k.processMockCallback(ctx, callbacktypes.CallbackTypeSendPacket, packetSenderAddress) + return nil +} From bbfb458ddac489631656fe1243a5fe90f709004a Mon Sep 17 00:00:00 2001 From: mmsqe Date: Tue, 26 Sep 2023 09:51:22 +0800 Subject: [PATCH 03/26] go mod tidy --- go.mod | 4 +--- go.sum | 2 ++ gomod2nix.toml | 3 +++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index a9cb77baa5..972d569792 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/cosmos/cosmos-proto v1.0.0-beta.2 github.com/cosmos/cosmos-sdk v0.47.5 github.com/cosmos/gogoproto v1.4.10 - github.com/cosmos/ibc-go/modules/apps/callbacks v0.0.0-20230925162011-0364aae96f03 + github.com/cosmos/ibc-go/modules/apps/callbacks v0.1.1-0.20230831194909-17cf1260a9cd github.com/cosmos/ibc-go/v7 v7.3.1-0.20230920070810-c3261472c815 github.com/crypto-org-chain/cronos/store v0.0.4 github.com/crypto-org-chain/cronos/versiondb v0.0.0-00010101000000-000000000000 @@ -227,8 +227,6 @@ replace ( github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0 github.com/cometbft/cometbft-db => github.com/crypto-org-chain/cometbft-db v0.0.0-20230921030527-0d47d7537e32 github.com/cosmos/cosmos-sdk => github.com/crypto-org-chain/cosmos-sdk v0.46.0-beta2.0.20230905040840-b3af5590283b - // github.com/cosmos/ibc-go/modules/apps/callbacks => github.com/cosmos/ibc-go/modules/apps/callbacks v0.0.0-0.20230920070810-c3261472c815 - github.com/cosmos/ibc-go/modules/apps/callbacks => ../ibc-go/modules/apps/callbacks github.com/crypto-org-chain/cronos/memiavl => ./memiavl github.com/crypto-org-chain/cronos/store => ./store github.com/crypto-org-chain/cronos/versiondb => ./versiondb diff --git a/go.sum b/go.sum index 46b6476148..033ff091b1 100644 --- a/go.sum +++ b/go.sum @@ -452,6 +452,8 @@ github.com/cosmos/gogoproto v1.4.10 h1:QH/yT8X+c0F4ZDacDv3z+xE3WU1P1Z3wQoLMBRJoK github.com/cosmos/gogoproto v1.4.10/go.mod h1:3aAZzeRWpAwr+SS/LLkICX2/kDFyaYVzckBDzygIxek= github.com/cosmos/iavl v0.21.0-alpha.1.0.20230904092046-df3db2d96583 h1:3Matt7/LjZiZkIBPalYazOZcw2B05Ch14dU5TJyqJEc= github.com/cosmos/iavl v0.21.0-alpha.1.0.20230904092046-df3db2d96583/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= +github.com/cosmos/ibc-go/modules/apps/callbacks v0.1.1-0.20230831194909-17cf1260a9cd h1:KVnAwC1d0b+LWrVi+U1rex0e9LlyGTZ17zYhU3S4il8= +github.com/cosmos/ibc-go/modules/apps/callbacks v0.1.1-0.20230831194909-17cf1260a9cd/go.mod h1:h+JtOsdOs/ikuntjZFXOAa8qnXUfgkTcRSHaTTcAM+M= github.com/cosmos/ibc-go/v7 v7.3.1-0.20230920070810-c3261472c815 h1:raSo7w7B3IXCb7DZozHWz8ajG7HLWZw9foiyCbEgInI= github.com/cosmos/ibc-go/v7 v7.3.1-0.20230920070810-c3261472c815/go.mod h1:wvx4pPBofe5ZdMNV3OFRxSI4auEP5Qfqf8JXLLNV04g= github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM= diff --git a/gomod2nix.toml b/gomod2nix.toml index f5bf557fb7..af1504ac59 100644 --- a/gomod2nix.toml +++ b/gomod2nix.toml @@ -154,6 +154,9 @@ schema = 3 [mod."github.com/cosmos/iavl"] version = "v0.21.0-alpha.1.0.20230904092046-df3db2d96583" hash = "sha256-3Va8Ljq63IXty0oHlRpqfsC6WsMut6TWZ2R+/nYtfTU=" + [mod."github.com/cosmos/ibc-go/modules/apps/callbacks"] + version = "v0.1.1-0.20230831194909-17cf1260a9cd" + hash = "sha256-kVvGNQt3A1H6pQs3YtMvx1t9nNcL6ClKnIfsR24OTi8=" [mod."github.com/cosmos/ibc-go/v7"] version = "v7.3.1-0.20230920070810-c3261472c815" hash = "sha256-x/D64hmU+aOc5sm8RzXMB+8y+530+CCEik/Zpj3Rf9A=" From 300a8c50b18ad3d59fddfadf77530f51a70ffe66 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Tue, 26 Sep 2023 09:13:50 +0800 Subject: [PATCH 04/26] gen binding pack method add cb --- app/app.go | 2 + .../precompile/ica/i_ica_module.abigen.go | 44 ++++++++++++++++++- x/cronos/events/bindings/src/ICA.sol | 2 + x/cronos/events/events.go | 4 +- x/cronos/keeper/evm.go | 10 +++-- x/cronos/keeper/keeper.go | 24 +++++++--- x/cronos/keeper/precompiles/ica.go | 22 +++++++++- 7 files changed, 94 insertions(+), 14 deletions(-) diff --git a/app/app.go b/app/app.go index 55059c2185..5d11554ce0 100644 --- a/app/app.go +++ b/app/app.go @@ -659,6 +659,8 @@ func New( var icaControllerStack porttypes.IBCModule icaControllerStack = icacontroller.NewIBCMiddleware(icaAuthIBCModule, app.ICAControllerKeeper) icaControllerStack = ibcfee.NewIBCMiddleware(icaControllerStack, app.IBCFeeKeeper) + // Since the callbacks middleware itself is an ics4wrapper, it needs to be passed to the ica controller keeper + app.ICAControllerKeeper.WithICS4Wrapper(icaControllerStack.(porttypes.Middleware)) const maxCallbackGas = uint64(1000000) icaControllerStack = ibccallbacks.NewIBCMiddleware(icaControllerStack, app.IBCFeeKeeper, app.CronosKeeper, maxCallbackGas) diff --git a/x/cronos/events/bindings/cosmos/precompile/ica/i_ica_module.abigen.go b/x/cronos/events/bindings/cosmos/precompile/ica/i_ica_module.abigen.go index 7f05447446..dfc2242bb3 100644 --- a/x/cronos/events/bindings/cosmos/precompile/ica/i_ica_module.abigen.go +++ b/x/cronos/events/bindings/cosmos/precompile/ica/i_ica_module.abigen.go @@ -30,7 +30,7 @@ var ( // ICAModuleMetaData contains all meta data concerning the ICAModule contract. var ICAModuleMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"}],\"name\":\"SubmitMsgsResult\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"queryAccount\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"}],\"name\":\"registerAccount\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"timeout\",\"type\":\"uint256\"}],\"name\":\"submitMsgs\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"}],\"name\":\"SubmitMsgsResult\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"},{\"internalType\":\"string\",\"name\":\"packetSenderAddress\",\"type\":\"string\"}],\"name\":\"onAcknowledgementPacketCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"},{\"internalType\":\"string\",\"name\":\"packetSenderAddress\",\"type\":\"string\"}],\"name\":\"onTimeoutPacketCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"queryAccount\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"}],\"name\":\"registerAccount\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"timeout\",\"type\":\"uint256\"}],\"name\":\"submitMsgs\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", } // ICAModuleABI is the input ABI used to generate the binding from. @@ -210,6 +210,48 @@ func (_ICAModule *ICAModuleCallerSession) QueryAccount(connectionID string, addr return _ICAModule.Contract.QueryAccount(&_ICAModule.CallOpts, connectionID, addr) } +// OnAcknowledgementPacketCallback is a paid mutator transaction binding the contract method 0x7f15df2f. +// +// Solidity: function onAcknowledgementPacketCallback(uint64 seq, string packetSenderAddress) payable returns(bool) +func (_ICAModule *ICAModuleTransactor) OnAcknowledgementPacketCallback(opts *bind.TransactOpts, seq uint64, packetSenderAddress string) (*types.Transaction, error) { + return _ICAModule.contract.Transact(opts, "onAcknowledgementPacketCallback", seq, packetSenderAddress) +} + +// OnAcknowledgementPacketCallback is a paid mutator transaction binding the contract method 0x7f15df2f. +// +// Solidity: function onAcknowledgementPacketCallback(uint64 seq, string packetSenderAddress) payable returns(bool) +func (_ICAModule *ICAModuleSession) OnAcknowledgementPacketCallback(seq uint64, packetSenderAddress string) (*types.Transaction, error) { + return _ICAModule.Contract.OnAcknowledgementPacketCallback(&_ICAModule.TransactOpts, seq, packetSenderAddress) +} + +// OnAcknowledgementPacketCallback is a paid mutator transaction binding the contract method 0x7f15df2f. +// +// Solidity: function onAcknowledgementPacketCallback(uint64 seq, string packetSenderAddress) payable returns(bool) +func (_ICAModule *ICAModuleTransactorSession) OnAcknowledgementPacketCallback(seq uint64, packetSenderAddress string) (*types.Transaction, error) { + return _ICAModule.Contract.OnAcknowledgementPacketCallback(&_ICAModule.TransactOpts, seq, packetSenderAddress) +} + +// OnTimeoutPacketCallback is a paid mutator transaction binding the contract method 0xd72be239. +// +// Solidity: function onTimeoutPacketCallback(uint64 seq, string packetSenderAddress) payable returns(bool) +func (_ICAModule *ICAModuleTransactor) OnTimeoutPacketCallback(opts *bind.TransactOpts, seq uint64, packetSenderAddress string) (*types.Transaction, error) { + return _ICAModule.contract.Transact(opts, "onTimeoutPacketCallback", seq, packetSenderAddress) +} + +// OnTimeoutPacketCallback is a paid mutator transaction binding the contract method 0xd72be239. +// +// Solidity: function onTimeoutPacketCallback(uint64 seq, string packetSenderAddress) payable returns(bool) +func (_ICAModule *ICAModuleSession) OnTimeoutPacketCallback(seq uint64, packetSenderAddress string) (*types.Transaction, error) { + return _ICAModule.Contract.OnTimeoutPacketCallback(&_ICAModule.TransactOpts, seq, packetSenderAddress) +} + +// OnTimeoutPacketCallback is a paid mutator transaction binding the contract method 0xd72be239. +// +// Solidity: function onTimeoutPacketCallback(uint64 seq, string packetSenderAddress) payable returns(bool) +func (_ICAModule *ICAModuleTransactorSession) OnTimeoutPacketCallback(seq uint64, packetSenderAddress string) (*types.Transaction, error) { + return _ICAModule.Contract.OnTimeoutPacketCallback(&_ICAModule.TransactOpts, seq, packetSenderAddress) +} + // RegisterAccount is a paid mutator transaction binding the contract method 0xddc7b6a7. // // Solidity: function registerAccount(string connectionID, string version) payable returns(bool) diff --git a/x/cronos/events/bindings/src/ICA.sol b/x/cronos/events/bindings/src/ICA.sol index 31f10530a7..b57bddc503 100644 --- a/x/cronos/events/bindings/src/ICA.sol +++ b/x/cronos/events/bindings/src/ICA.sol @@ -6,4 +6,6 @@ interface IICAModule { function registerAccount(string calldata connectionID, string calldata version) external payable returns (bool); function queryAccount(string calldata connectionID, address addr) external view returns (string memory); function submitMsgs(string calldata connectionID, bytes calldata data, uint256 timeout) external payable returns (uint64); + function onAcknowledgementPacketCallback(uint64 seq, string calldata packetSenderAddress) external payable returns (bool); + function onTimeoutPacketCallback(uint64 seq, string calldata packetSenderAddress) external payable returns (bool); } diff --git a/x/cronos/events/events.go b/x/cronos/events/events.go index 57da3426ff..d4b0a98be4 100644 --- a/x/cronos/events/events.go +++ b/x/cronos/events/events.go @@ -35,9 +35,7 @@ var ( transfertypes.AttributeKeyDenom: ReturnStringAsIs, } IcaValueDecoders = ValueDecoders{ - channeltypes.AttributeKeyChannelID: ReturnStringAsIs, - channeltypes.AttributeKeyPortID: ReturnStringAsIs, - cronoseventstypes.AttributeKeySeq: ConvertUint64, + cronoseventstypes.AttributeKeySeq: ConvertUint64, } ) diff --git a/x/cronos/keeper/evm.go b/x/cronos/keeper/evm.go index b5b1cfe42d..2108e32ac6 100644 --- a/x/cronos/keeper/evm.go +++ b/x/cronos/keeper/evm.go @@ -19,9 +19,14 @@ const DefaultGasCap uint64 = 25000000 // CallEVM execute an evm message from native module func (k Keeper) CallEVM(ctx sdk.Context, to *common.Address, data []byte, value *big.Int) (*ethtypes.Message, *evmtypes.MsgEthereumTxResponse, error) { - nonce := k.evmKeeper.GetNonce(ctx, types.EVMModuleAddress) + return k.CallEVMWithArgs(ctx, to, types.EVMModuleAddress, data, value) +} + +// CallEVMWithArgs execute an evm message with args +func (k Keeper) CallEVMWithArgs(ctx sdk.Context, to *common.Address, from common.Address, data []byte, value *big.Int) (*ethtypes.Message, *evmtypes.MsgEthereumTxResponse, error) { + nonce := k.evmKeeper.GetNonce(ctx, from) msg := ethtypes.NewMessage( - types.EVMModuleAddress, + common.Address(from.Bytes()), to, nonce, value, // amount @@ -31,7 +36,6 @@ func (k Keeper) CallEVM(ctx sdk.Context, to *common.Address, data []byte, value nil, // accessList false, // isFake ) - ret, err := k.evmKeeper.ApplyMessage(ctx, msg, nil, true) if err != nil { return nil, nil, err diff --git a/x/cronos/keeper/keeper.go b/x/cronos/keeper/keeper.go index cf3f7d6b8a..e26f933ca1 100644 --- a/x/cronos/keeper/keeper.go +++ b/x/cronos/keeper/keeper.go @@ -2,6 +2,7 @@ package keeper import ( "fmt" + "math/big" "strings" "cosmossdk.io/errors" @@ -18,6 +19,7 @@ import ( clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" + cronosprecompiles "github.com/crypto-org-chain/cronos/v2/x/cronos/keeper/precompiles" "github.com/crypto-org-chain/cronos/v2/x/cronos/types" "github.com/ethereum/go-ethereum/common" // this line is used by starport scaffolding # ibc/keeper/import @@ -292,8 +294,14 @@ func (k Keeper) IBCOnAcknowledgementPacketCallback( contractAddress, packetSenderAddress string, ) error { - // return k.processMockCallback(ctx, callbacktypes.CallbackTypeAcknowledgementPacket, packetSenderAddress) - return nil + relayerAddr := common.BytesToAddress(relayer.Bytes()) + precompileAddr := common.HexToAddress(contractAddress) + data, err := cronosprecompiles.GetOnAcknowledgementPacketCallback(packet.Sequence, packetSenderAddress) + if err != nil { + return err + } + _, _, err = k.CallEVMWithArgs(ctx, &precompileAddr, relayerAddr, data, big.NewInt(0)) + return err } // IBCOnTimeoutPacketCallback returns nil if the gas meter has greater than @@ -307,8 +315,14 @@ func (k Keeper) IBCOnTimeoutPacketCallback( contractAddress, packetSenderAddress string, ) error { - // return k.processMockCallback(ctx, callbacktypes.CallbackTypeTimeoutPacket, packetSenderAddress) - return nil + relayerAddr := common.BytesToAddress(relayer.Bytes()) + precompileAddr := common.HexToAddress(contractAddress) + data, err := cronosprecompiles.GetOnTimeoutPacketCallbackk(packet.Sequence, packetSenderAddress) + if err != nil { + return err + } + _, _, err = k.CallEVMWithArgs(ctx, &precompileAddr, relayerAddr, data, big.NewInt(0)) + return err } // IBCReceivePacketCallback returns nil if the gas meter has greater than @@ -321,7 +335,6 @@ func (k Keeper) IBCReceivePacketCallback( ack ibcexported.Acknowledgement, contractAddress string, ) error { - // return k.processMockCallback(ctx, callbacktypes.CallbackTypeReceivePacket, "") return nil } @@ -339,6 +352,5 @@ func (k Keeper) IBCSendPacketCallback( contractAddress, packetSenderAddress string, ) error { - // return k.processMockCallback(ctx, callbacktypes.CallbackTypeSendPacket, packetSenderAddress) return nil } diff --git a/x/cronos/keeper/precompiles/ica.go b/x/cronos/keeper/precompiles/ica.go index 077627acb1..4cab5b17aa 100644 --- a/x/cronos/keeper/precompiles/ica.go +++ b/x/cronos/keeper/precompiles/ica.go @@ -33,6 +33,14 @@ func init() { } } +func GetOnAcknowledgementPacketCallback(args ...interface{}) ([]byte, error) { + return icaABI.Pack("onAcknowledgementPacketCallback", args...) +} + +func GetOnTimeoutPacketCallbackk(args ...interface{}) ([]byte, error) { + return icaABI.Pack("onTimeoutPacketCallback", args...) +} + type IcaContract struct { BaseContract @@ -68,7 +76,6 @@ func (ic *IcaContract) Run(evm *vm.EVM, contract *vm.Contract, readonly bool) ([ if err != nil { return nil, err } - stateDB := evm.StateDB.(ExtStateDB) precompileAddr := ic.Address() caller := contract.CallerAddress @@ -134,6 +141,7 @@ func (ic *IcaContract) Run(evm *vm.EVM, contract *vm.Contract, readonly bool) ([ icaMsgData := icatypes.InterchainAccountPacketData{ Type: icatypes.EXECUTE_TX, Data: data, + Memo: fmt.Sprintf(`{"src_callback": {"address": "%s"}}`, icaContractAddress.String()), } timeoutDuration := time.Duration(timeout.Uint64()) seq := uint64(0) @@ -160,6 +168,18 @@ func (ic *IcaContract) Run(evm *vm.EVM, contract *vm.Contract, readonly bool) ([ return nil, execErr } return method.Outputs.Pack(seq) + case "onAcknowledgementPacketCallback", "onTimeoutPacketCallback": + if readonly { + return nil, errors.New("the method is not readonly") + } + args, err := method.Inputs.Unpack(contract.Input[4:]) + if err != nil { + return nil, errors.New("fail to unpack input arguments") + } + seq := args[0].(uint64) + packetSenderAddress := args[1].(string) + fmt.Printf("mm-%s, %d, %s\n", method.Name, seq, packetSenderAddress) + return method.Outputs.Pack(true) default: return nil, errors.New("unknown method") } From 629eed9a7c940e62b3ff16bd097a0c176d9ad977 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Tue, 26 Sep 2023 14:46:20 +0800 Subject: [PATCH 05/26] use cb events --- .../precompile/ica/i_ica_module.abigen.go | 287 +++++++++++++++++- x/cronos/events/bindings/src/ICA.sol | 23 ++ x/cronos/events/events.go | 16 +- 3 files changed, 324 insertions(+), 2 deletions(-) diff --git a/x/cronos/events/bindings/cosmos/precompile/ica/i_ica_module.abigen.go b/x/cronos/events/bindings/cosmos/precompile/ica/i_ica_module.abigen.go index dfc2242bb3..277e2c80fe 100644 --- a/x/cronos/events/bindings/cosmos/precompile/ica/i_ica_module.abigen.go +++ b/x/cronos/events/bindings/cosmos/precompile/ica/i_ica_module.abigen.go @@ -30,7 +30,7 @@ var ( // ICAModuleMetaData contains all meta data concerning the ICAModule contract. var ICAModuleMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"}],\"name\":\"SubmitMsgsResult\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"},{\"internalType\":\"string\",\"name\":\"packetSenderAddress\",\"type\":\"string\"}],\"name\":\"onAcknowledgementPacketCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"},{\"internalType\":\"string\",\"name\":\"packetSenderAddress\",\"type\":\"string\"}],\"name\":\"onTimeoutPacketCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"queryAccount\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"}],\"name\":\"registerAccount\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"timeout\",\"type\":\"uint256\"}],\"name\":\"submitMsgs\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"module\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"callbackType\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"callbackAddress\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"callbackResult\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"callbackError\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"callbackExecGasLimit\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"callbackCommitGasLimit\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"packetDestPort\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"packetDestChannel\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"packetSequence\",\"type\":\"string\"}],\"name\":\"DestinationCallback\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"module\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"callbackType\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"callbackAddress\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"callbackResult\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"callbackExecGasLimit\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"callbackCommitGasLimit\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"packetSrcPort\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"packetSrcChannel\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"packetSequence\",\"type\":\"string\"}],\"name\":\"SourceCallback\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"}],\"name\":\"SubmitMsgsResult\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"},{\"internalType\":\"string\",\"name\":\"packetSenderAddress\",\"type\":\"string\"}],\"name\":\"onAcknowledgementPacketCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"},{\"internalType\":\"string\",\"name\":\"packetSenderAddress\",\"type\":\"string\"}],\"name\":\"onTimeoutPacketCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"queryAccount\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"}],\"name\":\"registerAccount\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"timeout\",\"type\":\"uint256\"}],\"name\":\"submitMsgs\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", } // ICAModuleABI is the input ABI used to generate the binding from. @@ -294,6 +294,291 @@ func (_ICAModule *ICAModuleTransactorSession) SubmitMsgs(connectionID string, da return _ICAModule.Contract.SubmitMsgs(&_ICAModule.TransactOpts, connectionID, data, timeout) } +// ICAModuleDestinationCallbackIterator is returned from FilterDestinationCallback and is used to iterate over the raw logs and unpacked data for DestinationCallback events raised by the ICAModule contract. +type ICAModuleDestinationCallbackIterator struct { + Event *ICAModuleDestinationCallback // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ICAModuleDestinationCallbackIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ICAModuleDestinationCallback) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ICAModuleDestinationCallback) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ICAModuleDestinationCallbackIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ICAModuleDestinationCallbackIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ICAModuleDestinationCallback represents a DestinationCallback event raised by the ICAModule contract. +type ICAModuleDestinationCallback struct { + Module string + CallbackType string + CallbackAddress string + CallbackResult string + CallbackError string + CallbackExecGasLimit string + CallbackCommitGasLimit string + PacketDestPort string + PacketDestChannel string + PacketSequence string + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDestinationCallback is a free log retrieval operation binding the contract event 0x2ae174bea5540138f8433743ac6f4338f304522f95b07f0fbfaeb260143a71ba. +// +// Solidity: event DestinationCallback(string module, string callbackType, string callbackAddress, string callbackResult, string callbackError, string callbackExecGasLimit, string callbackCommitGasLimit, string packetDestPort, string packetDestChannel, string packetSequence) +func (_ICAModule *ICAModuleFilterer) FilterDestinationCallback(opts *bind.FilterOpts) (*ICAModuleDestinationCallbackIterator, error) { + + logs, sub, err := _ICAModule.contract.FilterLogs(opts, "DestinationCallback") + if err != nil { + return nil, err + } + return &ICAModuleDestinationCallbackIterator{contract: _ICAModule.contract, event: "DestinationCallback", logs: logs, sub: sub}, nil +} + +// WatchDestinationCallback is a free log subscription operation binding the contract event 0x2ae174bea5540138f8433743ac6f4338f304522f95b07f0fbfaeb260143a71ba. +// +// Solidity: event DestinationCallback(string module, string callbackType, string callbackAddress, string callbackResult, string callbackError, string callbackExecGasLimit, string callbackCommitGasLimit, string packetDestPort, string packetDestChannel, string packetSequence) +func (_ICAModule *ICAModuleFilterer) WatchDestinationCallback(opts *bind.WatchOpts, sink chan<- *ICAModuleDestinationCallback) (event.Subscription, error) { + + logs, sub, err := _ICAModule.contract.WatchLogs(opts, "DestinationCallback") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ICAModuleDestinationCallback) + if err := _ICAModule.contract.UnpackLog(event, "DestinationCallback", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseDestinationCallback is a log parse operation binding the contract event 0x2ae174bea5540138f8433743ac6f4338f304522f95b07f0fbfaeb260143a71ba. +// +// Solidity: event DestinationCallback(string module, string callbackType, string callbackAddress, string callbackResult, string callbackError, string callbackExecGasLimit, string callbackCommitGasLimit, string packetDestPort, string packetDestChannel, string packetSequence) +func (_ICAModule *ICAModuleFilterer) ParseDestinationCallback(log types.Log) (*ICAModuleDestinationCallback, error) { + event := new(ICAModuleDestinationCallback) + if err := _ICAModule.contract.UnpackLog(event, "DestinationCallback", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ICAModuleSourceCallbackIterator is returned from FilterSourceCallback and is used to iterate over the raw logs and unpacked data for SourceCallback events raised by the ICAModule contract. +type ICAModuleSourceCallbackIterator struct { + Event *ICAModuleSourceCallback // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ICAModuleSourceCallbackIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ICAModuleSourceCallback) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ICAModuleSourceCallback) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ICAModuleSourceCallbackIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ICAModuleSourceCallbackIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ICAModuleSourceCallback represents a SourceCallback event raised by the ICAModule contract. +type ICAModuleSourceCallback struct { + Module string + CallbackType string + CallbackAddress string + CallbackResult string + CallbackExecGasLimit string + CallbackCommitGasLimit string + PacketSrcPort string + PacketSrcChannel string + PacketSequence string + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSourceCallback is a free log retrieval operation binding the contract event 0xb76e53cebd913fb7a3a645584b8ee6889866564177fc6a11ada9f86b66046ac3. +// +// Solidity: event SourceCallback(string module, string callbackType, string callbackAddress, string callbackResult, string callbackExecGasLimit, string callbackCommitGasLimit, string packetSrcPort, string packetSrcChannel, string packetSequence) +func (_ICAModule *ICAModuleFilterer) FilterSourceCallback(opts *bind.FilterOpts) (*ICAModuleSourceCallbackIterator, error) { + + logs, sub, err := _ICAModule.contract.FilterLogs(opts, "SourceCallback") + if err != nil { + return nil, err + } + return &ICAModuleSourceCallbackIterator{contract: _ICAModule.contract, event: "SourceCallback", logs: logs, sub: sub}, nil +} + +// WatchSourceCallback is a free log subscription operation binding the contract event 0xb76e53cebd913fb7a3a645584b8ee6889866564177fc6a11ada9f86b66046ac3. +// +// Solidity: event SourceCallback(string module, string callbackType, string callbackAddress, string callbackResult, string callbackExecGasLimit, string callbackCommitGasLimit, string packetSrcPort, string packetSrcChannel, string packetSequence) +func (_ICAModule *ICAModuleFilterer) WatchSourceCallback(opts *bind.WatchOpts, sink chan<- *ICAModuleSourceCallback) (event.Subscription, error) { + + logs, sub, err := _ICAModule.contract.WatchLogs(opts, "SourceCallback") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ICAModuleSourceCallback) + if err := _ICAModule.contract.UnpackLog(event, "SourceCallback", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseSourceCallback is a log parse operation binding the contract event 0xb76e53cebd913fb7a3a645584b8ee6889866564177fc6a11ada9f86b66046ac3. +// +// Solidity: event SourceCallback(string module, string callbackType, string callbackAddress, string callbackResult, string callbackExecGasLimit, string callbackCommitGasLimit, string packetSrcPort, string packetSrcChannel, string packetSequence) +func (_ICAModule *ICAModuleFilterer) ParseSourceCallback(log types.Log) (*ICAModuleSourceCallback, error) { + event := new(ICAModuleSourceCallback) + if err := _ICAModule.contract.UnpackLog(event, "SourceCallback", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + // ICAModuleSubmitMsgsResultIterator is returned from FilterSubmitMsgsResult and is used to iterate over the raw logs and unpacked data for SubmitMsgsResult events raised by the ICAModule contract. type ICAModuleSubmitMsgsResultIterator struct { Event *ICAModuleSubmitMsgsResult // Event containing the contract specifics and raw log diff --git a/x/cronos/events/bindings/src/ICA.sol b/x/cronos/events/bindings/src/ICA.sol index b57bddc503..e98d28a905 100644 --- a/x/cronos/events/bindings/src/ICA.sol +++ b/x/cronos/events/bindings/src/ICA.sol @@ -3,6 +3,29 @@ pragma solidity ^0.8.4; interface IICAModule { event SubmitMsgsResult(uint64 seq); + event DestinationCallback( + string module, + string callbackType, + string callbackAddress, + string callbackResult, + string callbackError, + string callbackExecGasLimit, + string callbackCommitGasLimit, + string packetDestPort, + string packetDestChannel, + string packetSequence + ); + event SourceCallback( + string module, + string callbackType, + string callbackAddress, + string callbackResult, + string callbackExecGasLimit, + string callbackCommitGasLimit, + string packetSrcPort, + string packetSrcChannel, + string packetSequence + ); function registerAccount(string calldata connectionID, string calldata version) external payable returns (bool); function queryAccount(string calldata connectionID, address addr) external view returns (string memory); function submitMsgs(string calldata connectionID, bytes calldata data, uint256 timeout) external payable returns (uint64); diff --git a/x/cronos/events/events.go b/x/cronos/events/events.go index d4b0a98be4..1d65a54a9c 100644 --- a/x/cronos/events/events.go +++ b/x/cronos/events/events.go @@ -3,6 +3,7 @@ package events import ( sdk "github.com/cosmos/cosmos-sdk/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + ibccallbackstypes "github.com/cosmos/ibc-go/modules/apps/callbacks/types" ibcfeetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" @@ -35,7 +36,20 @@ var ( transfertypes.AttributeKeyDenom: ReturnStringAsIs, } IcaValueDecoders = ValueDecoders{ - cronoseventstypes.AttributeKeySeq: ConvertUint64, + cronoseventstypes.AttributeKeySeq: ConvertUint64, + ibccallbackstypes.AttributeKeyCallbackType: ReturnStringAsIs, + ibccallbackstypes.AttributeKeyCallbackAddress: ReturnStringAsIs, + ibccallbackstypes.AttributeKeyCallbackResult: ReturnStringAsIs, + ibccallbackstypes.AttributeKeyCallbackError: ReturnStringAsIs, + ibccallbackstypes.AttributeKeyCallbackGasLimit: ReturnStringAsIs, + ibccallbackstypes.AttributeKeyCallbackCommitGasLimit: ReturnStringAsIs, + ibccallbackstypes.AttributeKeyCallbackSourcePortID: ReturnStringAsIs, + ibccallbackstypes.AttributeKeyCallbackSourceChannelID: ReturnStringAsIs, + ibccallbackstypes.AttributeKeyCallbackDestPortID: ReturnStringAsIs, + ibccallbackstypes.AttributeKeyCallbackDestChannelID: ReturnStringAsIs, + ibccallbackstypes.AttributeKeyCallbackSequence: ReturnStringAsIs, + ibccallbackstypes.AttributeValueCallbackSuccess: ReturnStringAsIs, + ibccallbackstypes.AttributeValueCallbackFailure: ReturnStringAsIs, } ) From aa55bcd5a55476bd5fea82081ac26d04c1d74a9f Mon Sep 17 00:00:00 2001 From: mmsqe Date: Tue, 26 Sep 2023 15:02:15 +0800 Subject: [PATCH 06/26] add max_callback_gas in param --- app/app.go | 2 +- client/docs/swagger-ui/swagger.yaml | 9 +++ proto/cronos/cronos.proto | 1 + x/cronos/simulation/genesis.go | 14 ++++- x/cronos/types/cronos.pb.go | 93 ++++++++++++++++++++--------- x/cronos/types/params.go | 15 ++++- 6 files changed, 101 insertions(+), 33 deletions(-) diff --git a/app/app.go b/app/app.go index 5d11554ce0..5a90a379ee 100644 --- a/app/app.go +++ b/app/app.go @@ -661,7 +661,7 @@ func New( icaControllerStack = ibcfee.NewIBCMiddleware(icaControllerStack, app.IBCFeeKeeper) // Since the callbacks middleware itself is an ics4wrapper, it needs to be passed to the ica controller keeper app.ICAControllerKeeper.WithICS4Wrapper(icaControllerStack.(porttypes.Middleware)) - const maxCallbackGas = uint64(1000000) + const maxCallbackGas = uint64(300000) icaControllerStack = ibccallbacks.NewIBCMiddleware(icaControllerStack, app.IBCFeeKeeper, app.CronosKeeper, maxCallbackGas) // Create static IBC router, add transfer route, then set and seal it diff --git a/client/docs/swagger-ui/swagger.yaml b/client/docs/swagger-ui/swagger.yaml index ead7dc06aa..d1a7de27d8 100644 --- a/client/docs/swagger-ui/swagger.yaml +++ b/client/docs/swagger-ui/swagger.yaml @@ -452,6 +452,9 @@ paths: title: the admin address who can update token mapping enable_auto_deployment: type: boolean + max_callback_gas: + type: string + format: uint64 description: >- QueryParamsResponse is the response type for the Query/Params RPC method. @@ -43648,6 +43651,9 @@ definitions: title: the admin address who can update token mapping enable_auto_deployment: type: boolean + max_callback_gas: + type: string + format: uint64 description: Params defines the parameters for the cronos module. cronos.QueryParamsResponse: type: object @@ -43666,6 +43672,9 @@ definitions: title: the admin address who can update token mapping enable_auto_deployment: type: boolean + max_callback_gas: + type: string + format: uint64 description: QueryParamsResponse is the response type for the Query/Params RPC method. cronos.QueryPermissionsResponse: type: object diff --git a/proto/cronos/cronos.proto b/proto/cronos/cronos.proto index ccfbf53d1e..06172ad52b 100644 --- a/proto/cronos/cronos.proto +++ b/proto/cronos/cronos.proto @@ -13,6 +13,7 @@ message Params { // the admin address who can update token mapping string cronos_admin = 3; bool enable_auto_deployment = 4; + uint64 max_callback_gas = 5; } // TokenMappingChangeProposal defines a proposal to change one token mapping. diff --git a/x/cronos/simulation/genesis.go b/x/cronos/simulation/genesis.go index 413f8f63a1..a63467f277 100644 --- a/x/cronos/simulation/genesis.go +++ b/x/cronos/simulation/genesis.go @@ -17,6 +17,7 @@ const ( ibcTimeoutKey = "ibc_timeout" cronosAdminKey = "cronos_admin" enableAutoDeploymentKey = "enable_auto_deployment" + maxCallbackGasKey = "max_callback_gas" ) func GenIbcCroDenom(r *rand.Rand) string { @@ -39,6 +40,11 @@ func GenEnableAutoDeployment(r *rand.Rand) bool { return r.Intn(2) > 0 } +func GenMaxCallbackGas(r *rand.Rand) uint64 { + maxCallbackGas := r.Uint64() + return maxCallbackGas +} + // RandomizedGenState generates a random GenesisState for the cronos module func RandomizedGenState(simState *module.SimulationState) { // cronos params @@ -47,6 +53,7 @@ func RandomizedGenState(simState *module.SimulationState) { ibcTimeout uint64 cronosAdmin string enableAutoDeployment bool + maxCallbackGas uint64 ) simState.AppParams.GetOrGenerate( @@ -69,7 +76,12 @@ func RandomizedGenState(simState *module.SimulationState) { func(r *rand.Rand) { enableAutoDeployment = GenEnableAutoDeployment(r) }, ) - params := types.NewParams(ibcCroDenom, ibcTimeout, cronosAdmin, enableAutoDeployment) + simState.AppParams.GetOrGenerate( + simState.Cdc, maxCallbackGasKey, &ibcTimeout, simState.Rand, + func(r *rand.Rand) { maxCallbackGas = GenIbcTimeout(r) }, + ) + + params := types.NewParams(ibcCroDenom, ibcTimeout, cronosAdmin, enableAutoDeployment, maxCallbackGas) cronosGenesis := &types.GenesisState{ Params: params, ExternalContracts: nil, diff --git a/x/cronos/types/cronos.pb.go b/x/cronos/types/cronos.pb.go index fbafdecb6c..12324030f2 100644 --- a/x/cronos/types/cronos.pb.go +++ b/x/cronos/types/cronos.pb.go @@ -30,6 +30,7 @@ type Params struct { // the admin address who can update token mapping CronosAdmin string `protobuf:"bytes,3,opt,name=cronos_admin,json=cronosAdmin,proto3" json:"cronos_admin,omitempty"` EnableAutoDeployment bool `protobuf:"varint,4,opt,name=enable_auto_deployment,json=enableAutoDeployment,proto3" json:"enable_auto_deployment,omitempty"` + MaxCallbackGas uint64 `protobuf:"varint,5,opt,name=max_callback_gas,json=maxCallbackGas,proto3" json:"max_callback_gas,omitempty"` } func (m *Params) Reset() { *m = Params{} } @@ -92,6 +93,13 @@ func (m *Params) GetEnableAutoDeployment() bool { return false } +func (m *Params) GetMaxCallbackGas() uint64 { + if m != nil { + return m.MaxCallbackGas + } + return 0 +} + // TokenMappingChangeProposal defines a proposal to change one token mapping. type TokenMappingChangeProposal struct { Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` @@ -197,34 +205,36 @@ func init() { func init() { proto.RegisterFile("cronos/cronos.proto", fileDescriptor_8bc54992a93db2d2) } var fileDescriptor_8bc54992a93db2d2 = []byte{ - // 422 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x92, 0xbd, 0x6e, 0xdb, 0x30, - 0x14, 0x85, 0xc5, 0xd4, 0x51, 0x6d, 0x3a, 0x59, 0x58, 0x23, 0x10, 0x3c, 0xc8, 0xaa, 0x26, 0x0f, - 0x4d, 0x04, 0xb4, 0x99, 0x3c, 0x35, 0x3f, 0xe8, 0xd6, 0x22, 0x20, 0x32, 0x75, 0x11, 0x28, 0x8a, - 0x90, 0x89, 0x8a, 0xbc, 0x04, 0x45, 0x15, 0xd5, 0x1b, 0x74, 0xec, 0xd8, 0x31, 0xcf, 0xd2, 0xa9, - 0xa3, 0xc7, 0x4e, 0x45, 0x61, 0xbf, 0x41, 0x9f, 0xa0, 0x90, 0x98, 0xa4, 0xc9, 0x90, 0x49, 0xf7, - 0x3b, 0x07, 0xc2, 0x39, 0x97, 0xb8, 0xf8, 0x05, 0xb7, 0xa0, 0xa1, 0xc9, 0xfc, 0xe7, 0xc4, 0x58, - 0x70, 0x40, 0x42, 0x4f, 0xf3, 0x59, 0x05, 0x15, 0x0c, 0x52, 0xd6, 0x4f, 0xde, 0x4d, 0x37, 0x08, - 0x87, 0x57, 0xcc, 0x32, 0xd5, 0x90, 0x77, 0xf8, 0x50, 0x16, 0x3c, 0xe7, 0x16, 0xf2, 0x52, 0x68, - 0x50, 0x11, 0x4a, 0xd0, 0x72, 0x72, 0x9e, 0xfe, 0xfd, 0xbd, 0x88, 0x3b, 0xa6, 0xea, 0x55, 0xfa, - 0xc8, 0x7e, 0x05, 0x4a, 0x3a, 0xa1, 0x8c, 0xeb, 0x52, 0x3a, 0x95, 0x05, 0xbf, 0xb0, 0x70, 0xd9, - 0xeb, 0x64, 0x81, 0x7b, 0xcc, 0x9d, 0x54, 0x02, 0x5a, 0x17, 0xed, 0x25, 0x68, 0x39, 0xa2, 0x58, - 0x16, 0xfc, 0xda, 0x2b, 0xe4, 0x25, 0x3e, 0xf0, 0x9d, 0x72, 0x56, 0x2a, 0xa9, 0xa3, 0x67, 0x7d, - 0x0e, 0x9d, 0x7a, 0xed, 0xac, 0x97, 0xc8, 0x29, 0x3e, 0x12, 0x9a, 0x15, 0xb5, 0xc8, 0x59, 0xeb, - 0xfa, 0x40, 0x53, 0x43, 0xa7, 0x84, 0x76, 0xd1, 0x28, 0x41, 0xcb, 0x31, 0x9d, 0x79, 0xf7, 0xac, - 0x75, 0x70, 0x79, 0xef, 0xad, 0x46, 0xdf, 0x6f, 0x16, 0x41, 0xfa, 0x03, 0xe1, 0xf9, 0x35, 0x7c, - 0x12, 0xfa, 0x3d, 0x33, 0x46, 0xea, 0xea, 0x62, 0xcd, 0x74, 0x25, 0xae, 0x2c, 0x18, 0x68, 0x58, - 0x4d, 0x66, 0x78, 0xdf, 0x49, 0x57, 0x0b, 0xbf, 0x1e, 0xf5, 0x40, 0x12, 0x3c, 0x2d, 0x45, 0xc3, - 0xad, 0x34, 0x4e, 0x82, 0x1e, 0x4a, 0x4f, 0xe8, 0x43, 0xa9, 0xff, 0xcf, 0x3f, 0x8b, 0xaf, 0xeb, - 0x81, 0xcc, 0xf1, 0x98, 0x83, 0x76, 0x96, 0x71, 0x5f, 0x6d, 0x42, 0xef, 0x99, 0x1c, 0xe1, 0xb0, - 0xe9, 0x54, 0x01, 0x75, 0xb4, 0x3f, 0x38, 0xb7, 0x44, 0x22, 0xfc, 0xbc, 0x14, 0x5c, 0x2a, 0x56, - 0x47, 0x61, 0x82, 0x96, 0x87, 0xf4, 0x0e, 0x57, 0xe3, 0xaf, 0x37, 0x8b, 0x60, 0x58, 0xe2, 0x2d, - 0x3e, 0x78, 0xb8, 0xc3, 0xff, 0x74, 0xf4, 0x54, 0xfa, 0xde, 0xe3, 0xf4, 0xf3, 0x0f, 0x3f, 0xb7, - 0x31, 0xda, 0x6c, 0x63, 0xf4, 0x67, 0x1b, 0xa3, 0x6f, 0xbb, 0x38, 0xd8, 0xec, 0xe2, 0xe0, 0xd7, - 0x2e, 0x0e, 0x3e, 0x9e, 0x56, 0xd2, 0xad, 0xdb, 0xe2, 0x84, 0x83, 0xca, 0xb8, 0xed, 0x8c, 0x83, - 0x63, 0xb0, 0xd5, 0x31, 0x5f, 0x33, 0xa9, 0x6f, 0x6f, 0x27, 0xfb, 0xfc, 0x3a, 0xfb, 0x72, 0x37, - 0xbb, 0xce, 0x88, 0xa6, 0x08, 0x87, 0x83, 0x79, 0xf3, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x3d, 0x74, - 0x94, 0x69, 0x65, 0x02, 0x00, 0x00, + // 451 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x92, 0xb1, 0x6f, 0xd3, 0x40, + 0x14, 0xc6, 0x7d, 0x25, 0x35, 0xc9, 0xa5, 0x45, 0xe8, 0x88, 0x2a, 0x2b, 0x83, 0x63, 0x3c, 0x79, + 0xa0, 0xb5, 0x04, 0x9d, 0x32, 0xd1, 0xa6, 0x82, 0x09, 0x54, 0x59, 0x9d, 0x58, 0xac, 0xf3, 0xe5, + 0xe4, 0x9c, 0xea, 0xbb, 0x77, 0x3a, 0x5f, 0x50, 0xfc, 0x1f, 0x30, 0x32, 0x32, 0xf6, 0x6f, 0x61, + 0x62, 0xec, 0xc8, 0x84, 0x50, 0xf2, 0x1f, 0x30, 0x32, 0x21, 0xfb, 0xd2, 0xd2, 0x0c, 0x9d, 0x7c, + 0xdf, 0xef, 0x93, 0xf5, 0xbd, 0xef, 0xe9, 0xe1, 0x17, 0xcc, 0x80, 0x82, 0x3a, 0x75, 0x9f, 0x13, + 0x6d, 0xc0, 0x02, 0xf1, 0x9d, 0x1a, 0x8f, 0x4a, 0x28, 0xa1, 0x43, 0x69, 0xfb, 0x72, 0x6e, 0xfc, + 0x17, 0x61, 0xff, 0x92, 0x1a, 0x2a, 0x6b, 0xf2, 0x0e, 0x1f, 0x8a, 0x82, 0xe5, 0xcc, 0x40, 0x3e, + 0xe7, 0x0a, 0x64, 0x80, 0x22, 0x94, 0x0c, 0xce, 0xe3, 0x3f, 0xbf, 0x26, 0x61, 0x43, 0x65, 0x35, + 0x8d, 0x77, 0xec, 0x57, 0x20, 0x85, 0xe5, 0x52, 0xdb, 0x26, 0xce, 0x86, 0xa2, 0x60, 0x33, 0x03, + 0x17, 0x2d, 0x27, 0x13, 0xdc, 0xca, 0xdc, 0x0a, 0xc9, 0x61, 0x69, 0x83, 0xbd, 0x08, 0x25, 0xbd, + 0x0c, 0x8b, 0x82, 0x5d, 0x39, 0x42, 0x5e, 0xe2, 0x03, 0x37, 0x53, 0x4e, 0xe7, 0x52, 0xa8, 0xe0, + 0x49, 0x9b, 0x93, 0x0d, 0x1d, 0x3b, 0x6b, 0x11, 0x39, 0xc5, 0x47, 0x5c, 0xd1, 0xa2, 0xe2, 0x39, + 0x5d, 0xda, 0x36, 0x50, 0x57, 0xd0, 0x48, 0xae, 0x6c, 0xd0, 0x8b, 0x50, 0xd2, 0xcf, 0x46, 0xce, + 0x3d, 0x5b, 0x5a, 0xb8, 0xb8, 0xf7, 0x48, 0x82, 0x9f, 0x4b, 0xba, 0xca, 0x19, 0xad, 0xaa, 0x82, + 0xb2, 0xeb, 0xbc, 0xa4, 0x75, 0xb0, 0xdf, 0xc5, 0x3f, 0x93, 0x74, 0x35, 0xdb, 0xe2, 0xf7, 0xb4, + 0x9e, 0xf6, 0xbe, 0xdd, 0x4c, 0xbc, 0xf8, 0x3b, 0xc2, 0xe3, 0x2b, 0xb8, 0xe6, 0xea, 0x03, 0xd5, + 0x5a, 0xa8, 0x72, 0xb6, 0xa0, 0xaa, 0xe4, 0x97, 0x06, 0x34, 0xd4, 0xb4, 0x22, 0x23, 0xbc, 0x6f, + 0x85, 0xad, 0xb8, 0x5b, 0x44, 0xe6, 0x04, 0x89, 0xf0, 0x70, 0xce, 0x6b, 0x66, 0x84, 0xb6, 0x02, + 0x54, 0x57, 0x6f, 0x90, 0x3d, 0x44, 0xed, 0x7f, 0x6e, 0x81, 0xae, 0x98, 0x13, 0x64, 0x8c, 0xfb, + 0x0c, 0x94, 0x35, 0x94, 0xb9, 0x12, 0x83, 0xec, 0x5e, 0x93, 0x23, 0xec, 0xd7, 0x8d, 0x2c, 0xa0, + 0xea, 0xc6, 0x1d, 0x64, 0x5b, 0x45, 0x02, 0xfc, 0x74, 0xce, 0x99, 0x90, 0xb4, 0x0a, 0xfc, 0x08, + 0x25, 0x87, 0xd9, 0x9d, 0x9c, 0xf6, 0xbf, 0xdc, 0x4c, 0xbc, 0xae, 0xc4, 0x5b, 0x7c, 0xf0, 0xb0, + 0xc3, 0xff, 0x74, 0xf4, 0x58, 0xfa, 0xde, 0x6e, 0xfa, 0xf9, 0xc7, 0x1f, 0xeb, 0x10, 0xdd, 0xae, + 0x43, 0xf4, 0x7b, 0x1d, 0xa2, 0xaf, 0x9b, 0xd0, 0xbb, 0xdd, 0x84, 0xde, 0xcf, 0x4d, 0xe8, 0x7d, + 0x3a, 0x2d, 0x85, 0x5d, 0x2c, 0x8b, 0x13, 0x06, 0x32, 0x65, 0xa6, 0xd1, 0x16, 0x8e, 0xc1, 0x94, + 0xc7, 0x6c, 0x41, 0x85, 0xda, 0x5e, 0x59, 0xfa, 0xf9, 0x75, 0xba, 0xba, 0x7b, 0xdb, 0x46, 0xf3, + 0xba, 0xf0, 0xbb, 0xd3, 0x7a, 0xf3, 0x2f, 0x00, 0x00, 0xff, 0xff, 0xad, 0x72, 0x13, 0x5e, 0x8f, + 0x02, 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -247,6 +257,11 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.MaxCallbackGas != 0 { + i = encodeVarintCronos(dAtA, i, uint64(m.MaxCallbackGas)) + i-- + dAtA[i] = 0x28 + } if m.EnableAutoDeployment { i-- if m.EnableAutoDeployment { @@ -410,6 +425,9 @@ func (m *Params) Size() (n int) { if m.EnableAutoDeployment { n += 2 } + if m.MaxCallbackGas != 0 { + n += 1 + sovCronos(uint64(m.MaxCallbackGas)) + } return n } @@ -600,6 +618,25 @@ func (m *Params) Unmarshal(dAtA []byte) error { } } m.EnableAutoDeployment = bool(v != 0) + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxCallbackGas", wireType) + } + m.MaxCallbackGas = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCronos + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MaxCallbackGas |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipCronos(dAtA[iNdEx:]) diff --git a/x/cronos/types/params.go b/x/cronos/types/params.go index c99ff0dbc1..fe88d43bc6 100644 --- a/x/cronos/types/params.go +++ b/x/cronos/types/params.go @@ -18,11 +18,14 @@ var ( KeyCronosAdmin = []byte("CronosAdmin") // KeyEnableAutoDeployment is store's key for the EnableAutoDeployment KeyEnableAutoDeployment = []byte("EnableAutoDeployment") + // KeyMaxCallbackGas is store's key for the MaxCallbackGas + KeyMaxCallbackGas = []byte("MaxCallbackGas") ) const ( - IbcCroDenomDefaultValue = "ibc/6B5A664BF0AF4F71B2F0BAA33141E2F1321242FBD5D19762F541EC971ACB0865" - IbcTimeoutDefaultValue = uint64(86400000000000) // 1 day + IbcCroDenomDefaultValue = "ibc/6B5A664BF0AF4F71B2F0BAA33141E2F1321242FBD5D19762F541EC971ACB0865" + IbcTimeoutDefaultValue = uint64(86400000000000) // 1 day + MaxCallbackGasDefaultValue = uint64(300000) ) // ParamKeyTable returns the parameter key table. @@ -31,12 +34,13 @@ func ParamKeyTable() paramtypes.KeyTable { } // NewParams creates a new parameter configuration for the cronos module -func NewParams(ibcCroDenom string, ibcTimeout uint64, cronosAdmin string, enableAutoDeployment bool) Params { +func NewParams(ibcCroDenom string, ibcTimeout uint64, cronosAdmin string, enableAutoDeployment bool, maxCallbackGas uint64) Params { return Params{ IbcCroDenom: ibcCroDenom, IbcTimeout: ibcTimeout, CronosAdmin: cronosAdmin, EnableAutoDeployment: enableAutoDeployment, + MaxCallbackGas: maxCallbackGas, } } @@ -47,6 +51,7 @@ func DefaultParams() Params { IbcTimeout: IbcTimeoutDefaultValue, CronosAdmin: "", EnableAutoDeployment: false, + MaxCallbackGas: MaxCallbackGasDefaultValue, } } @@ -63,6 +68,9 @@ func (p Params) Validate() error { return err } } + if err := validateIsUint64(p.MaxCallbackGas); err != nil { + return err + } return nil } @@ -79,6 +87,7 @@ func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { paramtypes.NewParamSetPair(KeyIbcTimeout, &p.IbcTimeout, validateIsUint64), paramtypes.NewParamSetPair(KeyCronosAdmin, &p.CronosAdmin, validateIsAddress), paramtypes.NewParamSetPair(KeyEnableAutoDeployment, &p.EnableAutoDeployment, validateIsBool), + paramtypes.NewParamSetPair(KeyMaxCallbackGas, &p.MaxCallbackGas, validateIsUint64), } } From 5d86aad2c38c876cc5d963e5d2bf3ea7f5cb775e Mon Sep 17 00:00:00 2001 From: mmsqe Date: Tue, 26 Sep 2023 15:23:49 +0800 Subject: [PATCH 07/26] Apply suggestions from code review --- x/cronos/keeper/keeper.go | 18 +----------------- x/cronos/keeper/precompiles/ica.go | 2 +- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/x/cronos/keeper/keeper.go b/x/cronos/keeper/keeper.go index e26f933ca1..ff00830563 100644 --- a/x/cronos/keeper/keeper.go +++ b/x/cronos/keeper/keeper.go @@ -282,10 +282,6 @@ func (k Keeper) RegisterOrUpdateTokenMapping(ctx sdk.Context, msg *types.MsgUpda return nil } -// IBCOnAcknowledgementPacketCallback returns nil if the gas meter has greater than -// or equal to 500_000 gas remaining. -// This function oog panics if the gas remaining is less than 500_000. -// This function errors if the authAddress is MockCallbackUnauthorizedAddress. func (k Keeper) IBCOnAcknowledgementPacketCallback( ctx sdk.Context, packet channeltypes.Packet, @@ -304,10 +300,6 @@ func (k Keeper) IBCOnAcknowledgementPacketCallback( return err } -// IBCOnTimeoutPacketCallback returns nil if the gas meter has greater than -// or equal to 500_000 gas remaining. -// This function oog panics if the gas remaining is less than 500_000. -// This function errors if the authAddress is MockCallbackUnauthorizedAddress. func (k Keeper) IBCOnTimeoutPacketCallback( ctx sdk.Context, packet channeltypes.Packet, @@ -317,7 +309,7 @@ func (k Keeper) IBCOnTimeoutPacketCallback( ) error { relayerAddr := common.BytesToAddress(relayer.Bytes()) precompileAddr := common.HexToAddress(contractAddress) - data, err := cronosprecompiles.GetOnTimeoutPacketCallbackk(packet.Sequence, packetSenderAddress) + data, err := cronosprecompiles.GetOnTimeoutPacketCallback(packet.Sequence, packetSenderAddress) if err != nil { return err } @@ -325,10 +317,6 @@ func (k Keeper) IBCOnTimeoutPacketCallback( return err } -// IBCReceivePacketCallback returns nil if the gas meter has greater than -// or equal to 500_000 gas remaining. -// This function oog panics if the gas remaining is less than 500_000. -// This function errors if the authAddress is MockCallbackUnauthorizedAddress. func (k Keeper) IBCReceivePacketCallback( ctx sdk.Context, packet ibcexported.PacketI, @@ -338,10 +326,6 @@ func (k Keeper) IBCReceivePacketCallback( return nil } -// IBCPacketSendCallback returns nil if the gas meter has greater than -// or equal to 500_000 gas remaining. -// This function oog panics if the gas remaining is less than 500_000. -// This function errors if the authAddress is MockCallbackUnauthorizedAddress. func (k Keeper) IBCSendPacketCallback( ctx sdk.Context, sourcePort string, diff --git a/x/cronos/keeper/precompiles/ica.go b/x/cronos/keeper/precompiles/ica.go index 4cab5b17aa..31c8912c6e 100644 --- a/x/cronos/keeper/precompiles/ica.go +++ b/x/cronos/keeper/precompiles/ica.go @@ -37,7 +37,7 @@ func GetOnAcknowledgementPacketCallback(args ...interface{}) ([]byte, error) { return icaABI.Pack("onAcknowledgementPacketCallback", args...) } -func GetOnTimeoutPacketCallbackk(args ...interface{}) ([]byte, error) { +func GetOnTimeoutPacketCallback(args ...interface{}) ([]byte, error) { return icaABI.Pack("onTimeoutPacketCallback", args...) } From 85bb2d8ea986c206f3534ff3e45931127b352308 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Tue, 26 Sep 2023 20:45:38 +0800 Subject: [PATCH 08/26] use default maxCallbackGas --- app/app.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/app.go b/app/app.go index 5a90a379ee..6a3387a76a 100644 --- a/app/app.go +++ b/app/app.go @@ -661,8 +661,7 @@ func New( icaControllerStack = ibcfee.NewIBCMiddleware(icaControllerStack, app.IBCFeeKeeper) // Since the callbacks middleware itself is an ics4wrapper, it needs to be passed to the ica controller keeper app.ICAControllerKeeper.WithICS4Wrapper(icaControllerStack.(porttypes.Middleware)) - const maxCallbackGas = uint64(300000) - icaControllerStack = ibccallbacks.NewIBCMiddleware(icaControllerStack, app.IBCFeeKeeper, app.CronosKeeper, maxCallbackGas) + icaControllerStack = ibccallbacks.NewIBCMiddleware(icaControllerStack, app.IBCFeeKeeper, app.CronosKeeper, cronostypes.MaxCallbackGasDefaultValue) // Create static IBC router, add transfer route, then set and seal it ibcRouter := porttypes.NewRouter() From 062ca0349084760dff73a1b73a93312f9d2618bc Mon Sep 17 00:00:00 2001 From: mmsqe Date: Tue, 26 Sep 2023 20:46:22 +0800 Subject: [PATCH 09/26] fix test --- integration_tests/test_gov_update_params.py | 24 +++++++++------------ 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/integration_tests/test_gov_update_params.py b/integration_tests/test_gov_update_params.py index 14f31d12af..b6efb5f8b3 100644 --- a/integration_tests/test_gov_update_params.py +++ b/integration_tests/test_gov_update_params.py @@ -9,18 +9,20 @@ def test_gov_update_params(cronos, tmp_path): proposal = tmp_path / "proposal.json" # governance module account as signer signer = "crc10d07y265gmmuvt4z0w9aw880jnsr700jdufnyd" + params = { + "cronos_admin": "crc12luku6uxehhak02py4rcz65zu0swh7wjsrw0pp", + "enable_auto_deployment": False, + "ibc_cro_denom": "ibc/6411AE2ADA1E73DB59DB151" + "A8988F9B7D5E7E233D8414DB6817F8F1A01600000", + "ibc_timeout": "96400000000000", + "max_callback_gas": "400000", + } proposal_src = { "messages": [ { "@type": "/cronos.MsgUpdateParams", "authority": signer, - "params": { - "cronos_admin": "crc12luku6uxehhak02py4rcz65zu0swh7wjsrw0pp", - "enable_auto_deployment": False, - "ibc_cro_denom": "ibc/6411AE2ADA1E73DB59DB151" - "A8988F9B7D5E7E233D8414DB6817F8F1A01600000", - "ibc_timeout": "96400000000000", - }, + "params": params, } ], "deposit": "1basetcro", @@ -35,10 +37,4 @@ def test_gov_update_params(cronos, tmp_path): print("check params have been updated now") rsp = cli.query_params() print("params", rsp) - assert rsp == { - "cronos_admin": "crc12luku6uxehhak02py4rcz65zu0swh7wjsrw0pp", - "enable_auto_deployment": False, - "ibc_cro_denom": "ibc/6411AE2ADA1E73DB59DB151" - "A8988F9B7D5E7E233D8414DB6817F8F1A01600000", - "ibc_timeout": "96400000000000", - } + assert rsp == params From 233f26795bd9089478fa882615d6e07918ff5a62 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Tue, 26 Sep 2023 20:46:28 +0800 Subject: [PATCH 10/26] revert events --- .../precompile/ica/i_ica_module.abigen.go | 287 +----------------- x/cronos/events/bindings/src/ICA.sol | 23 -- x/cronos/events/events.go | 16 +- 3 files changed, 2 insertions(+), 324 deletions(-) diff --git a/x/cronos/events/bindings/cosmos/precompile/ica/i_ica_module.abigen.go b/x/cronos/events/bindings/cosmos/precompile/ica/i_ica_module.abigen.go index 277e2c80fe..dfc2242bb3 100644 --- a/x/cronos/events/bindings/cosmos/precompile/ica/i_ica_module.abigen.go +++ b/x/cronos/events/bindings/cosmos/precompile/ica/i_ica_module.abigen.go @@ -30,7 +30,7 @@ var ( // ICAModuleMetaData contains all meta data concerning the ICAModule contract. var ICAModuleMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"module\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"callbackType\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"callbackAddress\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"callbackResult\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"callbackError\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"callbackExecGasLimit\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"callbackCommitGasLimit\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"packetDestPort\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"packetDestChannel\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"packetSequence\",\"type\":\"string\"}],\"name\":\"DestinationCallback\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"module\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"callbackType\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"callbackAddress\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"callbackResult\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"callbackExecGasLimit\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"callbackCommitGasLimit\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"packetSrcPort\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"packetSrcChannel\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"packetSequence\",\"type\":\"string\"}],\"name\":\"SourceCallback\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"}],\"name\":\"SubmitMsgsResult\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"},{\"internalType\":\"string\",\"name\":\"packetSenderAddress\",\"type\":\"string\"}],\"name\":\"onAcknowledgementPacketCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"},{\"internalType\":\"string\",\"name\":\"packetSenderAddress\",\"type\":\"string\"}],\"name\":\"onTimeoutPacketCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"queryAccount\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"}],\"name\":\"registerAccount\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"timeout\",\"type\":\"uint256\"}],\"name\":\"submitMsgs\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"}],\"name\":\"SubmitMsgsResult\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"},{\"internalType\":\"string\",\"name\":\"packetSenderAddress\",\"type\":\"string\"}],\"name\":\"onAcknowledgementPacketCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"},{\"internalType\":\"string\",\"name\":\"packetSenderAddress\",\"type\":\"string\"}],\"name\":\"onTimeoutPacketCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"queryAccount\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"}],\"name\":\"registerAccount\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"timeout\",\"type\":\"uint256\"}],\"name\":\"submitMsgs\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", } // ICAModuleABI is the input ABI used to generate the binding from. @@ -294,291 +294,6 @@ func (_ICAModule *ICAModuleTransactorSession) SubmitMsgs(connectionID string, da return _ICAModule.Contract.SubmitMsgs(&_ICAModule.TransactOpts, connectionID, data, timeout) } -// ICAModuleDestinationCallbackIterator is returned from FilterDestinationCallback and is used to iterate over the raw logs and unpacked data for DestinationCallback events raised by the ICAModule contract. -type ICAModuleDestinationCallbackIterator struct { - Event *ICAModuleDestinationCallback // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ICAModuleDestinationCallbackIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ICAModuleDestinationCallback) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ICAModuleDestinationCallback) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ICAModuleDestinationCallbackIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ICAModuleDestinationCallbackIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ICAModuleDestinationCallback represents a DestinationCallback event raised by the ICAModule contract. -type ICAModuleDestinationCallback struct { - Module string - CallbackType string - CallbackAddress string - CallbackResult string - CallbackError string - CallbackExecGasLimit string - CallbackCommitGasLimit string - PacketDestPort string - PacketDestChannel string - PacketSequence string - Raw types.Log // Blockchain specific contextual infos -} - -// FilterDestinationCallback is a free log retrieval operation binding the contract event 0x2ae174bea5540138f8433743ac6f4338f304522f95b07f0fbfaeb260143a71ba. -// -// Solidity: event DestinationCallback(string module, string callbackType, string callbackAddress, string callbackResult, string callbackError, string callbackExecGasLimit, string callbackCommitGasLimit, string packetDestPort, string packetDestChannel, string packetSequence) -func (_ICAModule *ICAModuleFilterer) FilterDestinationCallback(opts *bind.FilterOpts) (*ICAModuleDestinationCallbackIterator, error) { - - logs, sub, err := _ICAModule.contract.FilterLogs(opts, "DestinationCallback") - if err != nil { - return nil, err - } - return &ICAModuleDestinationCallbackIterator{contract: _ICAModule.contract, event: "DestinationCallback", logs: logs, sub: sub}, nil -} - -// WatchDestinationCallback is a free log subscription operation binding the contract event 0x2ae174bea5540138f8433743ac6f4338f304522f95b07f0fbfaeb260143a71ba. -// -// Solidity: event DestinationCallback(string module, string callbackType, string callbackAddress, string callbackResult, string callbackError, string callbackExecGasLimit, string callbackCommitGasLimit, string packetDestPort, string packetDestChannel, string packetSequence) -func (_ICAModule *ICAModuleFilterer) WatchDestinationCallback(opts *bind.WatchOpts, sink chan<- *ICAModuleDestinationCallback) (event.Subscription, error) { - - logs, sub, err := _ICAModule.contract.WatchLogs(opts, "DestinationCallback") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ICAModuleDestinationCallback) - if err := _ICAModule.contract.UnpackLog(event, "DestinationCallback", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseDestinationCallback is a log parse operation binding the contract event 0x2ae174bea5540138f8433743ac6f4338f304522f95b07f0fbfaeb260143a71ba. -// -// Solidity: event DestinationCallback(string module, string callbackType, string callbackAddress, string callbackResult, string callbackError, string callbackExecGasLimit, string callbackCommitGasLimit, string packetDestPort, string packetDestChannel, string packetSequence) -func (_ICAModule *ICAModuleFilterer) ParseDestinationCallback(log types.Log) (*ICAModuleDestinationCallback, error) { - event := new(ICAModuleDestinationCallback) - if err := _ICAModule.contract.UnpackLog(event, "DestinationCallback", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// ICAModuleSourceCallbackIterator is returned from FilterSourceCallback and is used to iterate over the raw logs and unpacked data for SourceCallback events raised by the ICAModule contract. -type ICAModuleSourceCallbackIterator struct { - Event *ICAModuleSourceCallback // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ICAModuleSourceCallbackIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ICAModuleSourceCallback) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ICAModuleSourceCallback) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ICAModuleSourceCallbackIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ICAModuleSourceCallbackIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ICAModuleSourceCallback represents a SourceCallback event raised by the ICAModule contract. -type ICAModuleSourceCallback struct { - Module string - CallbackType string - CallbackAddress string - CallbackResult string - CallbackExecGasLimit string - CallbackCommitGasLimit string - PacketSrcPort string - PacketSrcChannel string - PacketSequence string - Raw types.Log // Blockchain specific contextual infos -} - -// FilterSourceCallback is a free log retrieval operation binding the contract event 0xb76e53cebd913fb7a3a645584b8ee6889866564177fc6a11ada9f86b66046ac3. -// -// Solidity: event SourceCallback(string module, string callbackType, string callbackAddress, string callbackResult, string callbackExecGasLimit, string callbackCommitGasLimit, string packetSrcPort, string packetSrcChannel, string packetSequence) -func (_ICAModule *ICAModuleFilterer) FilterSourceCallback(opts *bind.FilterOpts) (*ICAModuleSourceCallbackIterator, error) { - - logs, sub, err := _ICAModule.contract.FilterLogs(opts, "SourceCallback") - if err != nil { - return nil, err - } - return &ICAModuleSourceCallbackIterator{contract: _ICAModule.contract, event: "SourceCallback", logs: logs, sub: sub}, nil -} - -// WatchSourceCallback is a free log subscription operation binding the contract event 0xb76e53cebd913fb7a3a645584b8ee6889866564177fc6a11ada9f86b66046ac3. -// -// Solidity: event SourceCallback(string module, string callbackType, string callbackAddress, string callbackResult, string callbackExecGasLimit, string callbackCommitGasLimit, string packetSrcPort, string packetSrcChannel, string packetSequence) -func (_ICAModule *ICAModuleFilterer) WatchSourceCallback(opts *bind.WatchOpts, sink chan<- *ICAModuleSourceCallback) (event.Subscription, error) { - - logs, sub, err := _ICAModule.contract.WatchLogs(opts, "SourceCallback") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ICAModuleSourceCallback) - if err := _ICAModule.contract.UnpackLog(event, "SourceCallback", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseSourceCallback is a log parse operation binding the contract event 0xb76e53cebd913fb7a3a645584b8ee6889866564177fc6a11ada9f86b66046ac3. -// -// Solidity: event SourceCallback(string module, string callbackType, string callbackAddress, string callbackResult, string callbackExecGasLimit, string callbackCommitGasLimit, string packetSrcPort, string packetSrcChannel, string packetSequence) -func (_ICAModule *ICAModuleFilterer) ParseSourceCallback(log types.Log) (*ICAModuleSourceCallback, error) { - event := new(ICAModuleSourceCallback) - if err := _ICAModule.contract.UnpackLog(event, "SourceCallback", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - // ICAModuleSubmitMsgsResultIterator is returned from FilterSubmitMsgsResult and is used to iterate over the raw logs and unpacked data for SubmitMsgsResult events raised by the ICAModule contract. type ICAModuleSubmitMsgsResultIterator struct { Event *ICAModuleSubmitMsgsResult // Event containing the contract specifics and raw log diff --git a/x/cronos/events/bindings/src/ICA.sol b/x/cronos/events/bindings/src/ICA.sol index e98d28a905..b57bddc503 100644 --- a/x/cronos/events/bindings/src/ICA.sol +++ b/x/cronos/events/bindings/src/ICA.sol @@ -3,29 +3,6 @@ pragma solidity ^0.8.4; interface IICAModule { event SubmitMsgsResult(uint64 seq); - event DestinationCallback( - string module, - string callbackType, - string callbackAddress, - string callbackResult, - string callbackError, - string callbackExecGasLimit, - string callbackCommitGasLimit, - string packetDestPort, - string packetDestChannel, - string packetSequence - ); - event SourceCallback( - string module, - string callbackType, - string callbackAddress, - string callbackResult, - string callbackExecGasLimit, - string callbackCommitGasLimit, - string packetSrcPort, - string packetSrcChannel, - string packetSequence - ); function registerAccount(string calldata connectionID, string calldata version) external payable returns (bool); function queryAccount(string calldata connectionID, address addr) external view returns (string memory); function submitMsgs(string calldata connectionID, bytes calldata data, uint256 timeout) external payable returns (uint64); diff --git a/x/cronos/events/events.go b/x/cronos/events/events.go index 1d65a54a9c..d4b0a98be4 100644 --- a/x/cronos/events/events.go +++ b/x/cronos/events/events.go @@ -3,7 +3,6 @@ package events import ( sdk "github.com/cosmos/cosmos-sdk/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - ibccallbackstypes "github.com/cosmos/ibc-go/modules/apps/callbacks/types" ibcfeetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" @@ -36,20 +35,7 @@ var ( transfertypes.AttributeKeyDenom: ReturnStringAsIs, } IcaValueDecoders = ValueDecoders{ - cronoseventstypes.AttributeKeySeq: ConvertUint64, - ibccallbackstypes.AttributeKeyCallbackType: ReturnStringAsIs, - ibccallbackstypes.AttributeKeyCallbackAddress: ReturnStringAsIs, - ibccallbackstypes.AttributeKeyCallbackResult: ReturnStringAsIs, - ibccallbackstypes.AttributeKeyCallbackError: ReturnStringAsIs, - ibccallbackstypes.AttributeKeyCallbackGasLimit: ReturnStringAsIs, - ibccallbackstypes.AttributeKeyCallbackCommitGasLimit: ReturnStringAsIs, - ibccallbackstypes.AttributeKeyCallbackSourcePortID: ReturnStringAsIs, - ibccallbackstypes.AttributeKeyCallbackSourceChannelID: ReturnStringAsIs, - ibccallbackstypes.AttributeKeyCallbackDestPortID: ReturnStringAsIs, - ibccallbackstypes.AttributeKeyCallbackDestChannelID: ReturnStringAsIs, - ibccallbackstypes.AttributeKeyCallbackSequence: ReturnStringAsIs, - ibccallbackstypes.AttributeValueCallbackSuccess: ReturnStringAsIs, - ibccallbackstypes.AttributeValueCallbackFailure: ReturnStringAsIs, + cronoseventstypes.AttributeKeySeq: ConvertUint64, } ) From b9fea2fc957408fcbd5d6b7d4a279cb237829294 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Tue, 26 Sep 2023 20:46:32 +0800 Subject: [PATCH 11/26] fix signature --- .../contracts/contracts/TestICA.sol | 12 +++++ .../precompile/ica/i_ica_module.abigen.go | 44 +++++++++---------- x/cronos/events/bindings/src/ICA.sol | 4 +- 3 files changed, 36 insertions(+), 24 deletions(-) diff --git a/integration_tests/contracts/contracts/TestICA.sol b/integration_tests/contracts/contracts/TestICA.sol index c4c80ab023..3af66d1804 100644 --- a/integration_tests/contracts/contracts/TestICA.sol +++ b/integration_tests/contracts/contracts/TestICA.sol @@ -8,6 +8,8 @@ contract TestICA { IICAModule ica = IICAModule(icaContract); address account; uint64 lastAckSeq; + event OnAcknowledgementPacketResult(uint64 seq, bytes acknowledgement); + event OnTimeoutPacketResult(uint64 seq); function encodeRegister(string memory connectionID, string memory version) internal view returns (bytes memory) { return abi.encodeWithSignature( @@ -92,4 +94,14 @@ contract TestICA { function getLastAckSeq() public view returns (uint256) { return lastAckSeq; } + + function onAcknowledgementPacketCallback(uint64 seq, address packetSenderAddress, bytes calldata acknowledgement) public { + require(packetSenderAddress == address(this), "different sender"); + emit OnAcknowledgementPacketResult(seq, acknowledgement); + } + + function onTimeoutPacketCallback(uint64 seq, address packetSenderAddress) public { + require(packetSenderAddress == address(this), "different sender"); + emit OnTimeoutPacketResult(seq); + } } \ No newline at end of file diff --git a/x/cronos/events/bindings/cosmos/precompile/ica/i_ica_module.abigen.go b/x/cronos/events/bindings/cosmos/precompile/ica/i_ica_module.abigen.go index dfc2242bb3..a98d055f6b 100644 --- a/x/cronos/events/bindings/cosmos/precompile/ica/i_ica_module.abigen.go +++ b/x/cronos/events/bindings/cosmos/precompile/ica/i_ica_module.abigen.go @@ -30,7 +30,7 @@ var ( // ICAModuleMetaData contains all meta data concerning the ICAModule contract. var ICAModuleMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"}],\"name\":\"SubmitMsgsResult\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"},{\"internalType\":\"string\",\"name\":\"packetSenderAddress\",\"type\":\"string\"}],\"name\":\"onAcknowledgementPacketCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"},{\"internalType\":\"string\",\"name\":\"packetSenderAddress\",\"type\":\"string\"}],\"name\":\"onTimeoutPacketCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"queryAccount\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"}],\"name\":\"registerAccount\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"timeout\",\"type\":\"uint256\"}],\"name\":\"submitMsgs\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"}],\"name\":\"SubmitMsgsResult\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"packetSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"acknowledgement\",\"type\":\"bytes\"}],\"name\":\"onAcknowledgementPacketCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"packetSenderAddress\",\"type\":\"address\"}],\"name\":\"onTimeoutPacketCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"queryAccount\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"}],\"name\":\"registerAccount\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"timeout\",\"type\":\"uint256\"}],\"name\":\"submitMsgs\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", } // ICAModuleABI is the input ABI used to generate the binding from. @@ -210,45 +210,45 @@ func (_ICAModule *ICAModuleCallerSession) QueryAccount(connectionID string, addr return _ICAModule.Contract.QueryAccount(&_ICAModule.CallOpts, connectionID, addr) } -// OnAcknowledgementPacketCallback is a paid mutator transaction binding the contract method 0x7f15df2f. +// OnAcknowledgementPacketCallback is a paid mutator transaction binding the contract method 0xee3ce76a. // -// Solidity: function onAcknowledgementPacketCallback(uint64 seq, string packetSenderAddress) payable returns(bool) -func (_ICAModule *ICAModuleTransactor) OnAcknowledgementPacketCallback(opts *bind.TransactOpts, seq uint64, packetSenderAddress string) (*types.Transaction, error) { - return _ICAModule.contract.Transact(opts, "onAcknowledgementPacketCallback", seq, packetSenderAddress) +// Solidity: function onAcknowledgementPacketCallback(uint64 seq, address packetSenderAddress, bytes acknowledgement) payable returns(bool) +func (_ICAModule *ICAModuleTransactor) OnAcknowledgementPacketCallback(opts *bind.TransactOpts, seq uint64, packetSenderAddress common.Address, acknowledgement []byte) (*types.Transaction, error) { + return _ICAModule.contract.Transact(opts, "onAcknowledgementPacketCallback", seq, packetSenderAddress, acknowledgement) } -// OnAcknowledgementPacketCallback is a paid mutator transaction binding the contract method 0x7f15df2f. +// OnAcknowledgementPacketCallback is a paid mutator transaction binding the contract method 0xee3ce76a. // -// Solidity: function onAcknowledgementPacketCallback(uint64 seq, string packetSenderAddress) payable returns(bool) -func (_ICAModule *ICAModuleSession) OnAcknowledgementPacketCallback(seq uint64, packetSenderAddress string) (*types.Transaction, error) { - return _ICAModule.Contract.OnAcknowledgementPacketCallback(&_ICAModule.TransactOpts, seq, packetSenderAddress) +// Solidity: function onAcknowledgementPacketCallback(uint64 seq, address packetSenderAddress, bytes acknowledgement) payable returns(bool) +func (_ICAModule *ICAModuleSession) OnAcknowledgementPacketCallback(seq uint64, packetSenderAddress common.Address, acknowledgement []byte) (*types.Transaction, error) { + return _ICAModule.Contract.OnAcknowledgementPacketCallback(&_ICAModule.TransactOpts, seq, packetSenderAddress, acknowledgement) } -// OnAcknowledgementPacketCallback is a paid mutator transaction binding the contract method 0x7f15df2f. +// OnAcknowledgementPacketCallback is a paid mutator transaction binding the contract method 0xee3ce76a. // -// Solidity: function onAcknowledgementPacketCallback(uint64 seq, string packetSenderAddress) payable returns(bool) -func (_ICAModule *ICAModuleTransactorSession) OnAcknowledgementPacketCallback(seq uint64, packetSenderAddress string) (*types.Transaction, error) { - return _ICAModule.Contract.OnAcknowledgementPacketCallback(&_ICAModule.TransactOpts, seq, packetSenderAddress) +// Solidity: function onAcknowledgementPacketCallback(uint64 seq, address packetSenderAddress, bytes acknowledgement) payable returns(bool) +func (_ICAModule *ICAModuleTransactorSession) OnAcknowledgementPacketCallback(seq uint64, packetSenderAddress common.Address, acknowledgement []byte) (*types.Transaction, error) { + return _ICAModule.Contract.OnAcknowledgementPacketCallback(&_ICAModule.TransactOpts, seq, packetSenderAddress, acknowledgement) } -// OnTimeoutPacketCallback is a paid mutator transaction binding the contract method 0xd72be239. +// OnTimeoutPacketCallback is a paid mutator transaction binding the contract method 0x14f4f3f0. // -// Solidity: function onTimeoutPacketCallback(uint64 seq, string packetSenderAddress) payable returns(bool) -func (_ICAModule *ICAModuleTransactor) OnTimeoutPacketCallback(opts *bind.TransactOpts, seq uint64, packetSenderAddress string) (*types.Transaction, error) { +// Solidity: function onTimeoutPacketCallback(uint64 seq, address packetSenderAddress) payable returns(bool) +func (_ICAModule *ICAModuleTransactor) OnTimeoutPacketCallback(opts *bind.TransactOpts, seq uint64, packetSenderAddress common.Address) (*types.Transaction, error) { return _ICAModule.contract.Transact(opts, "onTimeoutPacketCallback", seq, packetSenderAddress) } -// OnTimeoutPacketCallback is a paid mutator transaction binding the contract method 0xd72be239. +// OnTimeoutPacketCallback is a paid mutator transaction binding the contract method 0x14f4f3f0. // -// Solidity: function onTimeoutPacketCallback(uint64 seq, string packetSenderAddress) payable returns(bool) -func (_ICAModule *ICAModuleSession) OnTimeoutPacketCallback(seq uint64, packetSenderAddress string) (*types.Transaction, error) { +// Solidity: function onTimeoutPacketCallback(uint64 seq, address packetSenderAddress) payable returns(bool) +func (_ICAModule *ICAModuleSession) OnTimeoutPacketCallback(seq uint64, packetSenderAddress common.Address) (*types.Transaction, error) { return _ICAModule.Contract.OnTimeoutPacketCallback(&_ICAModule.TransactOpts, seq, packetSenderAddress) } -// OnTimeoutPacketCallback is a paid mutator transaction binding the contract method 0xd72be239. +// OnTimeoutPacketCallback is a paid mutator transaction binding the contract method 0x14f4f3f0. // -// Solidity: function onTimeoutPacketCallback(uint64 seq, string packetSenderAddress) payable returns(bool) -func (_ICAModule *ICAModuleTransactorSession) OnTimeoutPacketCallback(seq uint64, packetSenderAddress string) (*types.Transaction, error) { +// Solidity: function onTimeoutPacketCallback(uint64 seq, address packetSenderAddress) payable returns(bool) +func (_ICAModule *ICAModuleTransactorSession) OnTimeoutPacketCallback(seq uint64, packetSenderAddress common.Address) (*types.Transaction, error) { return _ICAModule.Contract.OnTimeoutPacketCallback(&_ICAModule.TransactOpts, seq, packetSenderAddress) } diff --git a/x/cronos/events/bindings/src/ICA.sol b/x/cronos/events/bindings/src/ICA.sol index b57bddc503..ea3bf43c7a 100644 --- a/x/cronos/events/bindings/src/ICA.sol +++ b/x/cronos/events/bindings/src/ICA.sol @@ -6,6 +6,6 @@ interface IICAModule { function registerAccount(string calldata connectionID, string calldata version) external payable returns (bool); function queryAccount(string calldata connectionID, address addr) external view returns (string memory); function submitMsgs(string calldata connectionID, bytes calldata data, uint256 timeout) external payable returns (uint64); - function onAcknowledgementPacketCallback(uint64 seq, string calldata packetSenderAddress) external payable returns (bool); - function onTimeoutPacketCallback(uint64 seq, string calldata packetSenderAddress) external payable returns (bool); + function onAcknowledgementPacketCallback(uint64 seq, address packetSenderAddress, bytes calldata acknowledgement) external payable returns (bool); + function onTimeoutPacketCallback(uint64 seq, address packetSenderAddress) external payable returns (bool); } From bcf46633a5c0f2a8da97bdf57312f34e0567f9d2 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Tue, 26 Sep 2023 20:46:35 +0800 Subject: [PATCH 12/26] notify caller --- app/app.go | 2 +- x/cronos/keeper/keeper.go | 14 ++++++-- x/cronos/keeper/precompiles/ica.go | 54 +++++++++++++++++++++++++----- x/cronos/types/interfaces.go | 16 +++++++++ 4 files changed, 74 insertions(+), 12 deletions(-) diff --git a/app/app.go b/app/app.go index 6a3387a76a..fd21a79968 100644 --- a/app/app.go +++ b/app/app.go @@ -552,7 +552,7 @@ func New( []vm.PrecompiledContract{ cronosprecompiles.NewBankContract(app.BankKeeper, appCodec), cronosprecompiles.NewRelayerContract(app.IBCKeeper, appCodec), - cronosprecompiles.NewIcaContract(&app.ICAAuthKeeper, appCodec), + cronosprecompiles.NewIcaContract(&app.ICAAuthKeeper, &app.CronosKeeper, appCodec), }, allKeys, ) diff --git a/x/cronos/keeper/keeper.go b/x/cronos/keeper/keeper.go index ff00830563..4e95e9132e 100644 --- a/x/cronos/keeper/keeper.go +++ b/x/cronos/keeper/keeper.go @@ -290,9 +290,14 @@ func (k Keeper) IBCOnAcknowledgementPacketCallback( contractAddress, packetSenderAddress string, ) error { + senderAddr, err := sdk.AccAddressFromBech32(packetSenderAddress) + if err != nil { + return fmt.Errorf("invalid bech32 address: %s, err: %w", packetSenderAddress, err) + } + sender := common.BytesToAddress(senderAddr.Bytes()) relayerAddr := common.BytesToAddress(relayer.Bytes()) precompileAddr := common.HexToAddress(contractAddress) - data, err := cronosprecompiles.GetOnAcknowledgementPacketCallback(packet.Sequence, packetSenderAddress) + data, err := cronosprecompiles.GetOnAcknowledgementPacketCallback(packet.Sequence, sender, acknowledgement) if err != nil { return err } @@ -307,9 +312,14 @@ func (k Keeper) IBCOnTimeoutPacketCallback( contractAddress, packetSenderAddress string, ) error { + senderAddr, err := sdk.AccAddressFromBech32(packetSenderAddress) + if err != nil { + return fmt.Errorf("invalid bech32 address: %s, err: %w", packetSenderAddress, err) + } + sender := common.BytesToAddress(senderAddr.Bytes()) relayerAddr := common.BytesToAddress(relayer.Bytes()) precompileAddr := common.HexToAddress(contractAddress) - data, err := cronosprecompiles.GetOnTimeoutPacketCallback(packet.Sequence, packetSenderAddress) + data, err := cronosprecompiles.GetOnTimeoutPacketCallback(packet.Sequence, sender) if err != nil { return err } diff --git a/x/cronos/keeper/precompiles/ica.go b/x/cronos/keeper/precompiles/ica.go index 31c8912c6e..e82bf9c600 100644 --- a/x/cronos/keeper/precompiles/ica.go +++ b/x/cronos/keeper/precompiles/ica.go @@ -12,8 +12,9 @@ import ( cronosevents "github.com/crypto-org-chain/cronos/v2/x/cronos/events" "github.com/crypto-org-chain/cronos/v2/x/cronos/events/bindings/cosmos/precompile/ica" cronoseventstypes "github.com/crypto-org-chain/cronos/v2/x/cronos/events/types" - icaauthkeeper "github.com/crypto-org-chain/cronos/v2/x/icaauth/keeper" - "github.com/crypto-org-chain/cronos/v2/x/icaauth/types" + "github.com/crypto-org-chain/cronos/v2/x/cronos/types" + + icaauthtypes "github.com/crypto-org-chain/cronos/v2/x/icaauth/types" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/vm" @@ -45,14 +46,16 @@ type IcaContract struct { BaseContract cdc codec.Codec - icaauthKeeper *icaauthkeeper.Keeper + icaauthKeeper types.Icaauthkeeper + cronosKeeper types.CronosKeeper } -func NewIcaContract(icaauthKeeper *icaauthkeeper.Keeper, cdc codec.Codec) vm.PrecompiledContract { +func NewIcaContract(icaauthKeeper types.Icaauthkeeper, cronosKeeper types.CronosKeeper, cdc codec.Codec) vm.PrecompiledContract { return &IcaContract{ BaseContract: NewBaseContract(icaContractAddress), cdc: cdc, icaauthKeeper: icaauthKeeper, + cronosKeeper: cronosKeeper, } } @@ -94,7 +97,7 @@ func (ic *IcaContract) Run(evm *vm.EVM, contract *vm.Contract, readonly bool) ([ connectionID := args[0].(string) version := args[1].(string) execErr = stateDB.ExecuteNativeAction(precompileAddr, converter, func(ctx sdk.Context) error { - _, err := ic.icaauthKeeper.RegisterAccount(ctx, &types.MsgRegisterAccount{ + _, err := ic.icaauthKeeper.RegisterAccount(ctx, &icaauthtypes.MsgRegisterAccount{ Owner: owner, ConnectionId: connectionID, Version: version, @@ -116,7 +119,7 @@ func (ic *IcaContract) Run(evm *vm.EVM, contract *vm.Contract, readonly bool) ([ icaAddress := "" response, err := ic.icaauthKeeper.InterchainAccountAddress( stateDB.CacheContext(), - &types.QueryInterchainAccountAddressRequest{ + &icaauthtypes.QueryInterchainAccountAddressRequest{ Owner: owner, ConnectionId: connectionID, }) @@ -168,7 +171,30 @@ func (ic *IcaContract) Run(evm *vm.EVM, contract *vm.Contract, readonly bool) ([ return nil, execErr } return method.Outputs.Pack(seq) - case "onAcknowledgementPacketCallback", "onTimeoutPacketCallback": + case "onAcknowledgementPacketCallback": + if readonly { + return nil, errors.New("the method is not readonly") + } + args, err := method.Inputs.Unpack(contract.Input[4:]) + if err != nil { + return nil, errors.New("fail to unpack input arguments") + } + seq := args[0].(uint64) + sender := args[1].(common.Address) + acknowledgement := args[2].([]byte) + data, err := GetOnAcknowledgementPacketCallback(seq, sender, acknowledgement) + if err != nil { + return nil, err + } + execErr = stateDB.ExecuteNativeAction(precompileAddr, converter, func(ctx sdk.Context) error { + _, _, err := ic.cronosKeeper.CallEVMWithArgs(ctx, &sender, precompileAddr, data, big.NewInt(0)) + return err + }) + if execErr != nil { + return nil, execErr + } + return method.Outputs.Pack(true) + case "onTimeoutPacketCallback": if readonly { return nil, errors.New("the method is not readonly") } @@ -177,8 +203,18 @@ func (ic *IcaContract) Run(evm *vm.EVM, contract *vm.Contract, readonly bool) ([ return nil, errors.New("fail to unpack input arguments") } seq := args[0].(uint64) - packetSenderAddress := args[1].(string) - fmt.Printf("mm-%s, %d, %s\n", method.Name, seq, packetSenderAddress) + sender := args[1].(common.Address) + data, err := GetOnTimeoutPacketCallback(seq, sender) + if err != nil { + return nil, err + } + execErr = stateDB.ExecuteNativeAction(precompileAddr, converter, func(ctx sdk.Context) error { + _, _, err := ic.cronosKeeper.CallEVMWithArgs(ctx, &sender, precompileAddr, data, big.NewInt(0)) + return err + }) + if execErr != nil { + return nil, execErr + } return method.Outputs.Pack(true) default: return nil, errors.New("unknown method") diff --git a/x/cronos/types/interfaces.go b/x/cronos/types/interfaces.go index a630a74911..87198bda9b 100644 --- a/x/cronos/types/interfaces.go +++ b/x/cronos/types/interfaces.go @@ -3,15 +3,19 @@ package types import ( context "context" "math/big" + time "time" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" tmbytes "github.com/cometbft/cometbft/libs/bytes" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + icaauthtypes "github.com/crypto-org-chain/cronos/v2/x/icaauth/types" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" + ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/params" evmtypes "github.com/evmos/ethermint/x/evm/types" @@ -74,3 +78,15 @@ type EvmKeeper interface { DeductTxCostsFromUserBalance(ctx sdk.Context, fees sdk.Coins, from common.Address) error ChainID() *big.Int } + +// Icaauthkeeper defines the interface for icaauth keeper +type Icaauthkeeper interface { + RegisterAccount(goCtx context.Context, msg *icaauthtypes.MsgRegisterAccount) (*icaauthtypes.MsgRegisterAccountResponse, error) + InterchainAccountAddress(goCtx context.Context, req *icaauthtypes.QueryInterchainAccountAddressRequest) (*icaauthtypes.QueryInterchainAccountAddressResponse, error) + SubmitTxWithArgs(goCtx context.Context, owner, connectionId string, timeoutDuration time.Duration, packetData icatypes.InterchainAccountPacketData) (*icaauthtypes.MsgSubmitTxResponse, error) +} + +// CronosKeeper defines the interface for cronos keeper +type CronosKeeper interface { + CallEVMWithArgs(ctx sdk.Context, to *common.Address, from common.Address, data []byte, value *big.Int) (*ethtypes.Message, *evmtypes.MsgEthereumTxResponse, error) +} From 9a2f5315d1f8b2f4ab1352e367f4ac53a5acb274 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Wed, 27 Sep 2023 09:28:08 +0800 Subject: [PATCH 13/26] fix migrate fix test fix lint test param --- integration_tests/test_upgrade.py | 1 + x/cronos/exported/exported.go | 2 +- x/cronos/migrations/v2/migrate.go | 6 ++++-- x/cronos/migrations/v2/migrate_test.go | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/integration_tests/test_upgrade.py b/integration_tests/test_upgrade.py index 02f6100250..4513d141ab 100644 --- a/integration_tests/test_upgrade.py +++ b/integration_tests/test_upgrade.py @@ -186,6 +186,7 @@ def test_cosmovisor_upgrade(custom_cronos: Cronos, tmp_path_factory): rsp = cli.query_params("icaauth") assert rsp["params"]["min_timeout_duration"] == "3600s", rsp + assert cli.query_params()["max_callback_gas"] == "300000", rsp # migrate to sdk v0.47 custom_cronos.supervisorctl("stop", "all") diff --git a/x/cronos/exported/exported.go b/x/cronos/exported/exported.go index 000114e619..64dc23a561 100644 --- a/x/cronos/exported/exported.go +++ b/x/cronos/exported/exported.go @@ -13,6 +13,6 @@ type ( // // NOTE: This is used solely for migration of x/params managed parameters. Subspace interface { - GetParamSet(ctx sdk.Context, ps ParamSet) + GetParamSetIfExists(ctx sdk.Context, ps ParamSet) } ) diff --git a/x/cronos/migrations/v2/migrate.go b/x/cronos/migrations/v2/migrate.go index 438bca6a14..2f0a383a4c 100644 --- a/x/cronos/migrations/v2/migrate.go +++ b/x/cronos/migrations/v2/migrate.go @@ -13,12 +13,14 @@ import ( // module state. func Migrate(ctx sdk.Context, store sdk.KVStore, legacySubspace exported.Subspace, cdc codec.BinaryCodec) error { var currParams types.Params - legacySubspace.GetParamSet(ctx, &currParams) + legacySubspace.GetParamSetIfExists(ctx, &currParams) if err := currParams.Validate(); err != nil { return err } - + if currParams.GetMaxCallbackGas() == 0 { + currParams.MaxCallbackGas = types.MaxCallbackGasDefaultValue + } bz := cdc.MustMarshal(&currParams) store.Set(types.ParamsKey, bz) diff --git a/x/cronos/migrations/v2/migrate_test.go b/x/cronos/migrations/v2/migrate_test.go index aff338f375..5240f3f2fa 100644 --- a/x/cronos/migrations/v2/migrate_test.go +++ b/x/cronos/migrations/v2/migrate_test.go @@ -20,7 +20,7 @@ func newMockSubspace(ps types.Params) mockSubspace { return mockSubspace{ps: ps} } -func (ms mockSubspace) GetParamSet(ctx sdk.Context, ps exported.ParamSet) { +func (ms mockSubspace) GetParamSetIfExists(ctx sdk.Context, ps exported.ParamSet) { *ps.(*types.Params) = ms.ps } From 5052c3b6c39d42dad0f618a80b9a37e131bc710a Mon Sep 17 00:00:00 2001 From: mmsqe Date: Wed, 27 Sep 2023 12:31:49 +0800 Subject: [PATCH 14/26] add cb signature --- .../contracts/contracts/TestICA.sol | 22 +- integration_tests/test_ica_precompile.py | 4 + scripts/gen-bindings-contracts | 2 + .../precompile/ica/i_ica_module.abigen.go | 47 +-- .../icacallback/icacallback.abigen.go | 389 ++++++++++++++++++ x/cronos/events/bindings/src/ICA.sol | 3 +- x/cronos/events/bindings/src/ICACallback.sol | 20 + x/cronos/keeper/evm.go | 9 +- x/cronos/keeper/keeper.go | 32 +- x/cronos/keeper/precompiles/ica.go | 41 +- x/cronos/types/interfaces.go | 2 +- 11 files changed, 473 insertions(+), 98 deletions(-) create mode 100644 x/cronos/events/bindings/cosmos/precompile/icacallback/icacallback.abigen.go create mode 100644 x/cronos/events/bindings/src/ICACallback.sol diff --git a/integration_tests/contracts/contracts/TestICA.sol b/integration_tests/contracts/contracts/TestICA.sol index 3af66d1804..a1d7797493 100644 --- a/integration_tests/contracts/contracts/TestICA.sol +++ b/integration_tests/contracts/contracts/TestICA.sol @@ -7,9 +7,12 @@ contract TestICA { address constant icaContract = 0x0000000000000000000000000000000000000066; IICAModule ica = IICAModule(icaContract); address account; + // sha256('cronos-evm')[:20] + address constant module_address = 0x89A7EF2F08B1c018D5Cc88836249b84Dd5392905; uint64 lastAckSeq; - event OnAcknowledgementPacketResult(uint64 seq, bytes acknowledgement); - event OnTimeoutPacketResult(uint64 seq); + bytes lastAck; + mapping (uint64 => bytes) public acknowledgement; + event OnPacketResult(uint64 seq, bytes ack); function encodeRegister(string memory connectionID, string memory version) internal view returns (bytes memory) { return abi.encodeWithSignature( @@ -95,13 +98,16 @@ contract TestICA { return lastAckSeq; } - function onAcknowledgementPacketCallback(uint64 seq, address packetSenderAddress, bytes calldata acknowledgement) public { - require(packetSenderAddress == address(this), "different sender"); - emit OnAcknowledgementPacketResult(seq, acknowledgement); + function getLastAck() public view returns (bytes memory) { + return lastAck; } - function onTimeoutPacketCallback(uint64 seq, address packetSenderAddress) public { - require(packetSenderAddress == address(this), "different sender"); - emit OnTimeoutPacketResult(seq); + function onPacketResultCallback(uint64 seq, bytes calldata ack) external payable returns (bool) { + // require(msg.sender == module_address); + lastAckSeq = seq; + lastAck = ack; + acknowledgement[seq] = ack; + emit OnPacketResult(seq, ack); + return true; } } \ No newline at end of file diff --git a/integration_tests/test_ica_precompile.py b/integration_tests/test_ica_precompile.py index 7aa08e714c..d747f5130d 100644 --- a/integration_tests/test_ica_precompile.py +++ b/integration_tests/test_ica_precompile.py @@ -191,6 +191,8 @@ def submit_msgs_ro(func, str): submit_msgs_ro(tcontract.functions.staticSubmitMsgs, str) assert tcontract.caller.getLastAckSeq() == seq balance -= amt + ack = tcontract.caller.getLastAck() + assert ack == tcontract.caller.acknowledgement(seq) assert cli_host.balance(ica_address, denom=denom) == balance seq = 2 str = submit_msgs( @@ -206,3 +208,5 @@ def submit_msgs_ro(func, str): balance -= amt balance -= amt1 assert cli_host.balance(ica_address, denom=denom) == balance + ack = tcontract.caller.getLastAck() + assert ack == tcontract.caller.acknowledgement(seq) diff --git a/scripts/gen-bindings-contracts b/scripts/gen-bindings-contracts index 52d629244b..b1f15c7f87 100755 --- a/scripts/gen-bindings-contracts +++ b/scripts/gen-bindings-contracts @@ -4,9 +4,11 @@ solc08 --abi --bin x/cronos/events/bindings/src/CosmosTypes.sol -o build --overw solc08 --abi --bin x/cronos/events/bindings/src/Relayer.sol -o build --overwrite solc08 --abi --bin x/cronos/events/bindings/src/Bank.sol -o build --overwrite solc08 --abi --bin x/cronos/events/bindings/src/ICA.sol -o build --overwrite +solc08 --abi --bin x/cronos/events/bindings/src/ICACallback.sol -o build --overwrite abigen --pkg lib --abi build/CosmosTypes.abi --bin build/CosmosTypes.bin --out x/cronos/events/bindings/cosmos/lib/cosmos_types.abigen.go --type CosmosTypes abigen --pkg relayer --abi build/IRelayerModule.abi --bin build/IRelayerModule.bin --out x/cronos/events/bindings/cosmos/precompile/relayer/i_relayer_module.abigen.go --type RelayerModule abigen --pkg bank --abi build/IBankModule.abi --bin build/IBankModule.bin --out x/cronos/events/bindings/cosmos/precompile/bank/i_bank_module.abigen.go --type BankModule abigen --pkg ica --abi build/IICAModule.abi --bin build/IICAModule.bin --out x/cronos/events/bindings/cosmos/precompile/ica/i_ica_module.abigen.go --type ICAModule +abigen --pkg icacallback --abi build/ICACallback.abi --bin build/ICACallback.bin --out x/cronos/events/bindings/cosmos/precompile/icacallback/icacallback.abigen.go --type ICACallback diff --git a/x/cronos/events/bindings/cosmos/precompile/ica/i_ica_module.abigen.go b/x/cronos/events/bindings/cosmos/precompile/ica/i_ica_module.abigen.go index a98d055f6b..2709567df8 100644 --- a/x/cronos/events/bindings/cosmos/precompile/ica/i_ica_module.abigen.go +++ b/x/cronos/events/bindings/cosmos/precompile/ica/i_ica_module.abigen.go @@ -30,7 +30,7 @@ var ( // ICAModuleMetaData contains all meta data concerning the ICAModule contract. var ICAModuleMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"}],\"name\":\"SubmitMsgsResult\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"packetSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"acknowledgement\",\"type\":\"bytes\"}],\"name\":\"onAcknowledgementPacketCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"packetSenderAddress\",\"type\":\"address\"}],\"name\":\"onTimeoutPacketCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"queryAccount\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"}],\"name\":\"registerAccount\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"timeout\",\"type\":\"uint256\"}],\"name\":\"submitMsgs\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"}],\"name\":\"SubmitMsgsResult\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"packetSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"ack\",\"type\":\"bytes\"}],\"name\":\"onPacketResult\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"queryAccount\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"}],\"name\":\"registerAccount\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"timeout\",\"type\":\"uint256\"}],\"name\":\"submitMsgs\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", } // ICAModuleABI is the input ABI used to generate the binding from. @@ -210,46 +210,25 @@ func (_ICAModule *ICAModuleCallerSession) QueryAccount(connectionID string, addr return _ICAModule.Contract.QueryAccount(&_ICAModule.CallOpts, connectionID, addr) } -// OnAcknowledgementPacketCallback is a paid mutator transaction binding the contract method 0xee3ce76a. +// OnPacketResult is a paid mutator transaction binding the contract method 0x15400f96. // -// Solidity: function onAcknowledgementPacketCallback(uint64 seq, address packetSenderAddress, bytes acknowledgement) payable returns(bool) -func (_ICAModule *ICAModuleTransactor) OnAcknowledgementPacketCallback(opts *bind.TransactOpts, seq uint64, packetSenderAddress common.Address, acknowledgement []byte) (*types.Transaction, error) { - return _ICAModule.contract.Transact(opts, "onAcknowledgementPacketCallback", seq, packetSenderAddress, acknowledgement) +// Solidity: function onPacketResult(uint64 seq, address packetSenderAddress, bytes ack) payable returns(bool) +func (_ICAModule *ICAModuleTransactor) OnPacketResult(opts *bind.TransactOpts, seq uint64, packetSenderAddress common.Address, ack []byte) (*types.Transaction, error) { + return _ICAModule.contract.Transact(opts, "onPacketResult", seq, packetSenderAddress, ack) } -// OnAcknowledgementPacketCallback is a paid mutator transaction binding the contract method 0xee3ce76a. +// OnPacketResult is a paid mutator transaction binding the contract method 0x15400f96. // -// Solidity: function onAcknowledgementPacketCallback(uint64 seq, address packetSenderAddress, bytes acknowledgement) payable returns(bool) -func (_ICAModule *ICAModuleSession) OnAcknowledgementPacketCallback(seq uint64, packetSenderAddress common.Address, acknowledgement []byte) (*types.Transaction, error) { - return _ICAModule.Contract.OnAcknowledgementPacketCallback(&_ICAModule.TransactOpts, seq, packetSenderAddress, acknowledgement) +// Solidity: function onPacketResult(uint64 seq, address packetSenderAddress, bytes ack) payable returns(bool) +func (_ICAModule *ICAModuleSession) OnPacketResult(seq uint64, packetSenderAddress common.Address, ack []byte) (*types.Transaction, error) { + return _ICAModule.Contract.OnPacketResult(&_ICAModule.TransactOpts, seq, packetSenderAddress, ack) } -// OnAcknowledgementPacketCallback is a paid mutator transaction binding the contract method 0xee3ce76a. +// OnPacketResult is a paid mutator transaction binding the contract method 0x15400f96. // -// Solidity: function onAcknowledgementPacketCallback(uint64 seq, address packetSenderAddress, bytes acknowledgement) payable returns(bool) -func (_ICAModule *ICAModuleTransactorSession) OnAcknowledgementPacketCallback(seq uint64, packetSenderAddress common.Address, acknowledgement []byte) (*types.Transaction, error) { - return _ICAModule.Contract.OnAcknowledgementPacketCallback(&_ICAModule.TransactOpts, seq, packetSenderAddress, acknowledgement) -} - -// OnTimeoutPacketCallback is a paid mutator transaction binding the contract method 0x14f4f3f0. -// -// Solidity: function onTimeoutPacketCallback(uint64 seq, address packetSenderAddress) payable returns(bool) -func (_ICAModule *ICAModuleTransactor) OnTimeoutPacketCallback(opts *bind.TransactOpts, seq uint64, packetSenderAddress common.Address) (*types.Transaction, error) { - return _ICAModule.contract.Transact(opts, "onTimeoutPacketCallback", seq, packetSenderAddress) -} - -// OnTimeoutPacketCallback is a paid mutator transaction binding the contract method 0x14f4f3f0. -// -// Solidity: function onTimeoutPacketCallback(uint64 seq, address packetSenderAddress) payable returns(bool) -func (_ICAModule *ICAModuleSession) OnTimeoutPacketCallback(seq uint64, packetSenderAddress common.Address) (*types.Transaction, error) { - return _ICAModule.Contract.OnTimeoutPacketCallback(&_ICAModule.TransactOpts, seq, packetSenderAddress) -} - -// OnTimeoutPacketCallback is a paid mutator transaction binding the contract method 0x14f4f3f0. -// -// Solidity: function onTimeoutPacketCallback(uint64 seq, address packetSenderAddress) payable returns(bool) -func (_ICAModule *ICAModuleTransactorSession) OnTimeoutPacketCallback(seq uint64, packetSenderAddress common.Address) (*types.Transaction, error) { - return _ICAModule.Contract.OnTimeoutPacketCallback(&_ICAModule.TransactOpts, seq, packetSenderAddress) +// Solidity: function onPacketResult(uint64 seq, address packetSenderAddress, bytes ack) payable returns(bool) +func (_ICAModule *ICAModuleTransactorSession) OnPacketResult(seq uint64, packetSenderAddress common.Address, ack []byte) (*types.Transaction, error) { + return _ICAModule.Contract.OnPacketResult(&_ICAModule.TransactOpts, seq, packetSenderAddress, ack) } // RegisterAccount is a paid mutator transaction binding the contract method 0xddc7b6a7. diff --git a/x/cronos/events/bindings/cosmos/precompile/icacallback/icacallback.abigen.go b/x/cronos/events/bindings/cosmos/precompile/icacallback/icacallback.abigen.go new file mode 100644 index 0000000000..cdcf8a2481 --- /dev/null +++ b/x/cronos/events/bindings/cosmos/precompile/icacallback/icacallback.abigen.go @@ -0,0 +1,389 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package icacallback + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + +// ICACallbackMetaData contains all meta data concerning the ICACallback contract. +var ICACallbackMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"ack\",\"type\":\"bytes\"}],\"name\":\"OnPacketResult\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"acknowledgement\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"ack\",\"type\":\"bytes\"}],\"name\":\"onPacketResultCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561000f575f80fd5b506107a98061001d5f395ff3fe608060405260043610610028575f3560e01c8063968bcba31461002c578063a6d9a1c214610068575b5f80fd5b348015610037575f80fd5b50610052600480360381019061004d919061022d565b610098565b60405161005f91906102e2565b60405180910390f35b610082600480360381019061007d9190610363565b610133565b60405161008f91906103da565b60405180910390f35b6002602052805f5260405f205f9150905080546100b490610420565b80601f01602080910402602001604051908101604052809291908181526020018280546100e090610420565b801561012b5780601f106101025761010080835404028352916020019161012b565b820191905f5260205f20905b81548152906001019060200180831161010e57829003601f168201915b505050505081565b5f835f806101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555082826001918261016c92919061062d565b50828260025f8767ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f2091826101a192919061062d565b507f8e0c6cb5698eba8240951fde76f9e06a0844d4285c0e56f4cedf1415d03703fc8484846040516101d593929190610743565b60405180910390a1600190509392505050565b5f80fd5b5f80fd5b5f67ffffffffffffffff82169050919050565b61020c816101f0565b8114610216575f80fd5b50565b5f8135905061022781610203565b92915050565b5f60208284031215610242576102416101e8565b5b5f61024f84828501610219565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561028f578082015181840152602081019050610274565b5f8484015250505050565b5f601f19601f8301169050919050565b5f6102b482610258565b6102be8185610262565b93506102ce818560208601610272565b6102d78161029a565b840191505092915050565b5f6020820190508181035f8301526102fa81846102aa565b905092915050565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261032357610322610302565b5b8235905067ffffffffffffffff8111156103405761033f610306565b5b60208301915083600182028301111561035c5761035b61030a565b5b9250929050565b5f805f6040848603121561037a576103796101e8565b5b5f61038786828701610219565b935050602084013567ffffffffffffffff8111156103a8576103a76101ec565b5b6103b48682870161030e565b92509250509250925092565b5f8115159050919050565b6103d4816103c0565b82525050565b5f6020820190506103ed5f8301846103cb565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061043757607f821691505b60208210810361044a576104496103f3565b5b50919050565b5f82905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026104e37fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826104a8565b6104ed86836104a8565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f61053161052c61052784610505565b61050e565b610505565b9050919050565b5f819050919050565b61054a83610517565b61055e61055682610538565b8484546104b4565b825550505050565b5f90565b610572610566565b61057d818484610541565b505050565b5b818110156105a0576105955f8261056a565b600181019050610583565b5050565b601f8211156105e5576105b681610487565b6105bf84610499565b810160208510156105ce578190505b6105e26105da85610499565b830182610582565b50505b505050565b5f82821c905092915050565b5f6106055f19846008026105ea565b1980831691505092915050565b5f61061d83836105f6565b9150826002028217905092915050565b6106378383610450565b67ffffffffffffffff8111156106505761064f61045a565b5b61065a8254610420565b6106658282856105a4565b5f601f831160018114610692575f8415610680578287013590505b61068a8582610612565b8655506106f1565b601f1984166106a086610487565b5f5b828110156106c7578489013582556001820191506020850194506020810190506106a2565b868310156106e457848901356106e0601f8916826105f6565b8355505b6001600288020188555050505b50505050505050565b610703816101f0565b82525050565b828183375f83830152505050565b5f6107228385610262565b935061072f838584610709565b6107388361029a565b840190509392505050565b5f6040820190506107565f8301866106fa565b8181036020830152610769818486610717565b905094935050505056fea2646970667358221220209d1395f552db65e120063a95265a8c5d0c258b4fabfa7545d202c4e45287bb64736f6c63430008150033", +} + +// ICACallbackABI is the input ABI used to generate the binding from. +// Deprecated: Use ICACallbackMetaData.ABI instead. +var ICACallbackABI = ICACallbackMetaData.ABI + +// ICACallbackBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ICACallbackMetaData.Bin instead. +var ICACallbackBin = ICACallbackMetaData.Bin + +// DeployICACallback deploys a new Ethereum contract, binding an instance of ICACallback to it. +func DeployICACallback(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ICACallback, error) { + parsed, err := ICACallbackMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ICACallbackBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ICACallback{ICACallbackCaller: ICACallbackCaller{contract: contract}, ICACallbackTransactor: ICACallbackTransactor{contract: contract}, ICACallbackFilterer: ICACallbackFilterer{contract: contract}}, nil +} + +// ICACallback is an auto generated Go binding around an Ethereum contract. +type ICACallback struct { + ICACallbackCaller // Read-only binding to the contract + ICACallbackTransactor // Write-only binding to the contract + ICACallbackFilterer // Log filterer for contract events +} + +// ICACallbackCaller is an auto generated read-only Go binding around an Ethereum contract. +type ICACallbackCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ICACallbackTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ICACallbackTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ICACallbackFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ICACallbackFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ICACallbackSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ICACallbackSession struct { + Contract *ICACallback // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ICACallbackCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ICACallbackCallerSession struct { + Contract *ICACallbackCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ICACallbackTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ICACallbackTransactorSession struct { + Contract *ICACallbackTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ICACallbackRaw is an auto generated low-level Go binding around an Ethereum contract. +type ICACallbackRaw struct { + Contract *ICACallback // Generic contract binding to access the raw methods on +} + +// ICACallbackCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ICACallbackCallerRaw struct { + Contract *ICACallbackCaller // Generic read-only contract binding to access the raw methods on +} + +// ICACallbackTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ICACallbackTransactorRaw struct { + Contract *ICACallbackTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewICACallback creates a new instance of ICACallback, bound to a specific deployed contract. +func NewICACallback(address common.Address, backend bind.ContractBackend) (*ICACallback, error) { + contract, err := bindICACallback(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ICACallback{ICACallbackCaller: ICACallbackCaller{contract: contract}, ICACallbackTransactor: ICACallbackTransactor{contract: contract}, ICACallbackFilterer: ICACallbackFilterer{contract: contract}}, nil +} + +// NewICACallbackCaller creates a new read-only instance of ICACallback, bound to a specific deployed contract. +func NewICACallbackCaller(address common.Address, caller bind.ContractCaller) (*ICACallbackCaller, error) { + contract, err := bindICACallback(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ICACallbackCaller{contract: contract}, nil +} + +// NewICACallbackTransactor creates a new write-only instance of ICACallback, bound to a specific deployed contract. +func NewICACallbackTransactor(address common.Address, transactor bind.ContractTransactor) (*ICACallbackTransactor, error) { + contract, err := bindICACallback(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ICACallbackTransactor{contract: contract}, nil +} + +// NewICACallbackFilterer creates a new log filterer instance of ICACallback, bound to a specific deployed contract. +func NewICACallbackFilterer(address common.Address, filterer bind.ContractFilterer) (*ICACallbackFilterer, error) { + contract, err := bindICACallback(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ICACallbackFilterer{contract: contract}, nil +} + +// bindICACallback binds a generic wrapper to an already deployed contract. +func bindICACallback(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(ICACallbackABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ICACallback *ICACallbackRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ICACallback.Contract.ICACallbackCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ICACallback *ICACallbackRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ICACallback.Contract.ICACallbackTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ICACallback *ICACallbackRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ICACallback.Contract.ICACallbackTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ICACallback *ICACallbackCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ICACallback.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ICACallback *ICACallbackTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ICACallback.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ICACallback *ICACallbackTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ICACallback.Contract.contract.Transact(opts, method, params...) +} + +// Acknowledgement is a free data retrieval call binding the contract method 0x968bcba3. +// +// Solidity: function acknowledgement(uint64 ) view returns(bytes) +func (_ICACallback *ICACallbackCaller) Acknowledgement(opts *bind.CallOpts, arg0 uint64) ([]byte, error) { + var out []interface{} + err := _ICACallback.contract.Call(opts, &out, "acknowledgement", arg0) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// Acknowledgement is a free data retrieval call binding the contract method 0x968bcba3. +// +// Solidity: function acknowledgement(uint64 ) view returns(bytes) +func (_ICACallback *ICACallbackSession) Acknowledgement(arg0 uint64) ([]byte, error) { + return _ICACallback.Contract.Acknowledgement(&_ICACallback.CallOpts, arg0) +} + +// Acknowledgement is a free data retrieval call binding the contract method 0x968bcba3. +// +// Solidity: function acknowledgement(uint64 ) view returns(bytes) +func (_ICACallback *ICACallbackCallerSession) Acknowledgement(arg0 uint64) ([]byte, error) { + return _ICACallback.Contract.Acknowledgement(&_ICACallback.CallOpts, arg0) +} + +// OnPacketResultCallback is a paid mutator transaction binding the contract method 0xa6d9a1c2. +// +// Solidity: function onPacketResultCallback(uint64 seq, bytes ack) payable returns(bool) +func (_ICACallback *ICACallbackTransactor) OnPacketResultCallback(opts *bind.TransactOpts, seq uint64, ack []byte) (*types.Transaction, error) { + return _ICACallback.contract.Transact(opts, "onPacketResultCallback", seq, ack) +} + +// OnPacketResultCallback is a paid mutator transaction binding the contract method 0xa6d9a1c2. +// +// Solidity: function onPacketResultCallback(uint64 seq, bytes ack) payable returns(bool) +func (_ICACallback *ICACallbackSession) OnPacketResultCallback(seq uint64, ack []byte) (*types.Transaction, error) { + return _ICACallback.Contract.OnPacketResultCallback(&_ICACallback.TransactOpts, seq, ack) +} + +// OnPacketResultCallback is a paid mutator transaction binding the contract method 0xa6d9a1c2. +// +// Solidity: function onPacketResultCallback(uint64 seq, bytes ack) payable returns(bool) +func (_ICACallback *ICACallbackTransactorSession) OnPacketResultCallback(seq uint64, ack []byte) (*types.Transaction, error) { + return _ICACallback.Contract.OnPacketResultCallback(&_ICACallback.TransactOpts, seq, ack) +} + +// ICACallbackOnPacketResultIterator is returned from FilterOnPacketResult and is used to iterate over the raw logs and unpacked data for OnPacketResult events raised by the ICACallback contract. +type ICACallbackOnPacketResultIterator struct { + Event *ICACallbackOnPacketResult // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ICACallbackOnPacketResultIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ICACallbackOnPacketResult) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ICACallbackOnPacketResult) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ICACallbackOnPacketResultIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ICACallbackOnPacketResultIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ICACallbackOnPacketResult represents a OnPacketResult event raised by the ICACallback contract. +type ICACallbackOnPacketResult struct { + Seq uint64 + Ack []byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOnPacketResult is a free log retrieval operation binding the contract event 0x8e0c6cb5698eba8240951fde76f9e06a0844d4285c0e56f4cedf1415d03703fc. +// +// Solidity: event OnPacketResult(uint64 seq, bytes ack) +func (_ICACallback *ICACallbackFilterer) FilterOnPacketResult(opts *bind.FilterOpts) (*ICACallbackOnPacketResultIterator, error) { + + logs, sub, err := _ICACallback.contract.FilterLogs(opts, "OnPacketResult") + if err != nil { + return nil, err + } + return &ICACallbackOnPacketResultIterator{contract: _ICACallback.contract, event: "OnPacketResult", logs: logs, sub: sub}, nil +} + +// WatchOnPacketResult is a free log subscription operation binding the contract event 0x8e0c6cb5698eba8240951fde76f9e06a0844d4285c0e56f4cedf1415d03703fc. +// +// Solidity: event OnPacketResult(uint64 seq, bytes ack) +func (_ICACallback *ICACallbackFilterer) WatchOnPacketResult(opts *bind.WatchOpts, sink chan<- *ICACallbackOnPacketResult) (event.Subscription, error) { + + logs, sub, err := _ICACallback.contract.WatchLogs(opts, "OnPacketResult") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ICACallbackOnPacketResult) + if err := _ICACallback.contract.UnpackLog(event, "OnPacketResult", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseOnPacketResult is a log parse operation binding the contract event 0x8e0c6cb5698eba8240951fde76f9e06a0844d4285c0e56f4cedf1415d03703fc. +// +// Solidity: event OnPacketResult(uint64 seq, bytes ack) +func (_ICACallback *ICACallbackFilterer) ParseOnPacketResult(log types.Log) (*ICACallbackOnPacketResult, error) { + event := new(ICACallbackOnPacketResult) + if err := _ICACallback.contract.UnpackLog(event, "OnPacketResult", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/x/cronos/events/bindings/src/ICA.sol b/x/cronos/events/bindings/src/ICA.sol index ea3bf43c7a..2b68f92243 100644 --- a/x/cronos/events/bindings/src/ICA.sol +++ b/x/cronos/events/bindings/src/ICA.sol @@ -6,6 +6,5 @@ interface IICAModule { function registerAccount(string calldata connectionID, string calldata version) external payable returns (bool); function queryAccount(string calldata connectionID, address addr) external view returns (string memory); function submitMsgs(string calldata connectionID, bytes calldata data, uint256 timeout) external payable returns (uint64); - function onAcknowledgementPacketCallback(uint64 seq, address packetSenderAddress, bytes calldata acknowledgement) external payable returns (bool); - function onTimeoutPacketCallback(uint64 seq, address packetSenderAddress) external payable returns (bool); + function onPacketResult(uint64 seq, address packetSenderAddress, bytes calldata ack) external payable returns (bool); } diff --git a/x/cronos/events/bindings/src/ICACallback.sol b/x/cronos/events/bindings/src/ICACallback.sol new file mode 100644 index 0000000000..04dd4a6f01 --- /dev/null +++ b/x/cronos/events/bindings/src/ICACallback.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.4; + +contract ICACallback { + // sha256('cronos-evm')[:20] + address constant module_address = 0x89A7EF2F08B1c018D5Cc88836249b84Dd5392905; + uint64 lastAckSeq; + bytes lastAck; + mapping (uint64 => bytes) public acknowledgement; + event OnPacketResult(uint64 seq, bytes ack); + + function onPacketResultCallback(uint64 seq, bytes calldata ack) external payable returns (bool) { + // require(msg.sender == module_address); + lastAckSeq = seq; + lastAck = ack; + acknowledgement[seq] = ack; + emit OnPacketResult(seq, ack); + return true; + } +} diff --git a/x/cronos/keeper/evm.go b/x/cronos/keeper/evm.go index 2108e32ac6..04cb7a6247 100644 --- a/x/cronos/keeper/evm.go +++ b/x/cronos/keeper/evm.go @@ -19,14 +19,9 @@ const DefaultGasCap uint64 = 25000000 // CallEVM execute an evm message from native module func (k Keeper) CallEVM(ctx sdk.Context, to *common.Address, data []byte, value *big.Int) (*ethtypes.Message, *evmtypes.MsgEthereumTxResponse, error) { - return k.CallEVMWithArgs(ctx, to, types.EVMModuleAddress, data, value) -} - -// CallEVMWithArgs execute an evm message with args -func (k Keeper) CallEVMWithArgs(ctx sdk.Context, to *common.Address, from common.Address, data []byte, value *big.Int) (*ethtypes.Message, *evmtypes.MsgEthereumTxResponse, error) { - nonce := k.evmKeeper.GetNonce(ctx, from) + nonce := k.evmKeeper.GetNonce(ctx, types.EVMModuleAddress) msg := ethtypes.NewMessage( - common.Address(from.Bytes()), + types.EVMModuleAddress, to, nonce, value, // amount diff --git a/x/cronos/keeper/keeper.go b/x/cronos/keeper/keeper.go index 4e95e9132e..cdafb91df1 100644 --- a/x/cronos/keeper/keeper.go +++ b/x/cronos/keeper/keeper.go @@ -282,7 +282,7 @@ func (k Keeper) RegisterOrUpdateTokenMapping(ctx sdk.Context, msg *types.MsgUpda return nil } -func (k Keeper) IBCOnAcknowledgementPacketCallback( +func (k Keeper) onPacketResult( ctx sdk.Context, packet channeltypes.Packet, acknowledgement []byte, @@ -295,16 +295,26 @@ func (k Keeper) IBCOnAcknowledgementPacketCallback( return fmt.Errorf("invalid bech32 address: %s, err: %w", packetSenderAddress, err) } sender := common.BytesToAddress(senderAddr.Bytes()) - relayerAddr := common.BytesToAddress(relayer.Bytes()) precompileAddr := common.HexToAddress(contractAddress) - data, err := cronosprecompiles.GetOnAcknowledgementPacketCallback(packet.Sequence, sender, acknowledgement) + data, err := cronosprecompiles.OnPacketResult(packet.Sequence, sender, acknowledgement) if err != nil { return err } - _, _, err = k.CallEVMWithArgs(ctx, &precompileAddr, relayerAddr, data, big.NewInt(0)) + _, _, err = k.CallEVM(ctx, &precompileAddr, data, big.NewInt(0)) return err } +func (k Keeper) IBCOnAcknowledgementPacketCallback( + ctx sdk.Context, + packet channeltypes.Packet, + acknowledgement []byte, + relayer sdk.AccAddress, + contractAddress, + packetSenderAddress string, +) error { + return k.onPacketResult(ctx, packet, acknowledgement, relayer, contractAddress, packetSenderAddress) +} + func (k Keeper) IBCOnTimeoutPacketCallback( ctx sdk.Context, packet channeltypes.Packet, @@ -312,19 +322,7 @@ func (k Keeper) IBCOnTimeoutPacketCallback( contractAddress, packetSenderAddress string, ) error { - senderAddr, err := sdk.AccAddressFromBech32(packetSenderAddress) - if err != nil { - return fmt.Errorf("invalid bech32 address: %s, err: %w", packetSenderAddress, err) - } - sender := common.BytesToAddress(senderAddr.Bytes()) - relayerAddr := common.BytesToAddress(relayer.Bytes()) - precompileAddr := common.HexToAddress(contractAddress) - data, err := cronosprecompiles.GetOnTimeoutPacketCallback(packet.Sequence, sender) - if err != nil { - return err - } - _, _, err = k.CallEVMWithArgs(ctx, &precompileAddr, relayerAddr, data, big.NewInt(0)) - return err + return k.onPacketResult(ctx, packet, []byte{}, relayer, contractAddress, packetSenderAddress) } func (k Keeper) IBCReceivePacketCallback( diff --git a/x/cronos/keeper/precompiles/ica.go b/x/cronos/keeper/precompiles/ica.go index e82bf9c600..8d3685961b 100644 --- a/x/cronos/keeper/precompiles/ica.go +++ b/x/cronos/keeper/precompiles/ica.go @@ -11,6 +11,7 @@ import ( icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" cronosevents "github.com/crypto-org-chain/cronos/v2/x/cronos/events" "github.com/crypto-org-chain/cronos/v2/x/cronos/events/bindings/cosmos/precompile/ica" + "github.com/crypto-org-chain/cronos/v2/x/cronos/events/bindings/cosmos/precompile/icacallback" cronoseventstypes "github.com/crypto-org-chain/cronos/v2/x/cronos/events/types" "github.com/crypto-org-chain/cronos/v2/x/cronos/types" @@ -25,6 +26,7 @@ const ICAContractRequiredGas = 10000 var ( icaABI abi.ABI + icaCallbackABI abi.ABI icaContractAddress = common.BytesToAddress([]byte{102}) ) @@ -32,14 +34,17 @@ func init() { if err := icaABI.UnmarshalJSON([]byte(ica.ICAModuleMetaData.ABI)); err != nil { panic(err) } + if err := icaCallbackABI.UnmarshalJSON([]byte(icacallback.ICACallbackMetaData.ABI)); err != nil { + panic(err) + } } -func GetOnAcknowledgementPacketCallback(args ...interface{}) ([]byte, error) { - return icaABI.Pack("onAcknowledgementPacketCallback", args...) +func OnPacketResult(args ...interface{}) ([]byte, error) { + return icaABI.Pack("onPacketResult", args...) } -func GetOnTimeoutPacketCallback(args ...interface{}) ([]byte, error) { - return icaABI.Pack("onTimeoutPacketCallback", args...) +func onPacketResultCallback(args ...interface{}) ([]byte, error) { + return icaCallbackABI.Pack("onPacketResultCallback", args...) } type IcaContract struct { @@ -171,7 +176,7 @@ func (ic *IcaContract) Run(evm *vm.EVM, contract *vm.Contract, readonly bool) ([ return nil, execErr } return method.Outputs.Pack(seq) - case "onAcknowledgementPacketCallback": + case "onPacketResult": if readonly { return nil, errors.New("the method is not readonly") } @@ -182,34 +187,12 @@ func (ic *IcaContract) Run(evm *vm.EVM, contract *vm.Contract, readonly bool) ([ seq := args[0].(uint64) sender := args[1].(common.Address) acknowledgement := args[2].([]byte) - data, err := GetOnAcknowledgementPacketCallback(seq, sender, acknowledgement) - if err != nil { - return nil, err - } - execErr = stateDB.ExecuteNativeAction(precompileAddr, converter, func(ctx sdk.Context) error { - _, _, err := ic.cronosKeeper.CallEVMWithArgs(ctx, &sender, precompileAddr, data, big.NewInt(0)) - return err - }) - if execErr != nil { - return nil, execErr - } - return method.Outputs.Pack(true) - case "onTimeoutPacketCallback": - if readonly { - return nil, errors.New("the method is not readonly") - } - args, err := method.Inputs.Unpack(contract.Input[4:]) - if err != nil { - return nil, errors.New("fail to unpack input arguments") - } - seq := args[0].(uint64) - sender := args[1].(common.Address) - data, err := GetOnTimeoutPacketCallback(seq, sender) + data, err := onPacketResultCallback(seq, acknowledgement) if err != nil { return nil, err } execErr = stateDB.ExecuteNativeAction(precompileAddr, converter, func(ctx sdk.Context) error { - _, _, err := ic.cronosKeeper.CallEVMWithArgs(ctx, &sender, precompileAddr, data, big.NewInt(0)) + _, _, err := ic.cronosKeeper.CallEVM(ctx, &sender, data, big.NewInt(0)) return err }) if execErr != nil { diff --git a/x/cronos/types/interfaces.go b/x/cronos/types/interfaces.go index 87198bda9b..a46044250f 100644 --- a/x/cronos/types/interfaces.go +++ b/x/cronos/types/interfaces.go @@ -88,5 +88,5 @@ type Icaauthkeeper interface { // CronosKeeper defines the interface for cronos keeper type CronosKeeper interface { - CallEVMWithArgs(ctx sdk.Context, to *common.Address, from common.Address, data []byte, value *big.Int) (*ethtypes.Message, *evmtypes.MsgEthereumTxResponse, error) + CallEVM(ctx sdk.Context, to *common.Address, data []byte, value *big.Int) (*ethtypes.Message, *evmtypes.MsgEthereumTxResponse, error) } From 0960e47d433b8fcdb5240acd79dffd2f0cf8d28c Mon Sep 17 00:00:00 2001 From: mmsqe Date: Wed, 27 Sep 2023 14:06:11 +0800 Subject: [PATCH 15/26] json unmarshal and base64 decode for dapps --- integration_tests/test_ica_precompile.py | 4 +++- x/cronos/keeper/keeper.go | 19 ++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/integration_tests/test_ica_precompile.py b/integration_tests/test_ica_precompile.py index d747f5130d..312759d980 100644 --- a/integration_tests/test_ica_precompile.py +++ b/integration_tests/test_ica_precompile.py @@ -192,6 +192,7 @@ def submit_msgs_ro(func, str): assert tcontract.caller.getLastAckSeq() == seq balance -= amt ack = tcontract.caller.getLastAck() + assert ack == b"\x12&\n$/cosmos.bank.v1beta1.MsgSendResponse", ack assert ack == tcontract.caller.acknowledgement(seq) assert cli_host.balance(ica_address, denom=denom) == balance seq = 2 @@ -209,4 +210,5 @@ def submit_msgs_ro(func, str): balance -= amt1 assert cli_host.balance(ica_address, denom=denom) == balance ack = tcontract.caller.getLastAck() - assert ack == tcontract.caller.acknowledgement(seq) + expected = b"\x12&\n$/cosmos.bank.v1beta1.MsgSendResponse\x12-\n+/cosmos.staking.v1beta1.MsgDelegateResponse" # noqa: E501 + assert ack == expected, ack diff --git a/x/cronos/keeper/keeper.go b/x/cronos/keeper/keeper.go index cdafb91df1..8a2fa297e8 100644 --- a/x/cronos/keeper/keeper.go +++ b/x/cronos/keeper/keeper.go @@ -1,6 +1,7 @@ package keeper import ( + "encoding/json" "fmt" "math/big" "strings" @@ -282,6 +283,14 @@ func (k Keeper) RegisterOrUpdateTokenMapping(ctx sdk.Context, msg *types.MsgUpda return nil } +type IncentivizedAcknowledgement struct { + AppAcknowledgement []byte `json:"app_acknowledgement"` +} + +type PacketResult struct { + Result []byte `json:"result"` +} + func (k Keeper) onPacketResult( ctx sdk.Context, packet channeltypes.Packet, @@ -296,7 +305,15 @@ func (k Keeper) onPacketResult( } sender := common.BytesToAddress(senderAddr.Bytes()) precompileAddr := common.HexToAddress(contractAddress) - data, err := cronosprecompiles.OnPacketResult(packet.Sequence, sender, acknowledgement) + var ack IncentivizedAcknowledgement + if err := json.Unmarshal(acknowledgement, &ack); err != nil { + return err + } + var res PacketResult + if err := json.Unmarshal(ack.AppAcknowledgement, &res); err != nil { + return err + } + data, err := cronosprecompiles.OnPacketResult(packet.Sequence, sender, res.Result) if err != nil { return err } From b16986636bce435629edb23c42aa71802b78dcdb Mon Sep 17 00:00:00 2001 From: mmsqe Date: Wed, 27 Sep 2023 14:06:18 +0800 Subject: [PATCH 16/26] interface only when bind --- scripts/gen-bindings-contracts | 2 +- .../icacallback/i_ica_callback.abigen.go | 201 +++++++++ .../icacallback/icacallback.abigen.go | 389 ------------------ x/cronos/events/bindings/src/ICACallback.sol | 18 +- 4 files changed, 204 insertions(+), 406 deletions(-) create mode 100644 x/cronos/events/bindings/cosmos/precompile/icacallback/i_ica_callback.abigen.go delete mode 100644 x/cronos/events/bindings/cosmos/precompile/icacallback/icacallback.abigen.go diff --git a/scripts/gen-bindings-contracts b/scripts/gen-bindings-contracts index b1f15c7f87..4c55e25c2b 100755 --- a/scripts/gen-bindings-contracts +++ b/scripts/gen-bindings-contracts @@ -11,4 +11,4 @@ abigen --pkg lib --abi build/CosmosTypes.abi --bin build/CosmosTypes.bin --out x abigen --pkg relayer --abi build/IRelayerModule.abi --bin build/IRelayerModule.bin --out x/cronos/events/bindings/cosmos/precompile/relayer/i_relayer_module.abigen.go --type RelayerModule abigen --pkg bank --abi build/IBankModule.abi --bin build/IBankModule.bin --out x/cronos/events/bindings/cosmos/precompile/bank/i_bank_module.abigen.go --type BankModule abigen --pkg ica --abi build/IICAModule.abi --bin build/IICAModule.bin --out x/cronos/events/bindings/cosmos/precompile/ica/i_ica_module.abigen.go --type ICAModule -abigen --pkg icacallback --abi build/ICACallback.abi --bin build/ICACallback.bin --out x/cronos/events/bindings/cosmos/precompile/icacallback/icacallback.abigen.go --type ICACallback +abigen --pkg icacallback --abi build/IICACallback.abi --bin build/IICACallback.bin --out x/cronos/events/bindings/cosmos/precompile/icacallback/i_ica_callback.abigen.go --type ICACallback diff --git a/x/cronos/events/bindings/cosmos/precompile/icacallback/i_ica_callback.abigen.go b/x/cronos/events/bindings/cosmos/precompile/icacallback/i_ica_callback.abigen.go new file mode 100644 index 0000000000..f4ae46fdf6 --- /dev/null +++ b/x/cronos/events/bindings/cosmos/precompile/icacallback/i_ica_callback.abigen.go @@ -0,0 +1,201 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package icacallback + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + +// ICACallbackMetaData contains all meta data concerning the ICACallback contract. +var ICACallbackMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"ack\",\"type\":\"bytes\"}],\"name\":\"onPacketResultCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", +} + +// ICACallbackABI is the input ABI used to generate the binding from. +// Deprecated: Use ICACallbackMetaData.ABI instead. +var ICACallbackABI = ICACallbackMetaData.ABI + +// ICACallback is an auto generated Go binding around an Ethereum contract. +type ICACallback struct { + ICACallbackCaller // Read-only binding to the contract + ICACallbackTransactor // Write-only binding to the contract + ICACallbackFilterer // Log filterer for contract events +} + +// ICACallbackCaller is an auto generated read-only Go binding around an Ethereum contract. +type ICACallbackCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ICACallbackTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ICACallbackTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ICACallbackFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ICACallbackFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ICACallbackSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ICACallbackSession struct { + Contract *ICACallback // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ICACallbackCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ICACallbackCallerSession struct { + Contract *ICACallbackCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ICACallbackTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ICACallbackTransactorSession struct { + Contract *ICACallbackTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ICACallbackRaw is an auto generated low-level Go binding around an Ethereum contract. +type ICACallbackRaw struct { + Contract *ICACallback // Generic contract binding to access the raw methods on +} + +// ICACallbackCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ICACallbackCallerRaw struct { + Contract *ICACallbackCaller // Generic read-only contract binding to access the raw methods on +} + +// ICACallbackTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ICACallbackTransactorRaw struct { + Contract *ICACallbackTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewICACallback creates a new instance of ICACallback, bound to a specific deployed contract. +func NewICACallback(address common.Address, backend bind.ContractBackend) (*ICACallback, error) { + contract, err := bindICACallback(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ICACallback{ICACallbackCaller: ICACallbackCaller{contract: contract}, ICACallbackTransactor: ICACallbackTransactor{contract: contract}, ICACallbackFilterer: ICACallbackFilterer{contract: contract}}, nil +} + +// NewICACallbackCaller creates a new read-only instance of ICACallback, bound to a specific deployed contract. +func NewICACallbackCaller(address common.Address, caller bind.ContractCaller) (*ICACallbackCaller, error) { + contract, err := bindICACallback(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ICACallbackCaller{contract: contract}, nil +} + +// NewICACallbackTransactor creates a new write-only instance of ICACallback, bound to a specific deployed contract. +func NewICACallbackTransactor(address common.Address, transactor bind.ContractTransactor) (*ICACallbackTransactor, error) { + contract, err := bindICACallback(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ICACallbackTransactor{contract: contract}, nil +} + +// NewICACallbackFilterer creates a new log filterer instance of ICACallback, bound to a specific deployed contract. +func NewICACallbackFilterer(address common.Address, filterer bind.ContractFilterer) (*ICACallbackFilterer, error) { + contract, err := bindICACallback(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ICACallbackFilterer{contract: contract}, nil +} + +// bindICACallback binds a generic wrapper to an already deployed contract. +func bindICACallback(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(ICACallbackABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ICACallback *ICACallbackRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ICACallback.Contract.ICACallbackCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ICACallback *ICACallbackRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ICACallback.Contract.ICACallbackTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ICACallback *ICACallbackRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ICACallback.Contract.ICACallbackTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ICACallback *ICACallbackCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ICACallback.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ICACallback *ICACallbackTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ICACallback.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ICACallback *ICACallbackTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ICACallback.Contract.contract.Transact(opts, method, params...) +} + +// OnPacketResultCallback is a paid mutator transaction binding the contract method 0xa6d9a1c2. +// +// Solidity: function onPacketResultCallback(uint64 seq, bytes ack) payable returns(bool) +func (_ICACallback *ICACallbackTransactor) OnPacketResultCallback(opts *bind.TransactOpts, seq uint64, ack []byte) (*types.Transaction, error) { + return _ICACallback.contract.Transact(opts, "onPacketResultCallback", seq, ack) +} + +// OnPacketResultCallback is a paid mutator transaction binding the contract method 0xa6d9a1c2. +// +// Solidity: function onPacketResultCallback(uint64 seq, bytes ack) payable returns(bool) +func (_ICACallback *ICACallbackSession) OnPacketResultCallback(seq uint64, ack []byte) (*types.Transaction, error) { + return _ICACallback.Contract.OnPacketResultCallback(&_ICACallback.TransactOpts, seq, ack) +} + +// OnPacketResultCallback is a paid mutator transaction binding the contract method 0xa6d9a1c2. +// +// Solidity: function onPacketResultCallback(uint64 seq, bytes ack) payable returns(bool) +func (_ICACallback *ICACallbackTransactorSession) OnPacketResultCallback(seq uint64, ack []byte) (*types.Transaction, error) { + return _ICACallback.Contract.OnPacketResultCallback(&_ICACallback.TransactOpts, seq, ack) +} diff --git a/x/cronos/events/bindings/cosmos/precompile/icacallback/icacallback.abigen.go b/x/cronos/events/bindings/cosmos/precompile/icacallback/icacallback.abigen.go deleted file mode 100644 index cdcf8a2481..0000000000 --- a/x/cronos/events/bindings/cosmos/precompile/icacallback/icacallback.abigen.go +++ /dev/null @@ -1,389 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package icacallback - -import ( - "errors" - "math/big" - "strings" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription -) - -// ICACallbackMetaData contains all meta data concerning the ICACallback contract. -var ICACallbackMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"ack\",\"type\":\"bytes\"}],\"name\":\"OnPacketResult\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"acknowledgement\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"ack\",\"type\":\"bytes\"}],\"name\":\"onPacketResultCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", - Bin: "0x608060405234801561000f575f80fd5b506107a98061001d5f395ff3fe608060405260043610610028575f3560e01c8063968bcba31461002c578063a6d9a1c214610068575b5f80fd5b348015610037575f80fd5b50610052600480360381019061004d919061022d565b610098565b60405161005f91906102e2565b60405180910390f35b610082600480360381019061007d9190610363565b610133565b60405161008f91906103da565b60405180910390f35b6002602052805f5260405f205f9150905080546100b490610420565b80601f01602080910402602001604051908101604052809291908181526020018280546100e090610420565b801561012b5780601f106101025761010080835404028352916020019161012b565b820191905f5260205f20905b81548152906001019060200180831161010e57829003601f168201915b505050505081565b5f835f806101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555082826001918261016c92919061062d565b50828260025f8767ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f2091826101a192919061062d565b507f8e0c6cb5698eba8240951fde76f9e06a0844d4285c0e56f4cedf1415d03703fc8484846040516101d593929190610743565b60405180910390a1600190509392505050565b5f80fd5b5f80fd5b5f67ffffffffffffffff82169050919050565b61020c816101f0565b8114610216575f80fd5b50565b5f8135905061022781610203565b92915050565b5f60208284031215610242576102416101e8565b5b5f61024f84828501610219565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561028f578082015181840152602081019050610274565b5f8484015250505050565b5f601f19601f8301169050919050565b5f6102b482610258565b6102be8185610262565b93506102ce818560208601610272565b6102d78161029a565b840191505092915050565b5f6020820190508181035f8301526102fa81846102aa565b905092915050565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261032357610322610302565b5b8235905067ffffffffffffffff8111156103405761033f610306565b5b60208301915083600182028301111561035c5761035b61030a565b5b9250929050565b5f805f6040848603121561037a576103796101e8565b5b5f61038786828701610219565b935050602084013567ffffffffffffffff8111156103a8576103a76101ec565b5b6103b48682870161030e565b92509250509250925092565b5f8115159050919050565b6103d4816103c0565b82525050565b5f6020820190506103ed5f8301846103cb565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061043757607f821691505b60208210810361044a576104496103f3565b5b50919050565b5f82905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026104e37fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826104a8565b6104ed86836104a8565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f61053161052c61052784610505565b61050e565b610505565b9050919050565b5f819050919050565b61054a83610517565b61055e61055682610538565b8484546104b4565b825550505050565b5f90565b610572610566565b61057d818484610541565b505050565b5b818110156105a0576105955f8261056a565b600181019050610583565b5050565b601f8211156105e5576105b681610487565b6105bf84610499565b810160208510156105ce578190505b6105e26105da85610499565b830182610582565b50505b505050565b5f82821c905092915050565b5f6106055f19846008026105ea565b1980831691505092915050565b5f61061d83836105f6565b9150826002028217905092915050565b6106378383610450565b67ffffffffffffffff8111156106505761064f61045a565b5b61065a8254610420565b6106658282856105a4565b5f601f831160018114610692575f8415610680578287013590505b61068a8582610612565b8655506106f1565b601f1984166106a086610487565b5f5b828110156106c7578489013582556001820191506020850194506020810190506106a2565b868310156106e457848901356106e0601f8916826105f6565b8355505b6001600288020188555050505b50505050505050565b610703816101f0565b82525050565b828183375f83830152505050565b5f6107228385610262565b935061072f838584610709565b6107388361029a565b840190509392505050565b5f6040820190506107565f8301866106fa565b8181036020830152610769818486610717565b905094935050505056fea2646970667358221220209d1395f552db65e120063a95265a8c5d0c258b4fabfa7545d202c4e45287bb64736f6c63430008150033", -} - -// ICACallbackABI is the input ABI used to generate the binding from. -// Deprecated: Use ICACallbackMetaData.ABI instead. -var ICACallbackABI = ICACallbackMetaData.ABI - -// ICACallbackBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use ICACallbackMetaData.Bin instead. -var ICACallbackBin = ICACallbackMetaData.Bin - -// DeployICACallback deploys a new Ethereum contract, binding an instance of ICACallback to it. -func DeployICACallback(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ICACallback, error) { - parsed, err := ICACallbackMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } - - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ICACallbackBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &ICACallback{ICACallbackCaller: ICACallbackCaller{contract: contract}, ICACallbackTransactor: ICACallbackTransactor{contract: contract}, ICACallbackFilterer: ICACallbackFilterer{contract: contract}}, nil -} - -// ICACallback is an auto generated Go binding around an Ethereum contract. -type ICACallback struct { - ICACallbackCaller // Read-only binding to the contract - ICACallbackTransactor // Write-only binding to the contract - ICACallbackFilterer // Log filterer for contract events -} - -// ICACallbackCaller is an auto generated read-only Go binding around an Ethereum contract. -type ICACallbackCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// ICACallbackTransactor is an auto generated write-only Go binding around an Ethereum contract. -type ICACallbackTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// ICACallbackFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type ICACallbackFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// ICACallbackSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type ICACallbackSession struct { - Contract *ICACallback // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// ICACallbackCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type ICACallbackCallerSession struct { - Contract *ICACallbackCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// ICACallbackTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type ICACallbackTransactorSession struct { - Contract *ICACallbackTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// ICACallbackRaw is an auto generated low-level Go binding around an Ethereum contract. -type ICACallbackRaw struct { - Contract *ICACallback // Generic contract binding to access the raw methods on -} - -// ICACallbackCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type ICACallbackCallerRaw struct { - Contract *ICACallbackCaller // Generic read-only contract binding to access the raw methods on -} - -// ICACallbackTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type ICACallbackTransactorRaw struct { - Contract *ICACallbackTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewICACallback creates a new instance of ICACallback, bound to a specific deployed contract. -func NewICACallback(address common.Address, backend bind.ContractBackend) (*ICACallback, error) { - contract, err := bindICACallback(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &ICACallback{ICACallbackCaller: ICACallbackCaller{contract: contract}, ICACallbackTransactor: ICACallbackTransactor{contract: contract}, ICACallbackFilterer: ICACallbackFilterer{contract: contract}}, nil -} - -// NewICACallbackCaller creates a new read-only instance of ICACallback, bound to a specific deployed contract. -func NewICACallbackCaller(address common.Address, caller bind.ContractCaller) (*ICACallbackCaller, error) { - contract, err := bindICACallback(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &ICACallbackCaller{contract: contract}, nil -} - -// NewICACallbackTransactor creates a new write-only instance of ICACallback, bound to a specific deployed contract. -func NewICACallbackTransactor(address common.Address, transactor bind.ContractTransactor) (*ICACallbackTransactor, error) { - contract, err := bindICACallback(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &ICACallbackTransactor{contract: contract}, nil -} - -// NewICACallbackFilterer creates a new log filterer instance of ICACallback, bound to a specific deployed contract. -func NewICACallbackFilterer(address common.Address, filterer bind.ContractFilterer) (*ICACallbackFilterer, error) { - contract, err := bindICACallback(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &ICACallbackFilterer{contract: contract}, nil -} - -// bindICACallback binds a generic wrapper to an already deployed contract. -func bindICACallback(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(ICACallbackABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_ICACallback *ICACallbackRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ICACallback.Contract.ICACallbackCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_ICACallback *ICACallbackRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ICACallback.Contract.ICACallbackTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_ICACallback *ICACallbackRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ICACallback.Contract.ICACallbackTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_ICACallback *ICACallbackCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ICACallback.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_ICACallback *ICACallbackTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ICACallback.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_ICACallback *ICACallbackTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ICACallback.Contract.contract.Transact(opts, method, params...) -} - -// Acknowledgement is a free data retrieval call binding the contract method 0x968bcba3. -// -// Solidity: function acknowledgement(uint64 ) view returns(bytes) -func (_ICACallback *ICACallbackCaller) Acknowledgement(opts *bind.CallOpts, arg0 uint64) ([]byte, error) { - var out []interface{} - err := _ICACallback.contract.Call(opts, &out, "acknowledgement", arg0) - - if err != nil { - return *new([]byte), err - } - - out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) - - return out0, err - -} - -// Acknowledgement is a free data retrieval call binding the contract method 0x968bcba3. -// -// Solidity: function acknowledgement(uint64 ) view returns(bytes) -func (_ICACallback *ICACallbackSession) Acknowledgement(arg0 uint64) ([]byte, error) { - return _ICACallback.Contract.Acknowledgement(&_ICACallback.CallOpts, arg0) -} - -// Acknowledgement is a free data retrieval call binding the contract method 0x968bcba3. -// -// Solidity: function acknowledgement(uint64 ) view returns(bytes) -func (_ICACallback *ICACallbackCallerSession) Acknowledgement(arg0 uint64) ([]byte, error) { - return _ICACallback.Contract.Acknowledgement(&_ICACallback.CallOpts, arg0) -} - -// OnPacketResultCallback is a paid mutator transaction binding the contract method 0xa6d9a1c2. -// -// Solidity: function onPacketResultCallback(uint64 seq, bytes ack) payable returns(bool) -func (_ICACallback *ICACallbackTransactor) OnPacketResultCallback(opts *bind.TransactOpts, seq uint64, ack []byte) (*types.Transaction, error) { - return _ICACallback.contract.Transact(opts, "onPacketResultCallback", seq, ack) -} - -// OnPacketResultCallback is a paid mutator transaction binding the contract method 0xa6d9a1c2. -// -// Solidity: function onPacketResultCallback(uint64 seq, bytes ack) payable returns(bool) -func (_ICACallback *ICACallbackSession) OnPacketResultCallback(seq uint64, ack []byte) (*types.Transaction, error) { - return _ICACallback.Contract.OnPacketResultCallback(&_ICACallback.TransactOpts, seq, ack) -} - -// OnPacketResultCallback is a paid mutator transaction binding the contract method 0xa6d9a1c2. -// -// Solidity: function onPacketResultCallback(uint64 seq, bytes ack) payable returns(bool) -func (_ICACallback *ICACallbackTransactorSession) OnPacketResultCallback(seq uint64, ack []byte) (*types.Transaction, error) { - return _ICACallback.Contract.OnPacketResultCallback(&_ICACallback.TransactOpts, seq, ack) -} - -// ICACallbackOnPacketResultIterator is returned from FilterOnPacketResult and is used to iterate over the raw logs and unpacked data for OnPacketResult events raised by the ICACallback contract. -type ICACallbackOnPacketResultIterator struct { - Event *ICACallbackOnPacketResult // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ICACallbackOnPacketResultIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ICACallbackOnPacketResult) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ICACallbackOnPacketResult) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ICACallbackOnPacketResultIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ICACallbackOnPacketResultIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// ICACallbackOnPacketResult represents a OnPacketResult event raised by the ICACallback contract. -type ICACallbackOnPacketResult struct { - Seq uint64 - Ack []byte - Raw types.Log // Blockchain specific contextual infos -} - -// FilterOnPacketResult is a free log retrieval operation binding the contract event 0x8e0c6cb5698eba8240951fde76f9e06a0844d4285c0e56f4cedf1415d03703fc. -// -// Solidity: event OnPacketResult(uint64 seq, bytes ack) -func (_ICACallback *ICACallbackFilterer) FilterOnPacketResult(opts *bind.FilterOpts) (*ICACallbackOnPacketResultIterator, error) { - - logs, sub, err := _ICACallback.contract.FilterLogs(opts, "OnPacketResult") - if err != nil { - return nil, err - } - return &ICACallbackOnPacketResultIterator{contract: _ICACallback.contract, event: "OnPacketResult", logs: logs, sub: sub}, nil -} - -// WatchOnPacketResult is a free log subscription operation binding the contract event 0x8e0c6cb5698eba8240951fde76f9e06a0844d4285c0e56f4cedf1415d03703fc. -// -// Solidity: event OnPacketResult(uint64 seq, bytes ack) -func (_ICACallback *ICACallbackFilterer) WatchOnPacketResult(opts *bind.WatchOpts, sink chan<- *ICACallbackOnPacketResult) (event.Subscription, error) { - - logs, sub, err := _ICACallback.contract.WatchLogs(opts, "OnPacketResult") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ICACallbackOnPacketResult) - if err := _ICACallback.contract.UnpackLog(event, "OnPacketResult", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseOnPacketResult is a log parse operation binding the contract event 0x8e0c6cb5698eba8240951fde76f9e06a0844d4285c0e56f4cedf1415d03703fc. -// -// Solidity: event OnPacketResult(uint64 seq, bytes ack) -func (_ICACallback *ICACallbackFilterer) ParseOnPacketResult(log types.Log) (*ICACallbackOnPacketResult, error) { - event := new(ICACallbackOnPacketResult) - if err := _ICACallback.contract.UnpackLog(event, "OnPacketResult", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} diff --git a/x/cronos/events/bindings/src/ICACallback.sol b/x/cronos/events/bindings/src/ICACallback.sol index 04dd4a6f01..3487ebcd6e 100644 --- a/x/cronos/events/bindings/src/ICACallback.sol +++ b/x/cronos/events/bindings/src/ICACallback.sol @@ -1,20 +1,6 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.4; -contract ICACallback { - // sha256('cronos-evm')[:20] - address constant module_address = 0x89A7EF2F08B1c018D5Cc88836249b84Dd5392905; - uint64 lastAckSeq; - bytes lastAck; - mapping (uint64 => bytes) public acknowledgement; - event OnPacketResult(uint64 seq, bytes ack); - - function onPacketResultCallback(uint64 seq, bytes calldata ack) external payable returns (bool) { - // require(msg.sender == module_address); - lastAckSeq = seq; - lastAck = ack; - acknowledgement[seq] = ack; - emit OnPacketResult(seq, ack); - return true; - } +interface IICACallback { + function onPacketResultCallback(uint64 seq, bytes calldata ack) external payable returns (bool); } From ab87fde824ca003ee31094cff29f2a421c1af502 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Wed, 27 Sep 2023 14:37:30 +0800 Subject: [PATCH 17/26] Apply suggestions from code review --- integration_tests/contracts/contracts/TestICA.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/integration_tests/contracts/contracts/TestICA.sol b/integration_tests/contracts/contracts/TestICA.sol index a1d7797493..ee7359e582 100644 --- a/integration_tests/contracts/contracts/TestICA.sol +++ b/integration_tests/contracts/contracts/TestICA.sol @@ -103,7 +103,8 @@ contract TestICA { } function onPacketResultCallback(uint64 seq, bytes calldata ack) external payable returns (bool) { - // require(msg.sender == module_address); + // To prevent called by arbitrary user + require(msg.sender == module_address); lastAckSeq = seq; lastAck = ack; acknowledgement[seq] = ack; From d9229b405adebe282415a8c7cb0cf9554c97d33e Mon Sep 17 00:00:00 2001 From: mmsqe Date: Wed, 27 Sep 2023 15:29:10 +0800 Subject: [PATCH 18/26] notify directly from middleware --- .../precompile/ica/i_ica_module.abigen.go | 23 +------------- x/cronos/events/bindings/src/ICA.sol | 1 - x/cronos/keeper/keeper.go | 11 ++----- x/cronos/keeper/precompiles/ica.go | 31 ++----------------- 4 files changed, 6 insertions(+), 60 deletions(-) diff --git a/x/cronos/events/bindings/cosmos/precompile/ica/i_ica_module.abigen.go b/x/cronos/events/bindings/cosmos/precompile/ica/i_ica_module.abigen.go index 2709567df8..7f05447446 100644 --- a/x/cronos/events/bindings/cosmos/precompile/ica/i_ica_module.abigen.go +++ b/x/cronos/events/bindings/cosmos/precompile/ica/i_ica_module.abigen.go @@ -30,7 +30,7 @@ var ( // ICAModuleMetaData contains all meta data concerning the ICAModule contract. var ICAModuleMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"}],\"name\":\"SubmitMsgsResult\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"packetSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"ack\",\"type\":\"bytes\"}],\"name\":\"onPacketResult\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"queryAccount\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"}],\"name\":\"registerAccount\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"timeout\",\"type\":\"uint256\"}],\"name\":\"submitMsgs\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"}],\"name\":\"SubmitMsgsResult\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"queryAccount\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"}],\"name\":\"registerAccount\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"connectionID\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"timeout\",\"type\":\"uint256\"}],\"name\":\"submitMsgs\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", } // ICAModuleABI is the input ABI used to generate the binding from. @@ -210,27 +210,6 @@ func (_ICAModule *ICAModuleCallerSession) QueryAccount(connectionID string, addr return _ICAModule.Contract.QueryAccount(&_ICAModule.CallOpts, connectionID, addr) } -// OnPacketResult is a paid mutator transaction binding the contract method 0x15400f96. -// -// Solidity: function onPacketResult(uint64 seq, address packetSenderAddress, bytes ack) payable returns(bool) -func (_ICAModule *ICAModuleTransactor) OnPacketResult(opts *bind.TransactOpts, seq uint64, packetSenderAddress common.Address, ack []byte) (*types.Transaction, error) { - return _ICAModule.contract.Transact(opts, "onPacketResult", seq, packetSenderAddress, ack) -} - -// OnPacketResult is a paid mutator transaction binding the contract method 0x15400f96. -// -// Solidity: function onPacketResult(uint64 seq, address packetSenderAddress, bytes ack) payable returns(bool) -func (_ICAModule *ICAModuleSession) OnPacketResult(seq uint64, packetSenderAddress common.Address, ack []byte) (*types.Transaction, error) { - return _ICAModule.Contract.OnPacketResult(&_ICAModule.TransactOpts, seq, packetSenderAddress, ack) -} - -// OnPacketResult is a paid mutator transaction binding the contract method 0x15400f96. -// -// Solidity: function onPacketResult(uint64 seq, address packetSenderAddress, bytes ack) payable returns(bool) -func (_ICAModule *ICAModuleTransactorSession) OnPacketResult(seq uint64, packetSenderAddress common.Address, ack []byte) (*types.Transaction, error) { - return _ICAModule.Contract.OnPacketResult(&_ICAModule.TransactOpts, seq, packetSenderAddress, ack) -} - // RegisterAccount is a paid mutator transaction binding the contract method 0xddc7b6a7. // // Solidity: function registerAccount(string connectionID, string version) payable returns(bool) diff --git a/x/cronos/events/bindings/src/ICA.sol b/x/cronos/events/bindings/src/ICA.sol index 2b68f92243..31f10530a7 100644 --- a/x/cronos/events/bindings/src/ICA.sol +++ b/x/cronos/events/bindings/src/ICA.sol @@ -6,5 +6,4 @@ interface IICAModule { function registerAccount(string calldata connectionID, string calldata version) external payable returns (bool); function queryAccount(string calldata connectionID, address addr) external view returns (string memory); function submitMsgs(string calldata connectionID, bytes calldata data, uint256 timeout) external payable returns (uint64); - function onPacketResult(uint64 seq, address packetSenderAddress, bytes calldata ack) external payable returns (bool); } diff --git a/x/cronos/keeper/keeper.go b/x/cronos/keeper/keeper.go index 8a2fa297e8..9cf1f46e81 100644 --- a/x/cronos/keeper/keeper.go +++ b/x/cronos/keeper/keeper.go @@ -299,12 +299,7 @@ func (k Keeper) onPacketResult( contractAddress, packetSenderAddress string, ) error { - senderAddr, err := sdk.AccAddressFromBech32(packetSenderAddress) - if err != nil { - return fmt.Errorf("invalid bech32 address: %s, err: %w", packetSenderAddress, err) - } - sender := common.BytesToAddress(senderAddr.Bytes()) - precompileAddr := common.HexToAddress(contractAddress) + contractAddr := common.HexToAddress(contractAddress) var ack IncentivizedAcknowledgement if err := json.Unmarshal(acknowledgement, &ack); err != nil { return err @@ -313,11 +308,11 @@ func (k Keeper) onPacketResult( if err := json.Unmarshal(ack.AppAcknowledgement, &res); err != nil { return err } - data, err := cronosprecompiles.OnPacketResult(packet.Sequence, sender, res.Result) + data, err := cronosprecompiles.OnPacketResultCallback(packet.Sequence, res.Result) if err != nil { return err } - _, _, err = k.CallEVM(ctx, &precompileAddr, data, big.NewInt(0)) + _, _, err = k.CallEVM(ctx, &contractAddr, data, big.NewInt(0)) return err } diff --git a/x/cronos/keeper/precompiles/ica.go b/x/cronos/keeper/precompiles/ica.go index 8d3685961b..838de825fb 100644 --- a/x/cronos/keeper/precompiles/ica.go +++ b/x/cronos/keeper/precompiles/ica.go @@ -39,11 +39,7 @@ func init() { } } -func OnPacketResult(args ...interface{}) ([]byte, error) { - return icaABI.Pack("onPacketResult", args...) -} - -func onPacketResultCallback(args ...interface{}) ([]byte, error) { +func OnPacketResultCallback(args ...interface{}) ([]byte, error) { return icaCallbackABI.Pack("onPacketResultCallback", args...) } @@ -149,7 +145,7 @@ func (ic *IcaContract) Run(evm *vm.EVM, contract *vm.Contract, readonly bool) ([ icaMsgData := icatypes.InterchainAccountPacketData{ Type: icatypes.EXECUTE_TX, Data: data, - Memo: fmt.Sprintf(`{"src_callback": {"address": "%s"}}`, icaContractAddress.String()), + Memo: fmt.Sprintf(`{"src_callback": {"address": "%s"}}`, caller.String()), } timeoutDuration := time.Duration(timeout.Uint64()) seq := uint64(0) @@ -176,29 +172,6 @@ func (ic *IcaContract) Run(evm *vm.EVM, contract *vm.Contract, readonly bool) ([ return nil, execErr } return method.Outputs.Pack(seq) - case "onPacketResult": - if readonly { - return nil, errors.New("the method is not readonly") - } - args, err := method.Inputs.Unpack(contract.Input[4:]) - if err != nil { - return nil, errors.New("fail to unpack input arguments") - } - seq := args[0].(uint64) - sender := args[1].(common.Address) - acknowledgement := args[2].([]byte) - data, err := onPacketResultCallback(seq, acknowledgement) - if err != nil { - return nil, err - } - execErr = stateDB.ExecuteNativeAction(precompileAddr, converter, func(ctx sdk.Context) error { - _, _, err := ic.cronosKeeper.CallEVM(ctx, &sender, data, big.NewInt(0)) - return err - }) - if execErr != nil { - return nil, execErr - } - return method.Outputs.Pack(true) default: return nil, errors.New("unknown method") } From 0da3033c616882c93e0b5e7edc9a9f90403137ce Mon Sep 17 00:00:00 2001 From: mmsqe Date: Wed, 27 Sep 2023 16:37:04 +0800 Subject: [PATCH 19/26] make use of fee type --- x/cronos/keeper/keeper.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/x/cronos/keeper/keeper.go b/x/cronos/keeper/keeper.go index 9cf1f46e81..d71a8aaf99 100644 --- a/x/cronos/keeper/keeper.go +++ b/x/cronos/keeper/keeper.go @@ -17,6 +17,7 @@ import ( storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + ibcfeetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" @@ -283,10 +284,6 @@ func (k Keeper) RegisterOrUpdateTokenMapping(ctx sdk.Context, msg *types.MsgUpda return nil } -type IncentivizedAcknowledgement struct { - AppAcknowledgement []byte `json:"app_acknowledgement"` -} - type PacketResult struct { Result []byte `json:"result"` } @@ -300,7 +297,7 @@ func (k Keeper) onPacketResult( packetSenderAddress string, ) error { contractAddr := common.HexToAddress(contractAddress) - var ack IncentivizedAcknowledgement + var ack ibcfeetypes.IncentivizedAcknowledgement if err := json.Unmarshal(acknowledgement, &ack); err != nil { return err } From aa380c253fee9a94fb4ea9d949e7d88615656126 Mon Sep 17 00:00:00 2001 From: HuangYi Date: Wed, 27 Sep 2023 17:28:14 +0800 Subject: [PATCH 20/26] change ack to bool --- .../contracts/contracts/TestICA.sol | 12 +++++------ .../icacallback/i_ica_callback.abigen.go | 20 +++++++++---------- x/cronos/events/bindings/src/ICACallback.sol | 2 +- x/cronos/keeper/keeper.go | 10 +++------- 4 files changed, 20 insertions(+), 24 deletions(-) diff --git a/integration_tests/contracts/contracts/TestICA.sol b/integration_tests/contracts/contracts/TestICA.sol index ee7359e582..c8c901fab4 100644 --- a/integration_tests/contracts/contracts/TestICA.sol +++ b/integration_tests/contracts/contracts/TestICA.sol @@ -10,9 +10,9 @@ contract TestICA { // sha256('cronos-evm')[:20] address constant module_address = 0x89A7EF2F08B1c018D5Cc88836249b84Dd5392905; uint64 lastAckSeq; - bytes lastAck; - mapping (uint64 => bytes) public acknowledgement; - event OnPacketResult(uint64 seq, bytes ack); + bool lastAck; + mapping (uint64 => bool) public acknowledgement; + event OnPacketResult(uint64 seq, bool ack); function encodeRegister(string memory connectionID, string memory version) internal view returns (bytes memory) { return abi.encodeWithSignature( @@ -98,11 +98,11 @@ contract TestICA { return lastAckSeq; } - function getLastAck() public view returns (bytes memory) { + function getLastAck() public view returns (bool) { return lastAck; } - function onPacketResultCallback(uint64 seq, bytes calldata ack) external payable returns (bool) { + function onPacketResultCallback(uint64 seq, bool ack) external payable returns (bool) { // To prevent called by arbitrary user require(msg.sender == module_address); lastAckSeq = seq; @@ -111,4 +111,4 @@ contract TestICA { emit OnPacketResult(seq, ack); return true; } -} \ No newline at end of file +} diff --git a/x/cronos/events/bindings/cosmos/precompile/icacallback/i_ica_callback.abigen.go b/x/cronos/events/bindings/cosmos/precompile/icacallback/i_ica_callback.abigen.go index f4ae46fdf6..239ef1503a 100644 --- a/x/cronos/events/bindings/cosmos/precompile/icacallback/i_ica_callback.abigen.go +++ b/x/cronos/events/bindings/cosmos/precompile/icacallback/i_ica_callback.abigen.go @@ -30,7 +30,7 @@ var ( // ICACallbackMetaData contains all meta data concerning the ICACallback contract. var ICACallbackMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"ack\",\"type\":\"bytes\"}],\"name\":\"onPacketResultCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", + ABI: "[{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"seq\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"ack\",\"type\":\"bool\"}],\"name\":\"onPacketResultCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", } // ICACallbackABI is the input ABI used to generate the binding from. @@ -179,23 +179,23 @@ func (_ICACallback *ICACallbackTransactorRaw) Transact(opts *bind.TransactOpts, return _ICACallback.Contract.contract.Transact(opts, method, params...) } -// OnPacketResultCallback is a paid mutator transaction binding the contract method 0xa6d9a1c2. +// OnPacketResultCallback is a paid mutator transaction binding the contract method 0x74fb6019. // -// Solidity: function onPacketResultCallback(uint64 seq, bytes ack) payable returns(bool) -func (_ICACallback *ICACallbackTransactor) OnPacketResultCallback(opts *bind.TransactOpts, seq uint64, ack []byte) (*types.Transaction, error) { +// Solidity: function onPacketResultCallback(uint64 seq, bool ack) payable returns(bool) +func (_ICACallback *ICACallbackTransactor) OnPacketResultCallback(opts *bind.TransactOpts, seq uint64, ack bool) (*types.Transaction, error) { return _ICACallback.contract.Transact(opts, "onPacketResultCallback", seq, ack) } -// OnPacketResultCallback is a paid mutator transaction binding the contract method 0xa6d9a1c2. +// OnPacketResultCallback is a paid mutator transaction binding the contract method 0x74fb6019. // -// Solidity: function onPacketResultCallback(uint64 seq, bytes ack) payable returns(bool) -func (_ICACallback *ICACallbackSession) OnPacketResultCallback(seq uint64, ack []byte) (*types.Transaction, error) { +// Solidity: function onPacketResultCallback(uint64 seq, bool ack) payable returns(bool) +func (_ICACallback *ICACallbackSession) OnPacketResultCallback(seq uint64, ack bool) (*types.Transaction, error) { return _ICACallback.Contract.OnPacketResultCallback(&_ICACallback.TransactOpts, seq, ack) } -// OnPacketResultCallback is a paid mutator transaction binding the contract method 0xa6d9a1c2. +// OnPacketResultCallback is a paid mutator transaction binding the contract method 0x74fb6019. // -// Solidity: function onPacketResultCallback(uint64 seq, bytes ack) payable returns(bool) -func (_ICACallback *ICACallbackTransactorSession) OnPacketResultCallback(seq uint64, ack []byte) (*types.Transaction, error) { +// Solidity: function onPacketResultCallback(uint64 seq, bool ack) payable returns(bool) +func (_ICACallback *ICACallbackTransactorSession) OnPacketResultCallback(seq uint64, ack bool) (*types.Transaction, error) { return _ICACallback.Contract.OnPacketResultCallback(&_ICACallback.TransactOpts, seq, ack) } diff --git a/x/cronos/events/bindings/src/ICACallback.sol b/x/cronos/events/bindings/src/ICACallback.sol index 3487ebcd6e..aa3a779513 100644 --- a/x/cronos/events/bindings/src/ICACallback.sol +++ b/x/cronos/events/bindings/src/ICACallback.sol @@ -2,5 +2,5 @@ pragma solidity ^0.8.4; interface IICACallback { - function onPacketResultCallback(uint64 seq, bytes calldata ack) external payable returns (bool); + function onPacketResultCallback(uint64 seq, bool ack) external payable returns (bool); } diff --git a/x/cronos/keeper/keeper.go b/x/cronos/keeper/keeper.go index d71a8aaf99..bcc5726f0b 100644 --- a/x/cronos/keeper/keeper.go +++ b/x/cronos/keeper/keeper.go @@ -284,10 +284,6 @@ func (k Keeper) RegisterOrUpdateTokenMapping(ctx sdk.Context, msg *types.MsgUpda return nil } -type PacketResult struct { - Result []byte `json:"result"` -} - func (k Keeper) onPacketResult( ctx sdk.Context, packet channeltypes.Packet, @@ -301,11 +297,11 @@ func (k Keeper) onPacketResult( if err := json.Unmarshal(acknowledgement, &ack); err != nil { return err } - var res PacketResult - if err := json.Unmarshal(ack.AppAcknowledgement, &res); err != nil { + var res channeltypes.Acknowledgement + if err := k.cdc.UnmarshalJSON(ack.AppAcknowledgement, &res); err != nil { return err } - data, err := cronosprecompiles.OnPacketResultCallback(packet.Sequence, res.Result) + data, err := cronosprecompiles.OnPacketResultCallback(packet.Sequence, res.Success()) if err != nil { return err } From a5a7d8ea14bd372b391d0cdb7c6c326097ac1bf8 Mon Sep 17 00:00:00 2001 From: HuangYi Date: Wed, 27 Sep 2023 17:36:41 +0800 Subject: [PATCH 21/26] fix unmarshal --- x/cronos/keeper/keeper.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/cronos/keeper/keeper.go b/x/cronos/keeper/keeper.go index bcc5726f0b..80197277bf 100644 --- a/x/cronos/keeper/keeper.go +++ b/x/cronos/keeper/keeper.go @@ -1,7 +1,6 @@ package keeper import ( - "encoding/json" "fmt" "math/big" "strings" @@ -293,8 +292,9 @@ func (k Keeper) onPacketResult( packetSenderAddress string, ) error { contractAddr := common.HexToAddress(contractAddress) + // the ack is wrapped by fee middleware var ack ibcfeetypes.IncentivizedAcknowledgement - if err := json.Unmarshal(acknowledgement, &ack); err != nil { + if err := k.cdc.UnmarshalJSON(acknowledgement, &ack); err != nil { return err } var res channeltypes.Acknowledgement From 63ca95491a4fcfb63dbafd4e110400c45bee7ede Mon Sep 17 00:00:00 2001 From: HuangYi Date: Wed, 27 Sep 2023 17:42:06 +0800 Subject: [PATCH 22/26] timeout should be treated as failure --- x/cronos/keeper/keeper.go | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/x/cronos/keeper/keeper.go b/x/cronos/keeper/keeper.go index 80197277bf..e2f743af91 100644 --- a/x/cronos/keeper/keeper.go +++ b/x/cronos/keeper/keeper.go @@ -286,22 +286,14 @@ func (k Keeper) RegisterOrUpdateTokenMapping(ctx sdk.Context, msg *types.MsgUpda func (k Keeper) onPacketResult( ctx sdk.Context, packet channeltypes.Packet, - acknowledgement []byte, + acknowledgement bool, relayer sdk.AccAddress, contractAddress, packetSenderAddress string, ) error { contractAddr := common.HexToAddress(contractAddress) - // the ack is wrapped by fee middleware - var ack ibcfeetypes.IncentivizedAcknowledgement - if err := k.cdc.UnmarshalJSON(acknowledgement, &ack); err != nil { - return err - } - var res channeltypes.Acknowledgement - if err := k.cdc.UnmarshalJSON(ack.AppAcknowledgement, &res); err != nil { - return err - } - data, err := cronosprecompiles.OnPacketResultCallback(packet.Sequence, res.Success()) + + data, err := cronosprecompiles.OnPacketResultCallback(packet.Sequence, acknowledgement) if err != nil { return err } @@ -317,7 +309,16 @@ func (k Keeper) IBCOnAcknowledgementPacketCallback( contractAddress, packetSenderAddress string, ) error { - return k.onPacketResult(ctx, packet, acknowledgement, relayer, contractAddress, packetSenderAddress) + // the ack is wrapped by fee middleware + var ack ibcfeetypes.IncentivizedAcknowledgement + if err := k.cdc.UnmarshalJSON(acknowledgement, &ack); err != nil { + return err + } + var res channeltypes.Acknowledgement + if err := k.cdc.UnmarshalJSON(ack.AppAcknowledgement, &res); err != nil { + return err + } + return k.onPacketResult(ctx, packet, res.Success(), relayer, contractAddress, packetSenderAddress) } func (k Keeper) IBCOnTimeoutPacketCallback( @@ -327,7 +328,7 @@ func (k Keeper) IBCOnTimeoutPacketCallback( contractAddress, packetSenderAddress string, ) error { - return k.onPacketResult(ctx, packet, []byte{}, relayer, contractAddress, packetSenderAddress) + return k.onPacketResult(ctx, packet, false, relayer, contractAddress, packetSenderAddress) } func (k Keeper) IBCReceivePacketCallback( From fa936ce7439bb1ec439b329eab5c5d5fcb834612 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Wed, 27 Sep 2023 17:43:52 +0800 Subject: [PATCH 23/26] add change doc --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e515016f88..a7b1ea865d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ - [cronos#1163](https://github.com/crypto-org-chain/cronos/pull/1163) Support stateful precompiled contract for ica. - [cronos#837](https://github.com/crypto-org-chain/cronos/pull/837) Support stateful precompiled contract for bank. - [cronos#1184](https://github.com/crypto-org-chain/cronos/pull/1184) Update ibc-go to `v7.3.1`. +- [cronos#1185](https://github.com/crypto-org-chain/cronos/pull/1185) Support ibc callback. ### Bug Fixes From b64cdc71d9a76698ac93a4863116ccd23fb91e0a Mon Sep 17 00:00:00 2001 From: HuangYi Date: Wed, 27 Sep 2023 17:46:26 +0800 Subject: [PATCH 24/26] fix gas limit --- app/app.go | 4 +++- x/cronos/keeper/evm.go | 8 ++++---- x/cronos/keeper/keeper.go | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/app/app.go b/app/app.go index fd21a79968..bb31601a37 100644 --- a/app/app.go +++ b/app/app.go @@ -5,6 +5,7 @@ import ( "fmt" "io" "io/fs" + "math" "net/http" "os" "path/filepath" @@ -661,7 +662,8 @@ func New( icaControllerStack = ibcfee.NewIBCMiddleware(icaControllerStack, app.IBCFeeKeeper) // Since the callbacks middleware itself is an ics4wrapper, it needs to be passed to the ica controller keeper app.ICAControllerKeeper.WithICS4Wrapper(icaControllerStack.(porttypes.Middleware)) - icaControllerStack = ibccallbacks.NewIBCMiddleware(icaControllerStack, app.IBCFeeKeeper, app.CronosKeeper, cronostypes.MaxCallbackGasDefaultValue) + // we don't limit gas usage here, because the cronos keeper will use network parameter to control it. + icaControllerStack = ibccallbacks.NewIBCMiddleware(icaControllerStack, app.IBCFeeKeeper, app.CronosKeeper, math.MaxUint64) // Create static IBC router, add transfer route, then set and seal it ibcRouter := porttypes.NewRouter() diff --git a/x/cronos/keeper/evm.go b/x/cronos/keeper/evm.go index 04cb7a6247..3b17abb73b 100644 --- a/x/cronos/keeper/evm.go +++ b/x/cronos/keeper/evm.go @@ -18,14 +18,14 @@ import ( const DefaultGasCap uint64 = 25000000 // CallEVM execute an evm message from native module -func (k Keeper) CallEVM(ctx sdk.Context, to *common.Address, data []byte, value *big.Int) (*ethtypes.Message, *evmtypes.MsgEthereumTxResponse, error) { +func (k Keeper) CallEVM(ctx sdk.Context, to *common.Address, data []byte, value *big.Int, gasLimit uint64) (*ethtypes.Message, *evmtypes.MsgEthereumTxResponse, error) { nonce := k.evmKeeper.GetNonce(ctx, types.EVMModuleAddress) msg := ethtypes.NewMessage( types.EVMModuleAddress, to, nonce, value, // amount - DefaultGasCap, + gasLimit, big.NewInt(0), nil, nil, // gasPrice data, nil, // accessList @@ -44,7 +44,7 @@ func (k Keeper) CallModuleCRC21(ctx sdk.Context, contract common.Address, method if err != nil { return nil, err } - _, res, err := k.CallEVM(ctx, &contract, data, big.NewInt(0)) + _, res, err := k.CallEVM(ctx, &contract, data, big.NewInt(0), DefaultGasCap) if err != nil { return nil, err } @@ -63,7 +63,7 @@ func (k Keeper) DeployModuleCRC21(ctx sdk.Context, denom string) (common.Address data := types.ModuleCRC21Contract.Bin data = append(data, ctor...) - msg, res, err := k.CallEVM(ctx, nil, data, big.NewInt(0)) + msg, res, err := k.CallEVM(ctx, nil, data, big.NewInt(0), DefaultGasCap) if err != nil { return common.Address{}, err } diff --git a/x/cronos/keeper/keeper.go b/x/cronos/keeper/keeper.go index e2f743af91..8a013756a4 100644 --- a/x/cronos/keeper/keeper.go +++ b/x/cronos/keeper/keeper.go @@ -297,7 +297,8 @@ func (k Keeper) onPacketResult( if err != nil { return err } - _, _, err = k.CallEVM(ctx, &contractAddr, data, big.NewInt(0)) + gasLimit := k.GetParams(ctx).MaxCallbackGas + _, _, err = k.CallEVM(ctx, &contractAddr, data, big.NewInt(0), gasLimit) return err } From 067ac47888d8586dcbaa81182e82c31564da51f2 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Wed, 27 Sep 2023 18:00:48 +0800 Subject: [PATCH 25/26] fix interface --- x/cronos/types/interfaces.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/cronos/types/interfaces.go b/x/cronos/types/interfaces.go index a46044250f..37beaf900d 100644 --- a/x/cronos/types/interfaces.go +++ b/x/cronos/types/interfaces.go @@ -88,5 +88,5 @@ type Icaauthkeeper interface { // CronosKeeper defines the interface for cronos keeper type CronosKeeper interface { - CallEVM(ctx sdk.Context, to *common.Address, data []byte, value *big.Int) (*ethtypes.Message, *evmtypes.MsgEthereumTxResponse, error) + CallEVM(ctx sdk.Context, to *common.Address, data []byte, value *big.Int, gasLimit uint64) (*ethtypes.Message, *evmtypes.MsgEthereumTxResponse, error) } From 947abe0dd4a98b1ad4609a474032da0c140c3473 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Wed, 27 Sep 2023 18:01:02 +0800 Subject: [PATCH 26/26] fix test --- integration_tests/test_ica_precompile.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/integration_tests/test_ica_precompile.py b/integration_tests/test_ica_precompile.py index 312759d980..51dab1cd8b 100644 --- a/integration_tests/test_ica_precompile.py +++ b/integration_tests/test_ica_precompile.py @@ -192,8 +192,7 @@ def submit_msgs_ro(func, str): assert tcontract.caller.getLastAckSeq() == seq balance -= amt ack = tcontract.caller.getLastAck() - assert ack == b"\x12&\n$/cosmos.bank.v1beta1.MsgSendResponse", ack - assert ack == tcontract.caller.acknowledgement(seq) + assert ack == tcontract.caller.acknowledgement(seq), ack assert cli_host.balance(ica_address, denom=denom) == balance seq = 2 str = submit_msgs( @@ -209,6 +208,4 @@ def submit_msgs_ro(func, str): balance -= amt balance -= amt1 assert cli_host.balance(ica_address, denom=denom) == balance - ack = tcontract.caller.getLastAck() - expected = b"\x12&\n$/cosmos.bank.v1beta1.MsgSendResponse\x12-\n+/cosmos.staking.v1beta1.MsgDelegateResponse" # noqa: E501 - assert ack == expected, ack + assert ack == tcontract.caller.acknowledgement(seq), ack