Skip to content

Commit

Permalink
added ibc-hooks (#1173)
Browse files Browse the repository at this point in the history
  • Loading branch information
sampocs authored Apr 15, 2024
1 parent bdef5af commit b27e712
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 56 deletions.
106 changes: 66 additions & 40 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ import (
"github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v7/packetforward"
packetforwardkeeper "github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v7/packetforward/keeper"
packetforwardtypes "github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v7/packetforward/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"
icacontroller "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller"
icacontrollerkeeper "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/keeper"
Expand Down Expand Up @@ -223,6 +226,7 @@ var (
staketia.AppModuleBasic{},
stakedym.AppModuleBasic{},
wasm.AppModuleBasic{},
ibchooks.AppModuleBasic{},
)

// module account permissions
Expand Down Expand Up @@ -306,6 +310,11 @@ type StrideApp struct {
PacketForwardKeeper *packetforwardkeeper.Keeper
WasmKeeper wasmkeeper.Keeper
ContractKeeper *wasmkeeper.PermissionedKeeper
IBCHooksKeeper ibchookskeeper.Keeper

// Middleware for IBCHooks
Ics20WasmHooks *ibchooks.WasmHooks
HooksICS4Wrapper ibchooks.ICS4Middleware

// make scoped keepers public for test purposes
ScopedIBCKeeper capabilitykeeper.ScopedKeeper
Expand Down Expand Up @@ -381,6 +390,7 @@ func NewStrideApp(
staketiatypes.StoreKey,
stakedymtypes.StoreKey,
wasmtypes.StoreKey,
ibchookstypes.StoreKey,
)
tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey)
memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey)
Expand Down Expand Up @@ -458,13 +468,13 @@ func NewStrideApp(
stakingtypes.NewMultiStakingHooks(app.DistrKeeper.Hooks(), app.ClaimKeeper.Hooks()),
)

// ... other modules keepers

// Add ICS Consumer Keeper
app.ConsumerKeeper = ccvconsumerkeeper.NewNonZeroKeeper(
appCodec,
keys[ccvconsumertypes.StoreKey],
app.GetSubspace(ccvconsumertypes.ModuleName),
)

// Create IBC Keeper
app.IBCKeeper = ibckeeper.NewKeeper(
appCodec,
Expand All @@ -475,6 +485,14 @@ func NewStrideApp(
scopedIBCKeeper,
)

// Create IBC Hooks Keeper (must be defined after the wasmKeeper is created)
app.IBCHooksKeeper = ibchookskeeper.NewKeeper(
keys[ibchookstypes.StoreKey],
)
wasmHooks := ibchooks.NewWasmHooks(&app.IBCHooksKeeper, nil, AccountAddressPrefix) // the contract keeper is set later
app.Ics20WasmHooks = &wasmHooks
app.Ics20WasmHooks.ContractKeeper = &app.WasmKeeper // wasm keeper initialized below

// Create Ratelimit Keeper
scopedratelimitKeeper := app.CapabilityKeeper.ScopeToModule(ratelimittypes.ModuleName)
app.ScopedratelimitKeeper = scopedratelimitKeeper
Expand All @@ -489,6 +507,13 @@ func NewStrideApp(
)
ratelimitModule := ratelimit.NewAppModule(appCodec, app.RatelimitKeeper)

// Create the ICS4 wrapper which routes up the stack from ibchooks -> ratelimit
// (see full stack definition below)
app.HooksICS4Wrapper = ibchooks.NewICS4Middleware(
app.RatelimitKeeper, // ICS4Wrapper
app.Ics20WasmHooks,
)

// Initialize the packet forward middleware Keeper
// It's important to note that the PFM Keeper must be initialized before the Transfer Keeper
app.PacketForwardKeeper = packetforwardkeeper.NewKeeper(
Expand All @@ -498,7 +523,7 @@ func NewStrideApp(
app.IBCKeeper.ChannelKeeper,
app.DistrKeeper,
app.BankKeeper,
app.RatelimitKeeper, // ICS4Wrapper
app.HooksICS4Wrapper, // ICS4Wrapper
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)

Expand All @@ -517,8 +542,36 @@ func NewStrideApp(
// Set the TransferKeeper reference in the PacketForwardKeeper
app.PacketForwardKeeper.SetTransferKeeper(app.TransferKeeper)

transferModule := transfer.NewAppModule(app.TransferKeeper)
transferIBCModule := transfer.NewIBCModule(app.TransferKeeper)
// Add wasm keeper (must be after IBCKeeper and TransferKeeper)
wasmCapabilities := "iterator,staking,stargate,cosmwasm_1_1,cosmwasm_1_2,cosmwasm_1_3,cosmwasm_1_4"
wasmDir := filepath.Join(homePath, "wasm")
wasmConfig, err := wasm.ReadWasmConfig(appOpts)
if err != nil {
panic(fmt.Sprintf("error while reading wasm config: %s", err))
}

scopedWasmKeeper := app.CapabilityKeeper.ScopeToModule(wasmtypes.ModuleName)
app.WasmKeeper = wasmkeeper.NewKeeper(
appCodec,
keys[wasmtypes.StoreKey],
app.AccountKeeper,
app.BankKeeper,
app.StakingKeeper,
distrkeeper.NewQuerier(app.DistrKeeper),
app.IBCKeeper.ChannelKeeper, // ICS4Wrapper
app.IBCKeeper.ChannelKeeper,
&app.IBCKeeper.PortKeeper,
scopedWasmKeeper,
app.TransferKeeper,
app.MsgServiceRouter(),
app.GRPCQueryRouter(),
wasmDir,
wasmConfig,
wasmCapabilities,
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
wasmOpts...,
)
app.ContractKeeper = wasmkeeper.NewDefaultPermissionKeeper(app.WasmKeeper)

// Create evidence Keeper for to register the IBC light client misbehaviour evidence route
evidenceKeeper := evidencekeeper.NewKeeper(
Expand Down Expand Up @@ -660,39 +713,6 @@ func NewStrideApp(
app.AccountKeeper, app.BankKeeper, app.DistrKeeper, app.StakingKeeper,
)

// Add wasm keeper
wasmCapabilities := "iterator,staking,stargate,cosmwasm_1_1,cosmwasm_1_2,cosmwasm_1_3,cosmwasm_1_4"
wasmDir := filepath.Join(homePath, "wasm")
wasmConfig, err := wasm.ReadWasmConfig(appOpts)
if err != nil {
panic(fmt.Sprintf("error while reading wasm config: %s", err))
}

scopedWasmKeeper := app.CapabilityKeeper.ScopeToModule(wasmtypes.ModuleName)

app.WasmKeeper = wasmkeeper.NewKeeper(
appCodec,
keys[wasmtypes.StoreKey],
app.AccountKeeper,
app.BankKeeper,
app.StakingKeeper,
distrkeeper.NewQuerier(app.DistrKeeper),
app.IBCKeeper.ChannelKeeper, // ICS4Wrapper
app.IBCKeeper.ChannelKeeper,
&app.IBCKeeper.PortKeeper,
scopedWasmKeeper,
app.TransferKeeper,
app.MsgServiceRouter(),
app.GRPCQueryRouter(),
wasmDir,
wasmConfig,
wasmCapabilities,
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
wasmOpts...,
)

app.ContractKeeper = wasmkeeper.NewDefaultPermissionKeeper(app.WasmKeeper)

// Register Gov (must be registered after stakeibc)
govRouter := govtypesv1beta1.NewRouter()
govRouter.AddRoute(govtypes.RouterKey, govtypesv1beta1.ProposalHandler).
Expand Down Expand Up @@ -781,19 +801,21 @@ func NewStrideApp(
// - staketia
// - stakedym
// - ratelimit
// - ibchooks
// - pfm
// - transfer
// - base app
// Note: Traffic up the stack does not pass through records or autopilot,
// as defined via the ICS4Wrappers of each keeper
var transferStack porttypes.IBCModule = transferIBCModule
var transferStack porttypes.IBCModule = transfer.NewIBCModule(app.TransferKeeper)
transferStack = packetforward.NewIBCMiddleware(
transferStack,
app.PacketForwardKeeper,
0, // retries on timeout
packetforwardkeeper.DefaultForwardTransferPacketTimeoutTimestamp, // forward timeout
packetforwardkeeper.DefaultRefundTransferPacketTimeoutTimestamp, // refund timeout
)
transferStack = ibchooks.NewIBCMiddleware(transferStack, &app.HooksICS4Wrapper)
transferStack = ratelimit.NewIBCMiddleware(app.RatelimitKeeper, transferStack)
transferStack = staketia.NewIBCMiddleware(app.StaketiaKeeper, transferStack)
transferStack = stakedym.NewIBCMiddleware(app.StakedymKeeper, transferStack)
Expand Down Expand Up @@ -850,7 +872,8 @@ func NewStrideApp(
// technically, app.GetSubspace(packetforwardtypes.ModuleName) will never be run https://github.com/cosmos/ibc-apps/issues/146#issuecomment-1839242144
packetforward.NewAppModule(app.PacketForwardKeeper, app.GetSubspace(packetforwardtypes.ModuleName)),
wasm.NewAppModule(appCodec, &app.WasmKeeper, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.BaseApp.MsgServiceRouter(), app.GetSubspace(wasmtypes.ModuleName)),
transferModule,
ibchooks.NewAppModule(app.AccountKeeper),
transfer.NewAppModule(app.TransferKeeper),
// monitoringModule,
stakeibcModule,
epochsModule,
Expand Down Expand Up @@ -906,6 +929,7 @@ func NewStrideApp(
staketiatypes.ModuleName,
stakedymtypes.ModuleName,
wasmtypes.ModuleName,
ibchookstypes.ModuleName,
)

app.mm.SetOrderEndBlockers(
Expand Down Expand Up @@ -944,6 +968,7 @@ func NewStrideApp(
staketiatypes.ModuleName,
stakedymtypes.ModuleName,
wasmtypes.ModuleName,
ibchookstypes.ModuleName,
)

// NOTE: The genutils module must occur after staking so that pools are
Expand Down Expand Up @@ -987,6 +1012,7 @@ func NewStrideApp(
staketiatypes.ModuleName,
stakedymtypes.ModuleName,
wasmtypes.ModuleName,
ibchookstypes.ModuleName,
)

app.mm.RegisterInvariants(app.CrisisKeeper)
Expand Down
5 changes: 5 additions & 0 deletions app/upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
packetforwardtypes "github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v7/packetforward/types"
ibchookstypes "github.com/cosmos/ibc-apps/modules/ibc-hooks/v7/types"
consumertypes "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types"
evmosvestingtypes "github.com/evmos/vesting/x/vesting/types"

Expand Down Expand Up @@ -347,6 +348,10 @@ func (app *StrideApp) setupUpgradeHandlers(appOpts servertypes.AppOptions) {
storeUpgrades = &storetypes.StoreUpgrades{
Added: []string{wasmtypes.ModuleName, stakedymtypes.ModuleName},
}
case "v22":
storeUpgrades = &storetypes.StoreUpgrades{
Added: []string{ibchookstypes.ModuleName},
}
}

if storeUpgrades != nil {
Expand Down
7 changes: 4 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ require (
github.com/cosmos/cosmos-sdk v0.47.10
github.com/cosmos/gogoproto v1.4.10
github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v7 v7.1.3-0.20240228213828-cce7f56d000b
github.com/cosmos/ibc-go/v7 v7.3.1
github.com/cosmos/ibc-apps/modules/ibc-hooks/v7 v7.0.0-20240403143657-8e64543c87e0
github.com/cosmos/ibc-go/v7 v7.4.0
github.com/cosmos/ics23/go v0.10.0
github.com/cosmos/interchain-security/v4 v4.0.0
github.com/evmos/vesting v0.0.0-20230818101748-9ea561e4529c
Expand All @@ -40,13 +41,13 @@ require (
cloud.google.com/go/iam v1.1.5 // indirect
cloud.google.com/go/storage v1.30.1 // 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.4 // indirect
cosmossdk.io/log v1.3.1 // indirect
cosmossdk.io/tools/rosetta v0.2.1 // indirect
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 v1.0.0 // indirect
github.com/CosmWasm/wasmvm v1.5.2 // indirect
github.com/armon/go-metrics v0.4.1 // indirect
Expand Down
10 changes: 6 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,8 @@ cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1V
cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M=
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.4 h1:PLNp8ZYAMPTUKyG9IK2hsbciDWqna2z1Wsl98okJopc=
cosmossdk.io/depinject v1.0.0-alpha.4/go.mod h1:HeDk7IkR5ckZ3lMGs/o91AVUc7E596vMaOmslGFM3yU=
cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0=
Expand Down Expand Up @@ -354,8 +354,10 @@ github.com/cosmos/iavl v0.20.1 h1:rM1kqeG3/HBT85vsZdoSNsehciqUQPWrR4BYmqE2+zg=
github.com/cosmos/iavl v0.20.1/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A=
github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v7 v7.1.3-0.20240228213828-cce7f56d000b h1:VwhHRRIPdMshBMb2TP7xrkY4Ee8CJWsHZvucYeJ56no=
github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v7 v7.1.3-0.20240228213828-cce7f56d000b/go.mod h1:UvDmcGIWJPIytq+Q78/ff5NTOsuX/7IrNgEugTW5i0s=
github.com/cosmos/ibc-go/v7 v7.3.1 h1:bil1IjnHdyWDASFYKfwdRiNtFP6WK3osW7QFEAgU4I8=
github.com/cosmos/ibc-go/v7 v7.3.1/go.mod h1:wvx4pPBofe5ZdMNV3OFRxSI4auEP5Qfqf8JXLLNV04g=
github.com/cosmos/ibc-apps/modules/ibc-hooks/v7 v7.0.0-20240403143657-8e64543c87e0 h1:obD+CSx+aXpMEUWHLyMkWEcxLuYAcxvQaIXTwjjh3qI=
github.com/cosmos/ibc-apps/modules/ibc-hooks/v7 v7.0.0-20240403143657-8e64543c87e0/go.mod h1:JwHFbo1oX/ht4fPpnPvmhZr+dCkYK1Vihw+vZE9umR4=
github.com/cosmos/ibc-go/v7 v7.4.0 h1:8FqYMptvksgMvlbN4UW9jFxTXzsPyfAzEZurujXac8M=
github.com/cosmos/ibc-go/v7 v7.4.0/go.mod h1:L/KaEhzV5TGUCTfGysVgMBQtl5Dm7hHitfpk+GIeoAo=
github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM=
github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0=
github.com/cosmos/interchain-security/v4 v4.0.0 h1:6olP/UIrvckLgDpzJLAqPjmzo3+AoHjMM1TRrcrpME0=
Expand Down
9 changes: 5 additions & 4 deletions x/autopilot/types/autopilot.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,18 @@ import (
)

// RawPacketMetadata defines the raw JSON memo that's used in an autopilot transfer
// The PFM forward key is also used here to validate that the packet is not trying
// to use autopilot and PFM at the same time
// As a result, only the forward key is needed, cause the actual parsing of the PFM
// packet will occur in the PFM module
// The PFM forward key and wasm keys are also used here to validate that the packet
// was not trying to use more than one of autopilot PFM, and wasm at the same time
// As a result, only the key is needed, cause the actual parsing of the PFM/wasm
// packet will occur in the respective module
type RawPacketMetadata struct {
Autopilot *struct {
Receiver string `json:"receiver"`
Stakeibc *StakeibcPacketMetadata `json:"stakeibc,omitempty"`
Claim *ClaimPacketMetadata `json:"claim,omitempty"`
} `json:"autopilot"`
Forward *interface{} `json:"forward"`
Wasm *interface{} `json:"wasm"`
}

// AutopilotActionMetadata stores the metadata that's specific to the autopilot action
Expand Down
19 changes: 15 additions & 4 deletions x/autopilot/types/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,21 @@ func ParseAutopilotMetadata(metadata string) (*AutopilotMetadata, error) {
return nil, nil
}

// Packets cannot be used for both autopilot and PFM at the same time
// If both fields were provided, reject the packet
if raw.Autopilot != nil && raw.Forward != nil {
return nil, errorsmod.Wrapf(ErrInvalidPacketMetadata, "autopilot and pfm cannot both be used in the same packet")
// Packets cannot be used for more than one of autopilot, pfm, or wasmhooks at the same time
// If more than one module key was provided, reject the packet
middlewareModulesEnabled := 0
if raw.Autopilot != nil {
middlewareModulesEnabled++
}
if raw.Forward != nil {
middlewareModulesEnabled++
}
if raw.Wasm != nil {
middlewareModulesEnabled++
}
if middlewareModulesEnabled > 1 {
return nil, errorsmod.Wrapf(ErrInvalidPacketMetadata,
"only one of autopilot, pfm, and wasm can both be used in the same packet")
}

// If no forwarding logic was used for autopilot, return nil to indicate that
Expand Down
17 changes: 16 additions & 1 deletion x/autopilot/types/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,22 @@ func TestParsePacketMetadata(t *testing.T) {
{
name: "both autopilot and pfm in the memo",
metadata: `{"autopilot": {}, "forward": {}}`,
expectedErr: "autopilot and pfm cannot both be used in the same packet",
expectedErr: "only one of autopilot, pfm, and wasm can both be used in the same packet",
},
{
name: "both autopilot and wasm in the memo",
metadata: `{"autopilot": {}, "wasm": {}}`,
expectedErr: "only one of autopilot, pfm, and wasm can both be used in the same packet",
},
{
name: "both pfm and wasm in the memo",
metadata: `{"forward": {}, "wasm": {}}`,
expectedErr: "only one of autopilot, pfm, and wasm can both be used in the same packet",
},
{
name: "autopilot, pfm, and wasm in the memo",
metadata: `{"autopilot": {}, "pfm": {}, "wasm": {}}`,
expectedErr: "only one of autopilot, pfm, and wasm can both be used in the same packet",
},
{
name: "empty receiver address",
Expand Down

0 comments on commit b27e712

Please sign in to comment.