From 53ac3f7b69b26e10010b85aca300a89eb4f8a4c2 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Fri, 8 Sep 2023 12:13:18 +0800 Subject: [PATCH] use ibc-apps upstream --- app/app.go | 11 +- go.mod | 11 +- go.sum | 10 +- x/ibchooks/.cargo/config | 2 - x/ibchooks/README.md | 185 --------------- x/ibchooks/client/cli/query.go | 77 ------ x/ibchooks/hooks.go | 146 ------------ x/ibchooks/ibc_module.go | 262 -------------------- x/ibchooks/ics4_middleware.go | 85 ------- x/ibchooks/keeper/keeper.go | 62 ----- x/ibchooks/sdkmodule.go | 126 ---------- x/ibchooks/types/errors.go | 15 -- x/ibchooks/types/keys.go | 8 - x/ibchooks/wasm_hook.go | 421 --------------------------------- 14 files changed, 17 insertions(+), 1404 deletions(-) delete mode 100644 x/ibchooks/.cargo/config delete mode 100644 x/ibchooks/README.md delete mode 100644 x/ibchooks/client/cli/query.go delete mode 100644 x/ibchooks/hooks.go delete mode 100644 x/ibchooks/ibc_module.go delete mode 100644 x/ibchooks/ics4_middleware.go delete mode 100644 x/ibchooks/keeper/keeper.go delete mode 100644 x/ibchooks/sdkmodule.go delete mode 100644 x/ibchooks/types/errors.go delete mode 100644 x/ibchooks/types/keys.go delete mode 100644 x/ibchooks/wasm_hook.go diff --git a/app/app.go b/app/app.go index 4d994130..a19ba02c 100644 --- a/app/app.go +++ b/app/app.go @@ -18,6 +18,9 @@ import ( "github.com/CosmWasm/wasmd/x/wasm" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + ibchooks "github.com/cosmos/ibc-apps/modules/ibc-hooks/v7" + ibchookskeeper "github.com/cosmos/ibc-apps/modules/ibc-hooks/v7/keeper" + ibchookstypes "github.com/cosmos/ibc-apps/modules/ibc-hooks/v7/types" ica "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts" icacontrollerkeeper "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/keeper" icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" @@ -142,9 +145,6 @@ import ( // Upgrade Handler upgrades "github.com/White-Whale-Defi-Platform/migaloo-chain/v3/app/upgrades" v2 "github.com/White-Whale-Defi-Platform/migaloo-chain/v3/app/upgrades/v2" - ibchooks "github.com/White-Whale-Defi-Platform/migaloo-chain/v3/x/ibchooks" - ibchookskeeper "github.com/White-Whale-Defi-Platform/migaloo-chain/v3/x/ibchooks/keeper" - ibchookstypes "github.com/White-Whale-Defi-Platform/migaloo-chain/v3/x/ibchooks/types" ) const ( @@ -533,7 +533,7 @@ func NewMigalooApp( app.IBCHooksKeeper = &hooksKeeper migalooPrefix := sdk.GetConfig().GetBech32AccountAddrPrefix() - wasmHooks := ibchooks.NewWasmHooks(app.IBCHooksKeeper, app.ContractKeeper, &app.WasmKeeper, migalooPrefix) // The contract keeper needs to be set later // The contract keeper needs to be set later + wasmHooks := ibchooks.NewWasmHooks(app.IBCHooksKeeper, &app.WasmKeeper, migalooPrefix) // The contract keeper needs to be set later // The contract keeper needs to be set later app.Ics20WasmHooks = &wasmHooks app.HooksICS4Wrapper = ibchooks.NewICS4Middleware( app.IBCKeeper.ChannelKeeper, @@ -970,8 +970,7 @@ func NewMigalooApp( app.ScopedICQKeeper = scopedICQKeeper // set the contract keeper for the Ics20WasmHooks - app.ContractKeeper = wasmkeeper.NewDefaultPermissionKeeper(app.WasmKeeper) - app.Ics20WasmHooks.ContractKeeper = app.ContractKeeper + app.Ics20WasmHooks.ContractKeeper = &app.WasmKeeper if loadLatest { if err := app.LoadLatestVersion(); err != nil { diff --git a/go.mod b/go.mod index c9638794..90093696 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/cometbft/cometbft v0.37.2 github.com/cometbft/cometbft-db v0.8.0 github.com/cosmos/cosmos-sdk v0.47.3 + github.com/cosmos/ibc-apps/modules/ibc-hooks/v7 v7.0.0-20230906222317-d88d4028e5c9 github.com/cosmos/ibc-go/v7 v7.2.0 github.com/gorilla/mux v1.8.0 github.com/prometheus/client_golang v1.16.0 @@ -39,13 +40,13 @@ require ( cloud.google.com/go/iam v0.13.0 // indirect cloud.google.com/go/storage v1.29.0 // indirect cosmossdk.io/api v0.3.1 // indirect - cosmossdk.io/core v0.5.1 // indirect + cosmossdk.io/core v0.6.1 // indirect cosmossdk.io/depinject v1.0.0-alpha.3 // indirect - cosmossdk.io/errors v1.0.0-beta.7 + cosmossdk.io/errors v1.0.0-beta.7 // indirect cosmossdk.io/tools/rosetta v0.2.1 filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect - github.com/99designs/keyring v1.2.1 // indirect + github.com/99designs/keyring v1.2.2 // indirect github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect github.com/CosmWasm/wasmvm v1.2.3 // indirect github.com/armon/go-metrics v0.4.1 // indirect @@ -62,7 +63,7 @@ require ( github.com/coinbase/rosetta-sdk-go/types v1.0.0 // indirect github.com/confio/ics23/go v0.9.0 // indirect github.com/cosmos/btcutil v1.0.5 // indirect - github.com/cosmos/cosmos-proto v1.0.0-beta.2 // indirect + github.com/cosmos/cosmos-proto v1.0.0-beta.3 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gogogateway v1.2.0 // indirect github.com/cosmos/gogoproto v1.4.10 // indirect @@ -103,7 +104,7 @@ require ( github.com/gorilla/handlers v1.5.1 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect - github.com/grpc-ecosystem/grpc-gateway v1.16.0 + github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/gtank/merlin v0.1.1 // indirect github.com/gtank/ristretto255 v0.1.2 // indirect diff --git a/go.sum b/go.sum index e80098c0..2c31dbfc 100644 --- a/go.sum +++ b/go.sum @@ -396,8 +396,8 @@ cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vf cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= cosmossdk.io/api v0.3.1 h1:NNiOclKRR0AOlO4KIqeaG6PS6kswOMhHD0ir0SscNXE= cosmossdk.io/api v0.3.1/go.mod h1:DfHfMkiNA2Uhy8fj0JJlOCYOBp4eWUUJ1te5zBGNyIw= -cosmossdk.io/core v0.5.1 h1:vQVtFrIYOQJDV3f7rw4pjjVqc1id4+mE0L9hHP66pyI= -cosmossdk.io/core v0.5.1/go.mod h1:KZtwHCLjcFuo0nmDc24Xy6CRNEL9Vl/MeimQ2aC7NLE= +cosmossdk.io/core v0.6.1 h1:OBy7TI2W+/gyn2z40vVvruK3di+cAluinA6cybFbE7s= +cosmossdk.io/core v0.6.1/go.mod h1:g3MMBCBXtxbDWBURDVnJE7XML4BG5qENhs0gzkcpuFA= cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw= cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU= cosmossdk.io/errors v1.0.0-beta.7 h1:gypHW76pTQGVnHKo6QBkb4yFOJjC+sUGRc5Al3Odj1w= @@ -538,8 +538,8 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= -github.com/cosmos/cosmos-proto v1.0.0-beta.2 h1:X3OKvWgK9Gsejo0F1qs5l8Qn6xJV/AzgIWR2wZ8Nua8= -github.com/cosmos/cosmos-proto v1.0.0-beta.2/go.mod h1:+XRCLJ14pr5HFEHIUcn51IKXD1Fy3rkEQqt4WqmN4V0= +github.com/cosmos/cosmos-proto v1.0.0-beta.3 h1:VitvZ1lPORTVxkmF2fAp3IiA61xVwArQYKXTdEcpW6o= +github.com/cosmos/cosmos-proto v1.0.0-beta.3/go.mod h1:t8IASdLaAq+bbHbjq4p960BvcTqtwuAxid3b/2rOD6I= github.com/cosmos/cosmos-sdk v0.47.3 h1:r0hGmZoAzP2D+MaPaFGHwAaTdFQq3pNpHaUp1BsffbM= github.com/cosmos/cosmos-sdk v0.47.3/go.mod h1:c4OfLdAykA9zsj1CqrxBRqXzVz48I++JSvIMPSPcEmk= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= @@ -551,6 +551,8 @@ github.com/cosmos/gogoproto v1.4.8 h1:BrHKc6WFZt8+jRV71vKSQE+JrfF+JAnzrKo2VP7wIZ github.com/cosmos/gogoproto v1.4.8/go.mod h1:hnb0DIEWTv+wdNzNcqus5xCQXq5+CXauq1FJuurRfVY= github.com/cosmos/iavl v0.20.0 h1:fTVznVlepH0KK8NyKq8w+U7c2L6jofa27aFX6YGlm38= github.com/cosmos/iavl v0.20.0/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= +github.com/cosmos/ibc-apps/modules/ibc-hooks/v7 v7.0.0-20230906222317-d88d4028e5c9 h1:Ji2ch8iw8qLh0xG/NY+RVsQ0tqiy+tViQxiaOHKpsw0= +github.com/cosmos/ibc-apps/modules/ibc-hooks/v7 v7.0.0-20230906222317-d88d4028e5c9/go.mod h1:JwHFbo1oX/ht4fPpnPvmhZr+dCkYK1Vihw+vZE9umR4= github.com/cosmos/ibc-go/v7 v7.2.0 h1:dx0DLUl7rxdyZ8NiT6UsrbzKOJx/w7s+BOaewFRH6cg= github.com/cosmos/ibc-go/v7 v7.2.0/go.mod h1:OOcjKIRku/j1Xs1RgKK0yvKRrJ5iFuZYMetR1n3yMlc= github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM= diff --git a/x/ibchooks/.cargo/config b/x/ibchooks/.cargo/config deleted file mode 100644 index 946af0fa..00000000 --- a/x/ibchooks/.cargo/config +++ /dev/null @@ -1,2 +0,0 @@ -[alias] -wasm = "build --release --lib --target wasm32-unknown-unknown" diff --git a/x/ibchooks/README.md b/x/ibchooks/README.md deleted file mode 100644 index 1955c925..00000000 --- a/x/ibchooks/README.md +++ /dev/null @@ -1,185 +0,0 @@ -# IBC-hooks - -## Wasm Hooks - -The wasm hook is an IBC middleware which is used to allow ICS-20 token transfers to initiate contract calls. -This allows cross-chain contract calls, that involve token movement. -This is useful for a variety of usecases. -One of primary importance is cross-chain swaps, which is an extremely powerful primitive. - -The mechanism enabling this is a `memo` field on every ICS20 transfer packet as of [IBC v3.4.0](https://medium.com/the-interchain-foundation/moving-beyond-simple-token-transfers-d42b2b1dc29b). -Wasm hooks is an IBC middleware that parses an ICS20 transfer, and if the `memo` field is of a particular form, executes a wasm contract call. We now detail the `memo` format for `wasm` contract calls, and the execution guarantees provided. - -### Cosmwasm Contract Execution Format - -Before we dive into the IBC metadata format, we show the cosmwasm execute message format, so the reader has a sense of what are the fields we need to be setting in. -The cosmwasm `MsgExecuteContract` is defined [here](https://github.com/CosmWasm/wasmd/blob/4fe2fbc8f322efdaf187e2e5c99ce32fd1df06f0/x/wasm/types/tx.pb.go#L340-L349 -) as the following type: - -```go -type MsgExecuteContract struct { - // Sender is the that actor that signed the messages - Sender string - // Contract is the address of the smart contract - Contract string - // Msg json encoded message to be passed to the contract - Msg RawContractMessage - // Funds coins that are transferred to the contract on execution - Funds sdk.Coins -} -``` - -So we detail where we want to get each of these fields from: - -* Sender: We cannot trust the sender of an IBC packet, the counterparty chain has full ability to lie about it. -We cannot risk this sender being confused for a particular user or module address on Osmosis. -So we replace the sender with an account to represent the sender prefixed by the channel and a wasm module prefix. -This is done by setting the sender to `Bech32(Hash("ibc-wasm-hook-intermediary" || channelID || sender))`, where the channelId is the channel id on the local chain. -* Contract: This field should be directly obtained from the ICS-20 packet metadata -* Msg: This field should be directly obtained from the ICS-20 packet metadata. -* Funds: This field is set to the amount of funds being sent over in the ICS 20 packet. One detail is that the denom in the packet is the counterparty chains representation of the denom, so we have to translate it to Osmosis' representation. - -So our constructed cosmwasm message that we execute will look like: - -```go -msg := MsgExecuteContract{ - // Sender is the that actor that signed the messages - Sender: "osmo1-hash-of-channel-and-sender", - // Contract is the address of the smart contract - Contract: packet.data.memo["wasm"]["ContractAddress"], - // Msg json encoded message to be passed to the contract - Msg: packet.data.memo["wasm"]["Msg"], - // Funds coins that are transferred to the contract on execution - Funds: sdk.NewCoin{Denom: ibc.ConvertSenderDenomToLocalDenom(packet.data.Denom), Amount: packet.data.Amount} -``` - -### ICS20 packet structure - -So given the details above, we propogate the implied ICS20 packet data structure. -ICS20 is JSON native, so we use JSON for the memo format. - -```json -{ - //... other ibc fields that we don't care about - "data":{ - "denom": "denom on counterparty chain (e.g. uatom)", // will be transformed to the local denom (ibc/...) - "amount": "1000", - "sender": "addr on counterparty chain", // will be transformed - "receiver": "contract addr or blank", - "memo": { - "wasm": { - "contract": "osmo1contractAddr", - "msg": { - "raw_message_fields": "raw_message_data", - } - } - } - } -} -``` - -An ICS20 packet is formatted correctly for wasmhooks iff the following all hold: - -* `memo` is not blank -* `memo` is valid JSON -* `memo` has at least one key, with value `"wasm"` -* `memo["wasm"]` has exactly two entries, `"contract"` and `"msg"` -* `memo["wasm"]["msg"]` is a valid JSON object -* `receiver == "" || receiver == memo["wasm"]["contract"]` - -We consider an ICS20 packet as directed towards wasmhooks iff all of the following hold: - -* `memo` is not blank -* `memo` is valid JSON -* `memo` has at least one key, with name `"wasm"` - -If an ICS20 packet is not directed towards wasmhooks, wasmhooks doesn't do anything. -If an ICS20 packet is directed towards wasmhooks, and is formated incorrectly, then wasmhooks returns an error. - -### Execution flow - -Pre wasm hooks: - -* Ensure the incoming IBC packet is cryptogaphically valid -* Ensure the incoming IBC packet is not timed out. - -In Wasm hooks, pre packet execution: - -* Ensure the packet is correctly formatted (as defined above) -* Edit the receiver to be the hardcoded IBC module account - -In wasm hooks, post packet execution: - -* Construct wasm message as defined before -* Execute wasm message -* if wasm message has error, return ErrAck -* otherwise continue through middleware - -## Ack callbacks - -A contract that sends an IBC transfer, may need to listen for the ACK from that packet. To allow -contracts to listen on the ack of specific packets, we provide Ack callbacks. - -### Design - -The sender of an IBC transfer packet may specify a callback for when the ack of that packet is received in the memo -field of the transfer packet. - -Crucially, _only_ the IBC packet sender can set the callback. - -### Use case - -The crosschain swaps implementation sends an IBC transfer. If the transfer were to fail, we want to allow the sender -to be able to retrieve their funds (which would otherwise be stuck in the contract). To do this, we allow users to -retrieve the funds after the timeout has passed, but without the ack information, we cannot guarantee that the send -hasn't failed (i.e.: returned an error ack notifying that the receiving change didn't accept it) - -### Implementation - -#### Callback information in memo - -For the callback to be processed, the transfer packet's memo should contain the following in its JSON: - -`{"ibc_callback": "osmo1contractAddr"}` - -The wasm hooks will keep the mapping from the packet's channel and sequence to the contract in storage. When an ack is -received, it will notify the specified contract via a sudo message. - -#### Interface for receiving the Acks and Timeouts - -The contract that awaits the callback should implement the following interface for a sudo message: - -```rust -#[cw_serde] -pub enum IBCLifecycleComplete { - #[serde(rename = "ibc_ack")] - IBCAck { - /// The source channel (osmosis side) of the IBC packet - channel: String, - /// The sequence number that the packet was sent with - sequence: u64, - /// String encoded version of the ack as seen by OnAcknowledgementPacket(..) - ack: String, - /// Weather an ack is a success of failure according to the transfer spec - success: bool, - }, - #[serde(rename = "ibc_timeout")] - IBCTimeout { - /// The source channel (osmosis side) of the IBC packet - channel: String, - /// The sequence number that the packet was sent with - sequence: u64, - }, -} - -/// Message type for `sudo` entry_point -#[cw_serde] -pub enum SudoMsg { - #[serde(rename = "ibc_lifecycle_complete")] - IBCLifecycleComplete(IBCLifecycleComplete), -} -``` - -# Testing strategy - -See go tests. \ No newline at end of file diff --git a/x/ibchooks/client/cli/query.go b/x/ibchooks/client/cli/query.go deleted file mode 100644 index 832e63ce..00000000 --- a/x/ibchooks/client/cli/query.go +++ /dev/null @@ -1,77 +0,0 @@ -package cli - -import ( - "fmt" - "strings" - - "github.com/spf13/cobra" - - "github.com/cosmos/cosmos-sdk/client/flags" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/version" - - "github.com/White-Whale-Defi-Platform/migaloo-chain/v3/x/ibchooks/keeper" - "github.com/White-Whale-Defi-Platform/migaloo-chain/v3/x/ibchooks/types" -) - -func indexRunCmd(cmd *cobra.Command, _ []string) error { - usageTemplate := `Usage:{{if .HasAvailableSubCommands}} - {{.CommandPath}} [command]{{end}} - -{{if .HasAvailableSubCommands}}Available Commands:{{range .Commands}}{{if .IsAvailableCommand}} - {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}} - -Use "{{.CommandPath}} [command] --help" for more information about a command.{{end}} -` - cmd.SetUsageTemplate(usageTemplate) - return cmd.Help() -} - -// GetQueryCmd returns the cli query commands for this module. -func GetQueryCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: types.ModuleName, - Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName), - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - RunE: indexRunCmd, - } - - cmd.AddCommand( - GetCmdWasmSender(), - ) - return cmd -} - -// GetCmdPoolParams return pool params. -func GetCmdWasmSender() *cobra.Command { - cmd := &cobra.Command{ - Use: "wasm-sender ", - Short: "Generate the local address for a wasm hooks sender", - Long: strings.TrimSpace( - fmt.Sprintf(`Generate the local address for a wasm hooks sender. -Example: -$ %s query ibc-hooks wasm-hooks-sender channel-42 juno12smx2wdlyttvyzvzg54y2vnqwq2qjatezqwqxu -`, - version.AppName, - ), - ), - Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - channelID := args[0] - originalSender := args[1] - // ToDo: Make this flexible as an arg - prefix := sdk.GetConfig().GetBech32AccountAddrPrefix() - senderBech32, err := keeper.DeriveIntermediateSender(channelID, originalSender, prefix) - if err != nil { - return err - } - fmt.Println(senderBech32) - return nil - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd -} diff --git a/x/ibchooks/hooks.go b/x/ibchooks/hooks.go deleted file mode 100644 index 525a3d21..00000000 --- a/x/ibchooks/hooks.go +++ /dev/null @@ -1,146 +0,0 @@ -package ibchooks - -import ( - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - // ibc-go - channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" - - // external libraries - sdk "github.com/cosmos/cosmos-sdk/types" - capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" -) - -type Hooks interface{} - -type OnChanOpenInitOverrideHooks interface { - OnChanOpenInitOverride(im IBCMiddleware, ctx sdk.Context, order channeltypes.Order, connectionHops []string, portID string, channelID string, channelCap *capabilitytypes.Capability, counterparty channeltypes.Counterparty, version string) (string, error) -} -type OnChanOpenInitBeforeHooks interface { - OnChanOpenInitBeforeHook(ctx sdk.Context, order channeltypes.Order, connectionHops []string, portID string, channelID string, channelCap *capabilitytypes.Capability, counterparty channeltypes.Counterparty, version string) -} -type OnChanOpenInitAfterHooks interface { - OnChanOpenInitAfterHook(ctx sdk.Context, order channeltypes.Order, connectionHops []string, portID string, channelID string, channelCap *capabilitytypes.Capability, counterparty channeltypes.Counterparty, version string, finalVersion string, err error) -} - -// OnChanOpenTry Hooks -type OnChanOpenTryOverrideHooks interface { - OnChanOpenTryOverride(im IBCMiddleware, ctx sdk.Context, order channeltypes.Order, connectionHops []string, portID, channelID string, channelCap *capabilitytypes.Capability, counterparty channeltypes.Counterparty, counterpartyVersion string) (string, error) -} -type OnChanOpenTryBeforeHooks interface { - OnChanOpenTryBeforeHook(ctx sdk.Context, order channeltypes.Order, connectionHops []string, portID, channelID string, channelCap *capabilitytypes.Capability, counterparty channeltypes.Counterparty, counterpartyVersion string) -} -type OnChanOpenTryAfterHooks interface { - OnChanOpenTryAfterHook(ctx sdk.Context, order channeltypes.Order, connectionHops []string, portID, channelID string, channelCap *capabilitytypes.Capability, counterparty channeltypes.Counterparty, counterpartyVersion string, version string, err error) -} - -// OnChanOpenAck Hooks -type OnChanOpenAckOverrideHooks interface { - OnChanOpenAckOverride(im IBCMiddleware, ctx sdk.Context, portID, channelID string, counterpartyChannelID string, counterpartyVersion string) error -} -type OnChanOpenAckBeforeHooks interface { - OnChanOpenAckBeforeHook(ctx sdk.Context, portID, channelID string, counterpartyChannelID string, counterpartyVersion string) -} -type OnChanOpenAckAfterHooks interface { - OnChanOpenAckAfterHook(ctx sdk.Context, portID, channelID string, counterpartyChannelID string, counterpartyVersion string, err error) -} - -// OnChanOpenConfirm Hooks -type OnChanOpenConfirmOverrideHooks interface { - OnChanOpenConfirmOverride(im IBCMiddleware, ctx sdk.Context, portID, channelID string) error -} -type OnChanOpenConfirmBeforeHooks interface { - OnChanOpenConfirmBeforeHook(ctx sdk.Context, portID, channelID string) -} -type OnChanOpenConfirmAfterHooks interface { - OnChanOpenConfirmAfterHook(ctx sdk.Context, portID, channelID string, err error) -} - -// OnChanCloseInit Hooks -type OnChanCloseInitOverrideHooks interface { - OnChanCloseInitOverride(im IBCMiddleware, ctx sdk.Context, portID, channelID string) error -} -type OnChanCloseInitBeforeHooks interface { - OnChanCloseInitBeforeHook(ctx sdk.Context, portID, channelID string) -} -type OnChanCloseInitAfterHooks interface { - OnChanCloseInitAfterHook(ctx sdk.Context, portID, channelID string, err error) -} - -// OnChanCloseConfirm Hooks -type OnChanCloseConfirmOverrideHooks interface { - OnChanCloseConfirmOverride(im IBCMiddleware, ctx sdk.Context, portID, channelID string) error -} -type OnChanCloseConfirmBeforeHooks interface { - OnChanCloseConfirmBeforeHook(ctx sdk.Context, portID, channelID string) -} -type OnChanCloseConfirmAfterHooks interface { - OnChanCloseConfirmAfterHook(ctx sdk.Context, portID, channelID string, err error) -} - -// OnRecvPacket Hooks -type OnRecvPacketOverrideHooks interface { - OnRecvPacketOverride(im IBCMiddleware, ctx sdk.Context, packet channeltypes.Packet, relayer sdk.AccAddress) ibcexported.Acknowledgement -} -type OnRecvPacketBeforeHooks interface { - OnRecvPacketBeforeHook(ctx sdk.Context, packet channeltypes.Packet, relayer sdk.AccAddress) -} -type OnRecvPacketAfterHooks interface { - OnRecvPacketAfterHook(ctx sdk.Context, packet channeltypes.Packet, relayer sdk.AccAddress, ack ibcexported.Acknowledgement) -} - -// OnAcknowledgementPacket Hooks -type OnAcknowledgementPacketOverrideHooks interface { - OnAcknowledgementPacketOverride(im IBCMiddleware, ctx sdk.Context, packet channeltypes.Packet, acknowledgement []byte, relayer sdk.AccAddress) error -} -type OnAcknowledgementPacketBeforeHooks interface { - OnAcknowledgementPacketBeforeHook(ctx sdk.Context, packet channeltypes.Packet, acknowledgement []byte, relayer sdk.AccAddress) -} -type OnAcknowledgementPacketAfterHooks interface { - OnAcknowledgementPacketAfterHook(ctx sdk.Context, packet channeltypes.Packet, acknowledgement []byte, relayer sdk.AccAddress, err error) -} - -// OnTimeoutPacket Hooks -type OnTimeoutPacketOverrideHooks interface { - OnTimeoutPacketOverride(im IBCMiddleware, ctx sdk.Context, packet channeltypes.Packet, relayer sdk.AccAddress) error -} -type OnTimeoutPacketBeforeHooks interface { - OnTimeoutPacketBeforeHook(ctx sdk.Context, packet channeltypes.Packet, relayer sdk.AccAddress) -} -type OnTimeoutPacketAfterHooks interface { - OnTimeoutPacketAfterHook(ctx sdk.Context, packet channeltypes.Packet, relayer sdk.AccAddress, err error) -} - -// SendPacket Hooks - -type SendPacketOverrideHooks interface { - SendPacketOverride(i ICS4Middleware, ctx sdk.Context, chanCap *capabilitytypes.Capability, sourcePort string, sourceChannel string, timeoutHeight clienttypes.Height, timeoutTimestamp uint64, data []byte) (uint64, error) -} -type SendPacketBeforeHooks interface { - SendPacketBeforeHook(ctx sdk.Context, chanCap *capabilitytypes.Capability, sourcePort string, sourceChannel string, timeoutHeight clienttypes.Height, timeoutTimestamp uint64, data []byte) -} -type SendPacketAfterHooks interface { - SendPacketAfterHook(ctx sdk.Context, chanCap *capabilitytypes.Capability, sourcePort string, sourceChannel string, timeoutHeight clienttypes.Height, timeoutTimestamp uint64, data []byte, err error) -} - -// WriteAcknowledgement Hooks -type WriteAcknowledgementOverrideHooks interface { - WriteAcknowledgementOverride(i ICS4Middleware, ctx sdk.Context, chanCap *capabilitytypes.Capability, packet ibcexported.PacketI, ack ibcexported.Acknowledgement) error -} -type WriteAcknowledgementBeforeHooks interface { - WriteAcknowledgementBeforeHook(ctx sdk.Context, chanCap *capabilitytypes.Capability, packet ibcexported.PacketI, ack ibcexported.Acknowledgement) -} -type WriteAcknowledgementAfterHooks interface { - WriteAcknowledgementAfterHook(ctx sdk.Context, chanCap *capabilitytypes.Capability, packet ibcexported.PacketI, ack ibcexported.Acknowledgement, err error) -} - -// GetAppVersion Hooks -type GetAppVersionOverrideHooks interface { - GetAppVersionOverride(i ICS4Middleware, ctx sdk.Context, portID, channelID string) (string, bool) -} -type GetAppVersionBeforeHooks interface { - GetAppVersionBeforeHook(ctx sdk.Context, portID, channelID string) -} -type GetAppVersionAfterHooks interface { - GetAppVersionAfterHook(ctx sdk.Context, portID, channelID string, result string, success bool) -} diff --git a/x/ibchooks/ibc_module.go b/x/ibchooks/ibc_module.go deleted file mode 100644 index 1ba3ba23..00000000 --- a/x/ibchooks/ibc_module.go +++ /dev/null @@ -1,262 +0,0 @@ -package ibchooks - -import ( - // ibc-go - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" - ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" - - // external libraries - sdk "github.com/cosmos/cosmos-sdk/types" - capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" -) - -var _ porttypes.Middleware = &IBCMiddleware{} - -type IBCMiddleware struct { - App porttypes.IBCModule - ICS4Middleware *ICS4Middleware -} - -func NewIBCMiddleware(app porttypes.IBCModule, ics4 *ICS4Middleware) IBCMiddleware { - return IBCMiddleware{ - App: app, - ICS4Middleware: ics4, - } -} - -// OnChanOpenInit implements the IBCMiddleware interface -func (im IBCMiddleware) OnChanOpenInit( - ctx sdk.Context, - order channeltypes.Order, - connectionHops []string, - portID string, - channelID string, - channelCap *capabilitytypes.Capability, - counterparty channeltypes.Counterparty, - version string, -) (string, error) { - if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenInitOverrideHooks); ok { - return hook.OnChanOpenInitOverride(im, ctx, order, connectionHops, portID, channelID, channelCap, counterparty, version) - } - - if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenInitBeforeHooks); ok { - hook.OnChanOpenInitBeforeHook(ctx, order, connectionHops, portID, channelID, channelCap, counterparty, version) - } - - finalVersion, err := im.App.OnChanOpenInit(ctx, order, connectionHops, portID, channelID, channelCap, counterparty, version) - - if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenInitAfterHooks); ok { - hook.OnChanOpenInitAfterHook(ctx, order, connectionHops, portID, channelID, channelCap, counterparty, version, finalVersion, err) - } - return version, err -} - -// OnChanOpenTry implements the IBCMiddleware interface -func (im IBCMiddleware) OnChanOpenTry( - ctx sdk.Context, - order channeltypes.Order, - connectionHops []string, - portID, - channelID string, - channelCap *capabilitytypes.Capability, - counterparty channeltypes.Counterparty, - counterpartyVersion string, -) (string, error) { - if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenTryOverrideHooks); ok { - return hook.OnChanOpenTryOverride(im, ctx, order, connectionHops, portID, channelID, channelCap, counterparty, counterpartyVersion) - } - - if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenTryBeforeHooks); ok { - hook.OnChanOpenTryBeforeHook(ctx, order, connectionHops, portID, channelID, channelCap, counterparty, counterpartyVersion) - } - - version, err := im.App.OnChanOpenTry(ctx, order, connectionHops, portID, channelID, channelCap, counterparty, counterpartyVersion) - - if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenTryAfterHooks); ok { - hook.OnChanOpenTryAfterHook(ctx, order, connectionHops, portID, channelID, channelCap, counterparty, counterpartyVersion, version, err) - } - return version, err -} - -// OnChanOpenAck implements the IBCMiddleware interface -func (im IBCMiddleware) OnChanOpenAck( - ctx sdk.Context, - portID, - channelID string, - counterpartyChannelID string, - counterpartyVersion string, -) error { - if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenAckOverrideHooks); ok { - return hook.OnChanOpenAckOverride(im, ctx, portID, channelID, counterpartyChannelID, counterpartyVersion) - } - - if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenAckBeforeHooks); ok { - hook.OnChanOpenAckBeforeHook(ctx, portID, channelID, counterpartyChannelID, counterpartyVersion) - } - err := im.App.OnChanOpenAck(ctx, portID, channelID, counterpartyChannelID, counterpartyVersion) - if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenAckAfterHooks); ok { - hook.OnChanOpenAckAfterHook(ctx, portID, channelID, counterpartyChannelID, counterpartyVersion, err) - } - - return err -} - -// OnChanOpenConfirm implements the IBCMiddleware interface -func (im IBCMiddleware) OnChanOpenConfirm( - ctx sdk.Context, - portID, - channelID string, -) error { - if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenConfirmOverrideHooks); ok { - return hook.OnChanOpenConfirmOverride(im, ctx, portID, channelID) - } - - if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenConfirmBeforeHooks); ok { - hook.OnChanOpenConfirmBeforeHook(ctx, portID, channelID) - } - err := im.App.OnChanOpenConfirm(ctx, portID, channelID) - if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenConfirmAfterHooks); ok { - hook.OnChanOpenConfirmAfterHook(ctx, portID, channelID, err) - } - return err -} - -// OnChanCloseInit implements the IBCMiddleware interface -func (im IBCMiddleware) OnChanCloseInit( - ctx sdk.Context, - portID, - channelID string, -) error { - // Here we can remove the limits when a new channel is closed. For now, they can remove them manually on the contract - if hook, ok := im.ICS4Middleware.Hooks.(OnChanCloseInitOverrideHooks); ok { - return hook.OnChanCloseInitOverride(im, ctx, portID, channelID) - } - - if hook, ok := im.ICS4Middleware.Hooks.(OnChanCloseInitBeforeHooks); ok { - hook.OnChanCloseInitBeforeHook(ctx, portID, channelID) - } - err := im.App.OnChanCloseInit(ctx, portID, channelID) - if hook, ok := im.ICS4Middleware.Hooks.(OnChanCloseInitAfterHooks); ok { - hook.OnChanCloseInitAfterHook(ctx, portID, channelID, err) - } - - return err -} - -// OnChanCloseConfirm implements the IBCMiddleware interface -func (im IBCMiddleware) OnChanCloseConfirm( - ctx sdk.Context, - portID, - channelID string, -) error { - // Here we can remove the limits when a new channel is closed. For now, they can remove them manually on the contract - if hook, ok := im.ICS4Middleware.Hooks.(OnChanCloseConfirmOverrideHooks); ok { - return hook.OnChanCloseConfirmOverride(im, ctx, portID, channelID) - } - - if hook, ok := im.ICS4Middleware.Hooks.(OnChanCloseConfirmBeforeHooks); ok { - hook.OnChanCloseConfirmBeforeHook(ctx, portID, channelID) - } - err := im.App.OnChanCloseConfirm(ctx, portID, channelID) - if hook, ok := im.ICS4Middleware.Hooks.(OnChanCloseConfirmAfterHooks); ok { - hook.OnChanCloseConfirmAfterHook(ctx, portID, channelID, err) - } - - return err -} - -// OnRecvPacket implements the IBCMiddleware interface -func (im IBCMiddleware) OnRecvPacket( - ctx sdk.Context, - packet channeltypes.Packet, - relayer sdk.AccAddress, -) ibcexported.Acknowledgement { - if hook, ok := im.ICS4Middleware.Hooks.(OnRecvPacketOverrideHooks); ok { - return hook.OnRecvPacketOverride(im, ctx, packet, relayer) - } - - if hook, ok := im.ICS4Middleware.Hooks.(OnRecvPacketBeforeHooks); ok { - hook.OnRecvPacketBeforeHook(ctx, packet, relayer) - } - - ack := im.App.OnRecvPacket(ctx, packet, relayer) - - if hook, ok := im.ICS4Middleware.Hooks.(OnRecvPacketAfterHooks); ok { - hook.OnRecvPacketAfterHook(ctx, packet, relayer, ack) - } - - return ack -} - -// OnAcknowledgementPacket implements the IBCMiddleware interface -func (im IBCMiddleware) OnAcknowledgementPacket( - ctx sdk.Context, - packet channeltypes.Packet, - acknowledgement []byte, - relayer sdk.AccAddress, -) error { - if hook, ok := im.ICS4Middleware.Hooks.(OnAcknowledgementPacketOverrideHooks); ok { - return hook.OnAcknowledgementPacketOverride(im, ctx, packet, acknowledgement, relayer) - } - if hook, ok := im.ICS4Middleware.Hooks.(OnAcknowledgementPacketBeforeHooks); ok { - hook.OnAcknowledgementPacketBeforeHook(ctx, packet, acknowledgement, relayer) - } - - err := im.App.OnAcknowledgementPacket(ctx, packet, acknowledgement, relayer) - - if hook, ok := im.ICS4Middleware.Hooks.(OnAcknowledgementPacketAfterHooks); ok { - hook.OnAcknowledgementPacketAfterHook(ctx, packet, acknowledgement, relayer, err) - } - - return err -} - -// OnTimeoutPacket implements the IBCMiddleware interface -func (im IBCMiddleware) OnTimeoutPacket( - ctx sdk.Context, - packet channeltypes.Packet, - relayer sdk.AccAddress, -) error { - if hook, ok := im.ICS4Middleware.Hooks.(OnTimeoutPacketOverrideHooks); ok { - return hook.OnTimeoutPacketOverride(im, ctx, packet, relayer) - } - - if hook, ok := im.ICS4Middleware.Hooks.(OnTimeoutPacketBeforeHooks); ok { - hook.OnTimeoutPacketBeforeHook(ctx, packet, relayer) - } - err := im.App.OnTimeoutPacket(ctx, packet, relayer) - if hook, ok := im.ICS4Middleware.Hooks.(OnTimeoutPacketAfterHooks); ok { - hook.OnTimeoutPacketAfterHook(ctx, packet, relayer, err) - } - - return err -} - -// SendPacket implements the ICS4 Wrapper interface -func (im IBCMiddleware) SendPacket( - ctx sdk.Context, - chanCap *capabilitytypes.Capability, - sourcePort string, - sourceChannel string, - timeoutHeight clienttypes.Height, - timeoutTimestamp uint64, - data []byte, -) (uint64, error) { - return im.ICS4Middleware.SendPacket(ctx, chanCap, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, data) -} - -// WriteAcknowledgement implements the ICS4 Wrapper interface -func (im IBCMiddleware) WriteAcknowledgement( - ctx sdk.Context, - chanCap *capabilitytypes.Capability, - packet ibcexported.PacketI, - ack ibcexported.Acknowledgement, -) error { - return im.ICS4Middleware.WriteAcknowledgement(ctx, chanCap, packet, ack) -} - -func (im IBCMiddleware) GetAppVersion(ctx sdk.Context, portID, channelID string) (string, bool) { - return im.ICS4Middleware.GetAppVersion(ctx, portID, channelID) -} diff --git a/x/ibchooks/ics4_middleware.go b/x/ibchooks/ics4_middleware.go deleted file mode 100644 index 3ac128ae..00000000 --- a/x/ibchooks/ics4_middleware.go +++ /dev/null @@ -1,85 +0,0 @@ -package ibchooks - -import ( - // ibc-go - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" - ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" - - // external libraries - sdk "github.com/cosmos/cosmos-sdk/types" - capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" -) - -var _ porttypes.ICS4Wrapper = &ICS4Middleware{} - -type ICS4Middleware struct { - channel porttypes.ICS4Wrapper - - // Hooks - Hooks Hooks -} - -func NewICS4Middleware(channel porttypes.ICS4Wrapper, hooks Hooks) ICS4Middleware { - return ICS4Middleware{ - channel: channel, - Hooks: hooks, - } -} - -func (i ICS4Middleware) SendPacket(ctx sdk.Context, - channelCap *capabilitytypes.Capability, - sourcePort string, - sourceChannel string, - timeoutHeight clienttypes.Height, - timeoutTimestamp uint64, - data []byte, -) (sequence uint64, err error) { - if hook, ok := i.Hooks.(SendPacketOverrideHooks); ok { - return hook.SendPacketOverride(i, ctx, channelCap, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, data) - } - - if hook, ok := i.Hooks.(SendPacketBeforeHooks); ok { - hook.SendPacketBeforeHook(ctx, channelCap, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, data) - } - - sequence, err = i.channel.SendPacket(ctx, channelCap, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, data) - - if hook, ok := i.Hooks.(SendPacketAfterHooks); ok { - hook.SendPacketAfterHook(ctx, channelCap, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, data, err) - } - - return sequence, err -} - -func (i ICS4Middleware) WriteAcknowledgement(ctx sdk.Context, chanCap *capabilitytypes.Capability, packet ibcexported.PacketI, ack ibcexported.Acknowledgement) error { - if hook, ok := i.Hooks.(WriteAcknowledgementOverrideHooks); ok { - return hook.WriteAcknowledgementOverride(i, ctx, chanCap, packet, ack) - } - - if hook, ok := i.Hooks.(WriteAcknowledgementBeforeHooks); ok { - hook.WriteAcknowledgementBeforeHook(ctx, chanCap, packet, ack) - } - err := i.channel.WriteAcknowledgement(ctx, chanCap, packet, ack) - if hook, ok := i.Hooks.(WriteAcknowledgementAfterHooks); ok { - hook.WriteAcknowledgementAfterHook(ctx, chanCap, packet, ack, err) - } - - return err -} - -func (i ICS4Middleware) GetAppVersion(ctx sdk.Context, portID, channelID string) (string, bool) { - if hook, ok := i.Hooks.(GetAppVersionOverrideHooks); ok { - return hook.GetAppVersionOverride(i, ctx, portID, channelID) - } - - if hook, ok := i.Hooks.(GetAppVersionBeforeHooks); ok { - hook.GetAppVersionBeforeHook(ctx, portID, channelID) - } - version, err := i.channel.GetAppVersion(ctx, portID, channelID) - if hook, ok := i.Hooks.(GetAppVersionAfterHooks); ok { - hook.GetAppVersionAfterHook(ctx, portID, channelID, version, err) - } - - return version, err -} diff --git a/x/ibchooks/keeper/keeper.go b/x/ibchooks/keeper/keeper.go deleted file mode 100644 index 50983741..00000000 --- a/x/ibchooks/keeper/keeper.go +++ /dev/null @@ -1,62 +0,0 @@ -package keeper - -import ( - "fmt" - - storetypes "github.com/cosmos/cosmos-sdk/store/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/address" - - "github.com/cometbft/cometbft/libs/log" - - "github.com/White-Whale-Defi-Platform/migaloo-chain/v3/x/ibchooks/types" -) - -type ( - Keeper struct { - storeKey storetypes.StoreKey - } -) - -// NewKeeper returns a new instance of the x/ibchooks keeper -func NewKeeper( - storeKey storetypes.StoreKey, -) Keeper { - return Keeper{ - storeKey: storeKey, - } -} - -// Logger returns a logger for the x/tokenfactory module -func (k Keeper) Logger(ctx sdk.Context) log.Logger { - return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) -} - -func GetPacketKey(channel string, packetSequence uint64) []byte { - return []byte(fmt.Sprintf("%s::%d", channel, packetSequence)) -} - -// StorePacketCallback stores which contract will be listening for the ack or timeout of a packet -func (k Keeper) StorePacketCallback(ctx sdk.Context, channel string, packetSequence uint64, contract string) { - store := ctx.KVStore(k.storeKey) - store.Set(GetPacketKey(channel, packetSequence), []byte(contract)) -} - -// GetPacketCallback returns the bech32 addr of the contract that is expecting a callback from a packet -func (k Keeper) GetPacketCallback(ctx sdk.Context, channel string, packetSequence uint64) string { - store := ctx.KVStore(k.storeKey) - return string(store.Get(GetPacketKey(channel, packetSequence))) -} - -// DeletePacketCallback deletes the callback from storage once it has been processed -func (k Keeper) DeletePacketCallback(ctx sdk.Context, channel string, packetSequence uint64) { - store := ctx.KVStore(k.storeKey) - store.Delete(GetPacketKey(channel, packetSequence)) -} - -func DeriveIntermediateSender(channel, originalSender, bech32Prefix string) (string, error) { - senderStr := fmt.Sprintf("%s/%s", channel, originalSender) - senderHash32 := address.Hash(types.SenderPrefix, []byte(senderStr)) - sender := sdk.AccAddress(senderHash32) - return sdk.Bech32ifyAddressBytes(bech32Prefix, sender) -} diff --git a/x/ibchooks/sdkmodule.go b/x/ibchooks/sdkmodule.go deleted file mode 100644 index 926fd5df..00000000 --- a/x/ibchooks/sdkmodule.go +++ /dev/null @@ -1,126 +0,0 @@ -package ibchooks - -import ( - "encoding/json" - - "github.com/gorilla/mux" - "github.com/grpc-ecosystem/grpc-gateway/runtime" - "github.com/spf13/cobra" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/codec" - cdctypes "github.com/cosmos/cosmos-sdk/codec/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/module" - authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" - - abci "github.com/cometbft/cometbft/abci/types" - - "github.com/White-Whale-Defi-Platform/migaloo-chain/v3/x/ibchooks/client/cli" - "github.com/White-Whale-Defi-Platform/migaloo-chain/v3/x/ibchooks/types" -) - -var ( - _ module.AppModule = AppModule{} - _ module.AppModuleBasic = AppModuleBasic{} -) - -// AppModuleBasic defines the basic application module used by the ibc-hooks module. -type AppModuleBasic struct{} - -var _ module.AppModuleBasic = AppModuleBasic{} - -// Name returns the ibc-hooks module's name. -func (AppModuleBasic) Name() string { - return types.ModuleName -} - -// RegisterLegacyAminoCodec registers the ibc-hooks module's types on the given LegacyAmino codec. -func (AppModuleBasic) RegisterLegacyAminoCodec(_ *codec.LegacyAmino) {} - -// RegisterInterfaces registers the module's interface types. -func (b AppModuleBasic) RegisterInterfaces(_ cdctypes.InterfaceRegistry) {} - -// DefaultGenesis returns default genesis state as raw bytes for the -// module. -func (AppModuleBasic) DefaultGenesis(_ codec.JSONCodec) json.RawMessage { - emptyString := "{}" - return []byte(emptyString) -} - -// ValidateGenesis performs genesis state validation for the ibc-hooks module. -func (AppModuleBasic) ValidateGenesis(_ codec.JSONCodec, _ client.TxEncodingConfig, _ json.RawMessage) error { - return nil -} - -// RegisterRESTRoutes registers the REST routes for the ibc-hooks module. -func (AppModuleBasic) RegisterRESTRoutes(_ client.Context, _ *mux.Router) {} - -// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the ibc-hooks module. -func (AppModuleBasic) RegisterGRPCGatewayRoutes(_ client.Context, _ *runtime.ServeMux) {} - -// GetTxCmd returns no root tx command for the ibc-hooks module. -func (AppModuleBasic) GetTxCmd() *cobra.Command { return nil } - -// GetQueryCmd returns the root query command for the ibc-hooks module. -func (AppModuleBasic) GetQueryCmd() *cobra.Command { - return cli.GetQueryCmd() -} - -// ___________________________________________________________________________ - -// AppModule implements an application module for the ibc-hooks module. -type AppModule struct { - AppModuleBasic - - authKeeper authkeeper.AccountKeeper -} - -// NewAppModule creates a new AppModule object. -func NewAppModule(ak authkeeper.AccountKeeper) AppModule { - return AppModule{ - AppModuleBasic: AppModuleBasic{}, - authKeeper: ak, - } -} - -// Name returns the ibc-hooks module's name. -func (AppModule) Name() string { - return types.ModuleName -} - -// RegisterInvariants registers the ibc-hooks module invariants. -func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} - -// QuerierRoute returns the module's querier route name. -func (AppModule) QuerierRoute() string { - return "" -} - -// RegisterServices registers a gRPC query service to respond to the -// module-specific gRPC queries. -func (am AppModule) RegisterServices(_ module.Configurator) { -} - -// InitGenesis performs genesis initialization for the ibc-hooks module. It returns -// no validator updates. -func (am AppModule) InitGenesis(_ sdk.Context, _ codec.JSONCodec, _ json.RawMessage) []abci.ValidatorUpdate { - return []abci.ValidatorUpdate{} -} - -func (am AppModule) ExportGenesis(_ sdk.Context, _ codec.JSONCodec) json.RawMessage { - return json.RawMessage([]byte("{}")) -} - -// BeginBlock returns the begin blocker for the ibc-hooks module. -func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) { -} - -// EndBlock returns the end blocker for the ibc-hooks module. It returns no validator -// updates. -func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { - return []abci.ValidatorUpdate{} -} - -// ConsensusVersion implements AppModule/ConsensusVersion. -func (AppModule) ConsensusVersion() uint64 { return 1 } diff --git a/x/ibchooks/types/errors.go b/x/ibchooks/types/errors.go deleted file mode 100644 index f2ba928b..00000000 --- a/x/ibchooks/types/errors.go +++ /dev/null @@ -1,15 +0,0 @@ -package types - -import sdkerrors "cosmossdk.io/errors" - -var ( - ErrBadMetadataFormatMsg = "wasm metadata not properly formatted for: '%v'. %s" - ErrBadExecutionMsg = "cannot execute contract: %v" - - ErrMsgValidation = sdkerrors.Register("wasm-hooks", 2, "error in wasmhook message validation") - ErrMarshaling = sdkerrors.Register("wasm-hooks", 3, "cannot marshal the ICS20 packet") - ErrInvalidPacket = sdkerrors.Register("wasm-hooks", 4, "invalid packet data") - ErrBadResponse = sdkerrors.Register("wasm-hooks", 5, "cannot create response") - ErrWasmError = sdkerrors.Register("wasm-hooks", 6, "wasm error") - ErrBadSender = sdkerrors.Register("wasm-hooks", 7, "bad sender") -) diff --git a/x/ibchooks/types/keys.go b/x/ibchooks/types/keys.go deleted file mode 100644 index 9a3e7ded..00000000 --- a/x/ibchooks/types/keys.go +++ /dev/null @@ -1,8 +0,0 @@ -package types - -const ( - ModuleName = "ibchooks" - StoreKey = "hooks-for-ibc" // not using the module name because of collisions with key "ibc" - IBCCallbackKey = "ibc_callback" - SenderPrefix = "ibc-wasm-hook-intermediary" -) diff --git a/x/ibchooks/wasm_hook.go b/x/ibchooks/wasm_hook.go deleted file mode 100644 index 7a6e355b..00000000 --- a/x/ibchooks/wasm_hook.go +++ /dev/null @@ -1,421 +0,0 @@ -package ibchooks - -import ( - "encoding/json" - "fmt" - - wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" - wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" - transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/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" - - errorsmod "cosmossdk.io/errors" - - sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - - "github.com/White-Whale-Defi-Platform/migaloo-chain/v3/osmosis-types/osmoutils" - "github.com/White-Whale-Defi-Platform/migaloo-chain/v3/x/ibchooks/keeper" - "github.com/White-Whale-Defi-Platform/migaloo-chain/v3/x/ibchooks/types" -) - -type ContractAck struct { - ContractResult []byte `json:"contract_result"` - IbcAck []byte `json:"ibc_ack"` -} - -type WasmHooks struct { - WasmKeeper *wasmkeeper.Keeper - ContractKeeper *wasmkeeper.PermissionedKeeper - ibcHooksKeeper *keeper.Keeper - bech32PrefixAccAddr string -} - -func NewWasmHooks(ibcHooksKeeper *keeper.Keeper, contractKeeper *wasmkeeper.PermissionedKeeper, wasmKeeper *wasmkeeper.Keeper, bech32PrefixAccAddr string) WasmHooks { - return WasmHooks{ - WasmKeeper: wasmKeeper, - ContractKeeper: contractKeeper, - ibcHooksKeeper: ibcHooksKeeper, - bech32PrefixAccAddr: bech32PrefixAccAddr, - } -} - -func (h WasmHooks) ProperlyConfigured() bool { - return h.ContractKeeper != nil && h.ibcHooksKeeper != nil -} - -func (h WasmHooks) OnRecvPacketOverride(im IBCMiddleware, ctx sdk.Context, packet channeltypes.Packet, relayer sdk.AccAddress) ibcexported.Acknowledgement { - if !h.ProperlyConfigured() { - // Not configured - return im.App.OnRecvPacket(ctx, packet, relayer) - } - isIcs20, data := isIcs20Packet(packet) - if !isIcs20 { - return im.App.OnRecvPacket(ctx, packet, relayer) - } - - // Validate the memo - isWasmRouted, contractAddr, msgBytes, err := ValidateAndParseMemo(data.GetMemo(), data.Receiver) - if !isWasmRouted { - return im.App.OnRecvPacket(ctx, packet, relayer) - } - if err != nil { - return osmoutils.NewEmitErrorAcknowledgement(ctx, types.ErrMsgValidation, err.Error()) - } - if msgBytes == nil || contractAddr == nil { // This should never happen - return osmoutils.NewEmitErrorAcknowledgement(ctx, types.ErrMsgValidation) - } - - // Calculate the receiver / contract caller based on the packet's channel and sender - channel := packet.GetDestChannel() - sender := data.GetSender() - senderBech32, err := keeper.DeriveIntermediateSender(channel, sender, h.bech32PrefixAccAddr) - if err != nil { - return osmoutils.NewEmitErrorAcknowledgement(ctx, types.ErrBadSender, fmt.Sprintf("cannot convert sender address %s/%s to bech32: %s", channel, sender, err.Error())) - } - - // The funds sent on this packet need to be transferred to the intermediary account for the sender. - // For this, we override the ICS20 packet's Receiver (essentially hijacking the funds to this new address) - // and execute the underlying OnRecvPacket() call (which should eventually land on the transfer app's - // relay.go and send the sunds to the intermediary account. - // - // If that succeeds, we make the contract call - data.Receiver = senderBech32 - bz, err := json.Marshal(data) - if err != nil { - return osmoutils.NewEmitErrorAcknowledgement(ctx, types.ErrMarshaling, err.Error()) - } - packet.Data = bz - - // Execute the receive - ack := im.App.OnRecvPacket(ctx, packet, relayer) - if !ack.Success() { - return ack - } - - amount, ok := sdk.NewIntFromString(data.GetAmount()) - if !ok { - // This should never happen, as it should've been caught in the underlaying call to OnRecvPacket, - // but returning here for completeness - return osmoutils.NewEmitErrorAcknowledgement(ctx, types.ErrInvalidPacket, "Amount is not an int") - } - - // The packet's denom is the denom in the sender chain. This needs to be converted to the local denom. - denom := osmoutils.MustExtractDenomFromPacketOnRecv(packet) - funds := sdk.NewCoins(sdk.NewCoin(denom, amount)) - - // Execute the contract - execMsg := wasmtypes.MsgExecuteContract{ - Sender: senderBech32, - Contract: contractAddr.String(), - Msg: msgBytes, - Funds: funds, - } - response, err := h.execWasmMsg(ctx, &execMsg) - if err != nil { - return osmoutils.NewEmitErrorAcknowledgement(ctx, types.ErrWasmError, err.Error()) - } - - fullAck := ContractAck{ContractResult: response.Data, IbcAck: ack.Acknowledgement()} - bz, err = json.Marshal(fullAck) - if err != nil { - return osmoutils.NewEmitErrorAcknowledgement(ctx, types.ErrBadResponse, err.Error()) - } - - return channeltypes.NewResultAcknowledgement(bz) -} - -func (h WasmHooks) execWasmMsg(ctx sdk.Context, execMsg *wasmtypes.MsgExecuteContract) (*wasmtypes.MsgExecuteContractResponse, error) { - if err := execMsg.ValidateBasic(); err != nil { - return nil, fmt.Errorf(types.ErrBadExecutionMsg, err.Error()) - } - wasmMsgServer := wasmkeeper.NewMsgServerImpl(h.WasmKeeper) - return wasmMsgServer.ExecuteContract(sdk.WrapSDKContext(ctx), execMsg) -} - -func isIcs20Packet(packet channeltypes.Packet) (isIcs20 bool, ics20data transfertypes.FungibleTokenPacketData) { - var data transfertypes.FungibleTokenPacketData - if err := json.Unmarshal(packet.GetData(), &data); err != nil { - return false, data - } - return true, data -} - -// jsonStringHasKey parses the memo as a json object and checks if it contains the key. -func jsonStringHasKey(memo, key string) (found bool, jsonObject map[string]interface{}) { - jsonObject = make(map[string]interface{}) - - // If there is no memo, the packet was either sent with an earlier version of IBC, or the memo was - // intentionally left blank. Nothing to do here. Ignore the packet and pass it down the stack. - if len(memo) == 0 { - return false, jsonObject - } - - // the jsonObject must be a valid JSON object - err := json.Unmarshal([]byte(memo), &jsonObject) - if err != nil { - return false, jsonObject - } - - // If the key doesn't exist, there's nothing to do on this hook. Continue by passing the packet - // down the stack - _, ok := jsonObject[key] - if !ok { - return false, jsonObject - } - - return true, jsonObject -} - -func ValidateAndParseMemo(memo string, receiver string) (isWasmRouted bool, contractAddr sdk.AccAddress, msgBytes []byte, err error) { - isWasmRouted, metadata := jsonStringHasKey(memo, "wasm") - if !isWasmRouted { - return isWasmRouted, sdk.AccAddress{}, nil, nil - } - - wasmRaw := metadata["wasm"] - - // Make sure the wasm key is a map. If it isn't, ignore this packet - wasm, ok := wasmRaw.(map[string]interface{}) - if !ok { - return isWasmRouted, sdk.AccAddress{}, nil, - fmt.Errorf(types.ErrBadMetadataFormatMsg, memo, "wasm metadata is not a valid JSON map object") - } - - // Get the contract - contract, ok := wasm["contract"].(string) - if !ok { - // The tokens will be returned - return isWasmRouted, sdk.AccAddress{}, nil, - fmt.Errorf(types.ErrBadMetadataFormatMsg, memo, `Could not find key wasm["contract"]`) - } - - contractAddr, err = sdk.AccAddressFromBech32(contract) - if err != nil { - return isWasmRouted, sdk.AccAddress{}, nil, - fmt.Errorf(types.ErrBadMetadataFormatMsg, memo, `wasm["contract"] is not a valid bech32 address`) - } - - // The contract and the receiver should be the same for the packet to be valid - if contract != receiver { - return isWasmRouted, sdk.AccAddress{}, nil, - fmt.Errorf(types.ErrBadMetadataFormatMsg, memo, `wasm["contract"] should be the same as the receiver of the packet`) - } - - // Ensure the message key is provided - if wasm["msg"] == nil { - return isWasmRouted, sdk.AccAddress{}, nil, - fmt.Errorf(types.ErrBadMetadataFormatMsg, memo, `Could not find key wasm["msg"]`) - } - - // Make sure the msg key is a map. If it isn't, return an error - _, ok = wasm["msg"].(map[string]interface{}) - if !ok { - return isWasmRouted, sdk.AccAddress{}, nil, - fmt.Errorf(types.ErrBadMetadataFormatMsg, memo, `wasm["msg"] is not a map object`) - } - - // Get the message string by serializing the map - msgBytes, err = json.Marshal(wasm["msg"]) - if err != nil { - // The tokens will be returned - return isWasmRouted, sdk.AccAddress{}, nil, - fmt.Errorf(types.ErrBadMetadataFormatMsg, memo, err.Error()) - } - - return isWasmRouted, contractAddr, msgBytes, nil -} - -func (h WasmHooks) SendPacketOverride(i ICS4Middleware, ctx sdk.Context, chanCap *capabilitytypes.Capability, packet ibcexported.PacketI) error { - height := clienttypes.Height{ - RevisionNumber: packet.GetTimeoutHeight().GetRevisionHeight(), - RevisionHeight: packet.GetTimeoutHeight().GetRevisionHeight(), - } - - concretePacket, ok := packet.(channeltypes.Packet) - if !ok { - if _, err := i.channel.SendPacket(ctx, chanCap, - packet.GetSourcePort(), - packet.GetSourceChannel(), - height, - packet.GetTimeoutTimestamp(), - packet.GetData()); err != nil { - return err - } - } - - isIcs20, data := isIcs20Packet(concretePacket) - if !isIcs20 { - if _, err := i.channel.SendPacket(ctx, chanCap, - packet.GetSourcePort(), - packet.GetSourceChannel(), - height, - packet.GetTimeoutTimestamp(), - packet.GetData()); err != nil { - return err - } - } - - isCallbackRouted, metadata := jsonStringHasKey(data.GetMemo(), types.IBCCallbackKey) - if !isCallbackRouted { - if _, err := i.channel.SendPacket(ctx, chanCap, - packet.GetSourcePort(), - packet.GetSourceChannel(), - height, - packet.GetTimeoutTimestamp(), - packet.GetData()); err != nil { - return err - } - } - - // We remove the callback metadata from the memo as it has already been processed. - - // If the only available key in the memo is the callback, we should remove the memo - // from the data completely so the packet is sent without it. - // This way receiver chains that are on old versions of IBC will be able to process the packet - - callbackRaw := metadata[types.IBCCallbackKey] // This will be used later. - delete(metadata, types.IBCCallbackKey) - bzMetadata, err := json.Marshal(metadata) - if err != nil { - return errorsmod.Wrap(err, "Send packet with callback error") - } - stringMetadata := string(bzMetadata) - if stringMetadata == "{}" { - data.Memo = "" - } else { - data.Memo = stringMetadata - } - dataBytes, err := json.Marshal(data) - if err != nil { - return errorsmod.Wrap(err, "Send packet with callback error") - } - - packetWithoutCallbackMemo := channeltypes.Packet{ - Sequence: concretePacket.Sequence, - SourcePort: concretePacket.SourcePort, - SourceChannel: concretePacket.SourceChannel, - DestinationPort: concretePacket.DestinationPort, - DestinationChannel: concretePacket.DestinationChannel, - Data: dataBytes, - TimeoutTimestamp: concretePacket.TimeoutTimestamp, - TimeoutHeight: concretePacket.TimeoutHeight, - } - - _, err = i.channel.SendPacket(ctx, chanCap, - packetWithoutCallbackMemo.GetSourcePort(), - packetWithoutCallbackMemo.GetSourceChannel(), - height, - packetWithoutCallbackMemo.GetTimeoutTimestamp(), - packetWithoutCallbackMemo.GetData(), - ) - if err != nil { - return err - } - - // Make sure the callback contract is a string and a valid bech32 addr. If it isn't, ignore this packet - contract, ok := callbackRaw.(string) - if !ok { - return nil - } - _, err = sdk.AccAddressFromBech32(contract) - if err != nil { - return nil - } - - h.ibcHooksKeeper.StorePacketCallback(ctx, packet.GetSourceChannel(), packet.GetSequence(), contract) - return nil -} - -func (h WasmHooks) OnAcknowledgementPacketOverride(im IBCMiddleware, ctx sdk.Context, packet channeltypes.Packet, acknowledgement []byte, relayer sdk.AccAddress) error { - err := im.App.OnAcknowledgementPacket(ctx, packet, acknowledgement, relayer) - if err != nil { - return err - } - - if !h.ProperlyConfigured() { - // Not configured. Return from the underlying implementation - return nil - } - - contract := h.ibcHooksKeeper.GetPacketCallback(ctx, packet.GetSourceChannel(), packet.GetSequence()) - if contract == "" { - // No callback configured - return nil - } - - contractAddr, err := sdk.AccAddressFromBech32(contract) - if err != nil { - return sdkerrors.Wrap(err, "Ack callback error") // The callback configured is not a bech32. Error out - } - - success := "false" - if !osmoutils.IsAckError(acknowledgement) { - success = "true" - } - - // Notify the sender that the ack has been received - ackAsJSON, err := json.Marshal(acknowledgement) - if err != nil { - // If the ack is not a json object, error - return err - } - - sudoMsg := []byte(fmt.Sprintf( - `{"ibc_lifecycle_complete": {"ibc_ack": {"channel": "%s", "sequence": %d, "ack": %s, "success": %s}}}`, - packet.SourceChannel, packet.Sequence, ackAsJSON, success)) - _, err = h.ContractKeeper.Sudo(ctx, contractAddr, sudoMsg) - if err != nil { - // error processing the callback - // ToDo: Open Question: Should we also delete the callback here? - return sdkerrors.Wrap(err, "Ack callback error") - } - h.ibcHooksKeeper.DeletePacketCallback(ctx, packet.GetSourceChannel(), packet.GetSequence()) - return nil -} - -func (h WasmHooks) OnTimeoutPacketOverride(im IBCMiddleware, ctx sdk.Context, packet channeltypes.Packet, relayer sdk.AccAddress) error { - err := im.App.OnTimeoutPacket(ctx, packet, relayer) - if err != nil { - return err - } - - if !h.ProperlyConfigured() { - // Not configured. Return from the underlying implementation - return nil - } - - contract := h.ibcHooksKeeper.GetPacketCallback(ctx, packet.GetSourceChannel(), packet.GetSequence()) - if contract == "" { - // No callback configured - return nil - } - - contractAddr, err := sdk.AccAddressFromBech32(contract) - if err != nil { - return sdkerrors.Wrap(err, "Timeout callback error") // The callback configured is not a bech32. Error out - } - - sudoMsg := []byte(fmt.Sprintf( - `{"ibc_lifecycle_complete": {"ibc_timeout": {"channel": "%s", "sequence": %d}}}`, - packet.SourceChannel, packet.Sequence)) - _, err = h.ContractKeeper.Sudo(ctx, contractAddr, sudoMsg) - if err != nil { - // error processing the callback. This could be because the contract doesn't implement the message type to - // process the callback. Retrying this will not help, so we can delete the callback from storage. - // Since the packet has timed out, we don't expect any other responses that may trigger the callback. - ctx.EventManager().EmitEvents(sdk.Events{ - sdk.NewEvent( - "ibc-timeout-callback-error", - sdk.NewAttribute("contract", contractAddr.String()), - sdk.NewAttribute("message", string(sudoMsg)), - sdk.NewAttribute("error", err.Error()), - ), - }) - } - h.ibcHooksKeeper.DeletePacketCallback(ctx, packet.GetSourceChannel(), packet.GetSequence()) - return nil -}