diff --git a/CHANGELOG.md b/CHANGELOG.md index 46f412d48..dade1db65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -84,6 +84,7 @@ for (1) ERC20 transfers with tokens that return false success values instead of throwing an error and (2) ERC20 transfers with other operations that don't bring about the expected resulting balance for the transfer recipient. - [#2092](https://github.com/NibiruChain/nibiru/pull/2092) - feat(evm): add validation for wasm multi message execution +- [#2068](https://github.com/NibiruChain/nibiru/pull/2068) - feat: enable wasm light clients on IBC (08-wasm) - [#2101](https://github.com/NibiruChain/nibiru/pull/2101) - fix(evm): tx receipt proper marshalling #### Nibiru EVM | Before Audit 1 - 2024-10-18 diff --git a/app/app.go b/app/app.go index 9230a3553..2bc2618de 100644 --- a/app/app.go +++ b/app/app.go @@ -10,6 +10,9 @@ import ( wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + cmtos "github.com/cometbft/cometbft/libs/os" + cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" + ibcwasmkeeper "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/keeper" "github.com/NibiruChain/nibiru/v2/app/ante" "github.com/NibiruChain/nibiru/v2/app/wasmext" @@ -240,6 +243,10 @@ func NewNibiruApp( app.CommitMultiStore(), &app.WasmKeeper, ), + ibcwasmkeeper.NewWasmSnapshotter( + app.CommitMultiStore(), + &app.WasmClientKeeper, + ), ); err != nil { panic("failed to add wasm snapshot extension.") } @@ -250,6 +257,13 @@ func NewNibiruApp( tmos.Exit(err.Error()) } + ctx := app.BaseApp.NewUncachedContext(true, cmtproto.Header{}) + + // Initialize pinned codes in wasmvm as they are not persisted there + if err := ibcwasmkeeper.InitializePinnedCodes(ctx, app.appCodec); err != nil { + cmtos.Exit(fmt.Sprintf("failed to initialize pinned codes %s", err)) + } + /* Applications that wish to enforce statically created ScopedKeepers should call `Seal` after creating their scoped modules in `NewApp` with `capabilityKeeper.ScopeToModule`. diff --git a/app/keepers.go b/app/keepers.go index 4c5721e83..156ef6413 100644 --- a/app/keepers.go +++ b/app/keepers.go @@ -4,6 +4,8 @@ import ( "path/filepath" "strings" + ibcwasm "github.com/cosmos/ibc-go/modules/light-clients/08-wasm" + ibcwasmkeeper "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/keeper" 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" @@ -16,6 +18,7 @@ import ( "github.com/CosmWasm/wasmd/x/wasm" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + wasmvm "github.com/CosmWasm/wasmvm" _ "github.com/cosmos/cosmos-sdk/client/docs/statik" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" @@ -84,6 +87,7 @@ import ( // --------------------------------------------------------------- // IBC imports + ibcwasmtypes "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types" icahostkeeper "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/keeper" ibcfee "github.com/cosmos/ibc-go/v7/modules/apps/29-fee" ibcfeekeeper "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/keeper" @@ -121,7 +125,7 @@ import ( "github.com/NibiruChain/nibiru/v2/x/inflation" inflationkeeper "github.com/NibiruChain/nibiru/v2/x/inflation/keeper" inflationtypes "github.com/NibiruChain/nibiru/v2/x/inflation/types" - oracle "github.com/NibiruChain/nibiru/v2/x/oracle" + "github.com/NibiruChain/nibiru/v2/x/oracle" oraclekeeper "github.com/NibiruChain/nibiru/v2/x/oracle/keeper" oracletypes "github.com/NibiruChain/nibiru/v2/x/oracle/types" @@ -129,11 +133,13 @@ import ( "github.com/NibiruChain/nibiru/v2/x/sudo/keeper" sudotypes "github.com/NibiruChain/nibiru/v2/x/sudo/types" - tokenfactory "github.com/NibiruChain/nibiru/v2/x/tokenfactory" + "github.com/NibiruChain/nibiru/v2/x/tokenfactory" tokenfactorykeeper "github.com/NibiruChain/nibiru/v2/x/tokenfactory/keeper" tokenfactorytypes "github.com/NibiruChain/nibiru/v2/x/tokenfactory/types" ) +const wasmVmContractMemoryLimit = 32 + type AppKeepers struct { keepers.PublicKeepers privateKeepers @@ -193,6 +199,7 @@ func initStoreKeys() ( ibcexported.StoreKey, icahosttypes.StoreKey, icacontrollertypes.StoreKey, + ibcwasmtypes.StoreKey, // nibiru x/ keys oracletypes.StoreKey, @@ -253,7 +260,7 @@ func (app *NibiruApp) InitKeepers( // seal capability keeper after scoping modules // app.capabilityKeeper.Seal() - // TODO: chore(upgrade): Potential breaking change on AccountKeeper dur + // TODO: chore(upgrade): Potential breaking change on AccountKeeper due // to ProtoBaseAccount replacement. app.AccountKeeper = authkeeper.NewAccountKeeper( appCodec, @@ -450,6 +457,13 @@ func (app *NibiruApp) InitKeepers( // For example, if there are bindings for the x/inflation module, then the app // passed to GetWasmOpts must already have a non-nil InflationKeeper. supportedFeatures := strings.Join(wasmdapp.AllCapabilities(), ",") + + // Create wasm VM outside keeper so it can be re-used in client keeper + wasmVM, err := wasmvm.NewVM(filepath.Join(wasmDir, "wasm"), supportedFeatures, wasmVmContractMemoryLimit, wasmConfig.ContractDebugMode, wasmConfig.MemoryCacheSize) + if err != nil { + panic(err) + } + app.WasmKeeper = wasmkeeper.NewKeeper( appCodec, keys[wasmtypes.StoreKey], @@ -468,7 +482,16 @@ func (app *NibiruApp) InitKeepers( wasmConfig, supportedFeatures, govModuleAddr, - GetWasmOpts(*app, appOpts)..., + append(GetWasmOpts(*app, appOpts), wasmkeeper.WithWasmEngine(wasmVM))..., + ) + + app.WasmClientKeeper = ibcwasmkeeper.NewKeeperWithVM( + appCodec, + keys[ibcwasmtypes.StoreKey], + app.ibcKeeper.ClientKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + wasmVM, + app.GRPCQueryRouter(), ) // DevGas uses WasmKeeper @@ -632,6 +655,7 @@ func (app *NibiruApp) initAppModules( ibctransfer.NewAppModule(app.ibcTransferKeeper), ibcfee.NewAppModule(app.ibcFeeKeeper), ica.NewAppModule(&app.icaControllerKeeper, &app.icaHostKeeper), + ibcwasm.NewAppModule(app.WasmClientKeeper), evmmodule.NewAppModule(&app.EvmKeeper, app.AccountKeeper), @@ -703,6 +727,7 @@ func orderedModuleNames() []string { ibcexported.ModuleName, ibcfeetypes.ModuleName, icatypes.ModuleName, + ibcwasmtypes.ModuleName, // -------------------------------------------------------------------- evm.ModuleName, @@ -809,6 +834,7 @@ func ModuleBasicManager() module.BasicManager { ibctransfer.AppModuleBasic{}, ibctm.AppModuleBasic{}, ica.AppModuleBasic{}, + ibcwasm.AppModuleBasic{}, // native x/ evmmodule.AppModuleBasic{}, oracle.AppModuleBasic{}, diff --git a/app/keepers/all_keepers.go b/app/keepers/all_keepers.go index 7bbdc9c10..25303860f 100644 --- a/app/keepers/all_keepers.go +++ b/app/keepers/all_keepers.go @@ -10,6 +10,7 @@ import ( distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" feegrantkeeper "github.com/cosmos/cosmos-sdk/x/feegrant/keeper" govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" + ibcwasmkeeper "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/keeper" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" @@ -68,4 +69,5 @@ type PublicKeepers struct { // WASM keepers WasmKeeper wasmkeeper.Keeper ScopedWasmKeeper capabilitykeeper.ScopedKeeper + WasmClientKeeper ibcwasmkeeper.Keeper } diff --git a/app/upgrades.go b/app/upgrades.go index 3f9851fd4..6c547c390 100644 --- a/app/upgrades.go +++ b/app/upgrades.go @@ -10,6 +10,7 @@ import ( "github.com/NibiruChain/nibiru/v2/app/upgrades/v1_2_0" "github.com/NibiruChain/nibiru/v2/app/upgrades/v1_3_0" "github.com/NibiruChain/nibiru/v2/app/upgrades/v1_4_0" + "github.com/NibiruChain/nibiru/v2/app/upgrades/v2_1_0" ) var Upgrades = []upgrades.Upgrade{ @@ -17,6 +18,7 @@ var Upgrades = []upgrades.Upgrade{ v1_2_0.Upgrade, v1_3_0.Upgrade, v1_4_0.Upgrade, + v2_1_0.Upgrade, } func (app *NibiruApp) setupUpgrades() { @@ -26,7 +28,7 @@ func (app *NibiruApp) setupUpgrades() { func (app *NibiruApp) setUpgradeHandlers() { for _, u := range Upgrades { - app.upgradeKeeper.SetUpgradeHandler(u.UpgradeName, u.CreateUpgradeHandler(app.ModuleManager, app.configurator)) + app.upgradeKeeper.SetUpgradeHandler(u.UpgradeName, u.CreateUpgradeHandler(app.ModuleManager, app.configurator, app.ibcKeeper.ClientKeeper)) } } diff --git a/app/upgrades/types.go b/app/upgrades/types.go index a2cdde4b5..88dd83c13 100644 --- a/app/upgrades/types.go +++ b/app/upgrades/types.go @@ -4,12 +4,14 @@ import ( store "github.com/cosmos/cosmos-sdk/store/types" "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/x/upgrade/types" + + clientkeeper "github.com/cosmos/ibc-go/v7/modules/core/02-client/keeper" ) type Upgrade struct { UpgradeName string - CreateUpgradeHandler func(*module.Manager, module.Configurator) types.UpgradeHandler + CreateUpgradeHandler func(*module.Manager, module.Configurator, clientkeeper.Keeper) types.UpgradeHandler StoreUpgrades store.StoreUpgrades } diff --git a/app/upgrades/v1_1_0/constants.go b/app/upgrades/v1_1_0/constants.go index 4fdebdf6c..bd119eb7a 100644 --- a/app/upgrades/v1_1_0/constants.go +++ b/app/upgrades/v1_1_0/constants.go @@ -5,6 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + clientkeeper "github.com/cosmos/ibc-go/v7/modules/core/02-client/keeper" "github.com/NibiruChain/nibiru/v2/app/upgrades" inflationtypes "github.com/NibiruChain/nibiru/v2/x/inflation/types" @@ -14,7 +15,7 @@ const UpgradeName = "v1.1.0" var Upgrade = upgrades.Upgrade{ UpgradeName: UpgradeName, - CreateUpgradeHandler: func(mm *module.Manager, cfg module.Configurator) upgradetypes.UpgradeHandler { + CreateUpgradeHandler: func(mm *module.Manager, cfg module.Configurator, clientKeeper clientkeeper.Keeper) upgradetypes.UpgradeHandler { return func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { return mm.RunMigrations(ctx, cfg, fromVM) } diff --git a/app/upgrades/v1_2_0/constants.go b/app/upgrades/v1_2_0/constants.go index 63718c21d..0805d4b66 100644 --- a/app/upgrades/v1_2_0/constants.go +++ b/app/upgrades/v1_2_0/constants.go @@ -5,6 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + clientkeeper "github.com/cosmos/ibc-go/v7/modules/core/02-client/keeper" "github.com/NibiruChain/nibiru/v2/app/upgrades" ) @@ -13,7 +14,7 @@ const UpgradeName = "v1.2.0" var Upgrade = upgrades.Upgrade{ UpgradeName: UpgradeName, - CreateUpgradeHandler: func(mm *module.Manager, cfg module.Configurator) upgradetypes.UpgradeHandler { + CreateUpgradeHandler: func(mm *module.Manager, cfg module.Configurator, clientKeeper clientkeeper.Keeper) upgradetypes.UpgradeHandler { return func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { return mm.RunMigrations(ctx, cfg, fromVM) } diff --git a/app/upgrades/v1_3_0/constants.go b/app/upgrades/v1_3_0/constants.go index 320bdae7c..263817ac0 100644 --- a/app/upgrades/v1_3_0/constants.go +++ b/app/upgrades/v1_3_0/constants.go @@ -14,6 +14,7 @@ import ( icahosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + clientkeeper "github.com/cosmos/ibc-go/v7/modules/core/02-client/keeper" "github.com/NibiruChain/nibiru/v2/app/upgrades" ) @@ -22,7 +23,7 @@ const UpgradeName = "v1.3.0" var Upgrade = upgrades.Upgrade{ UpgradeName: UpgradeName, - CreateUpgradeHandler: func(mm *module.Manager, cfg module.Configurator) upgradetypes.UpgradeHandler { + CreateUpgradeHandler: func(mm *module.Manager, cfg module.Configurator, clientKeeper clientkeeper.Keeper) upgradetypes.UpgradeHandler { return func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { // set the ICS27 consensus version so InitGenesis is not run fromVM[icatypes.ModuleName] = mm.GetVersionMap()[icatypes.ModuleName] diff --git a/app/upgrades/v1_4_0/constants.go b/app/upgrades/v1_4_0/constants.go index fbfa766ea..28d53df22 100644 --- a/app/upgrades/v1_4_0/constants.go +++ b/app/upgrades/v1_4_0/constants.go @@ -5,6 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + clientkeeper "github.com/cosmos/ibc-go/v7/modules/core/02-client/keeper" "github.com/NibiruChain/nibiru/v2/app/upgrades" ) @@ -13,7 +14,7 @@ const UpgradeName = "v1.4.0" var Upgrade = upgrades.Upgrade{ UpgradeName: UpgradeName, - CreateUpgradeHandler: func(mm *module.Manager, cfg module.Configurator) upgradetypes.UpgradeHandler { + CreateUpgradeHandler: func(mm *module.Manager, cfg module.Configurator, clientKeeper clientkeeper.Keeper) upgradetypes.UpgradeHandler { return func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { return mm.RunMigrations(ctx, cfg, fromVM) } diff --git a/app/upgrades/v2_1_0/constants.go b/app/upgrades/v2_1_0/constants.go new file mode 100644 index 000000000..f294c66a4 --- /dev/null +++ b/app/upgrades/v2_1_0/constants.go @@ -0,0 +1,42 @@ +package v2_1_0 + +import ( + "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + ibcwasmtypes "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types" + clientkeeper "github.com/cosmos/ibc-go/v7/modules/core/02-client/keeper" + + "github.com/NibiruChain/nibiru/v2/app/upgrades" +) + +const UpgradeName = "v2.1.0" + +var Upgrade = upgrades.Upgrade{ + UpgradeName: UpgradeName, + CreateUpgradeHandler: func(mm *module.Manager, cfg module.Configurator, clientKeeper clientkeeper.Keeper) upgradetypes.UpgradeHandler { + return func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { + // explicitly update the IBC 02-client params, adding the wasm client type if it is not there + params := clientKeeper.GetParams(ctx) + + hasWasmClient := false + for _, client := range params.AllowedClients { + if client == ibcwasmtypes.Wasm { + hasWasmClient = true + break + } + } + + if !hasWasmClient { + params.AllowedClients = append(params.AllowedClients, ibcwasmtypes.Wasm) + clientKeeper.SetParams(ctx, params) + } + + return mm.RunMigrations(ctx, cfg, fromVM) + } + }, + StoreUpgrades: types.StoreUpgrades{ + Added: []string{ibcwasmtypes.ModuleName}, + }, +} diff --git a/cmd/nibid/cmd/init.go b/cmd/nibid/cmd/init.go index 1d8c439a9..13de92198 100644 --- a/cmd/nibid/cmd/init.go +++ b/cmd/nibid/cmd/init.go @@ -8,6 +8,7 @@ import ( "path/filepath" tmcfg "github.com/cometbft/cometbft/config" + ibcwasmtypes "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types" "github.com/NibiruChain/nibiru/v2/app/appconst" @@ -25,6 +26,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/x/genutil" + + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" + ibctypes "github.com/cosmos/ibc-go/v7/modules/core/types" ) const ( @@ -129,6 +133,11 @@ func InitCmd(mbm module.BasicManager, defaultNodeHome string) *cobra.Command { } appGenState := mbm.DefaultGenesis(cdc) + // add 08-wasm to AllowedClients + ibcState := ibctypes.DefaultGenesisState() + ibcState.ClientGenesis.Params.AllowedClients = append(ibcState.ClientGenesis.Params.AllowedClients, ibcwasmtypes.Wasm) + appGenState[ibcexported.ModuleName] = cdc.MustMarshalJSON(ibcState) + appState, err := json.MarshalIndent(appGenState, "", " ") if err != nil { return errors.Wrap(err, "Failed to marshal default genesis state") diff --git a/go.mod b/go.mod index bc14078f3..99e351a4e 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( // Cosmos-SDK and IBC github.com/cosmos/cosmos-proto v1.0.0-beta.5 github.com/cosmos/cosmos-sdk v0.47.11 - github.com/cosmos/ibc-go/v7 v7.3.2 + github.com/cosmos/ibc-go/v7 v7.4.0 github.com/ethereum/go-ethereum v1.10.17 ) @@ -57,6 +57,7 @@ require ( require ( cosmossdk.io/collections v0.4.0 cosmossdk.io/tools/rosetta v0.2.1 + github.com/cosmos/ibc-go/modules/light-clients/08-wasm v0.3.2-0.20240730185603-13c071f0b34d github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc github.com/gorilla/websocket v1.5.0 github.com/rs/cors v1.8.3 diff --git a/go.sum b/go.sum index 213ee9c84..616630872 100644 --- a/go.sum +++ b/go.sum @@ -438,8 +438,10 @@ 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.20.0 h1:fTVznVlepH0KK8NyKq8w+U7c2L6jofa27aFX6YGlm38= github.com/cosmos/iavl v0.20.0/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= -github.com/cosmos/ibc-go/v7 v7.3.2 h1:FeUDcBX7VYY0e0iRmcVkPPUjYfAqIc//QuHXo8JHz9c= -github.com/cosmos/ibc-go/v7 v7.3.2/go.mod h1:IMeOXb7gwpZ+/nOG5BuUkdW4weM1ezvN4PQPws4uzOI= +github.com/cosmos/ibc-go/modules/light-clients/08-wasm v0.3.2-0.20240730185603-13c071f0b34d h1:QJK/Zr0HblNx6z1x5LXIHEblY7DCCftMkUBcjpKe1qY= +github.com/cosmos/ibc-go/modules/light-clients/08-wasm v0.3.2-0.20240730185603-13c071f0b34d/go.mod h1:5oIHokzX6RJ6q93tLcWZ7Thkrt9vrMGIz3He9HFE660= +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/ledger-cosmos-go v0.12.4 h1:drvWt+GJP7Aiw550yeb3ON/zsrgW0jgh5saFCr7pDnw=