diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fc4c212a5b1..0e6f2a2764d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -171,6 +171,10 @@ jobs: - name: Install New Gaiad run: | git checkout - + curl -LO https://github.com/CosmWasm/wasmvm/releases/download/v1.5.0/libwasmvm.x86_64.so + curl -LO https://github.com/CosmWasm/wasmvm/releases/download/v1.5.0/libwasmvm.aarch64.so + uname -m + sudo cp "./libwasmvm.$(uname -m).so" /usr/lib/ make build cp ./build/gaiad ./build/gaiadnew go clean -modcache diff --git a/.golangci.yml b/.golangci.yml index 6eae92cbe71..27580c5f993 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -68,6 +68,7 @@ linters-settings: - prefix(github.com/cosmos) # cosmos org - prefix(cosmossdk.io) # new modules - prefix(github.com/cosmos/cosmos-sdk) # cosmos sdk + - prefix(github.com/CosmWasm/wasmd) # cosmwasm - prefix(github.com/cosmos/gaia) # Gaia dogsled: max-blank-identifiers: 3 diff --git a/.goreleaser.yml b/.goreleaser.yml index 64776146a60..4b81ae8778c 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -20,7 +20,6 @@ builds: goos: - darwin - linux - - windows goarch: - amd64 - arm64 diff --git a/Dockerfile b/Dockerfile index b27042c0886..88d4e2a1edc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,19 +1,31 @@ ARG IMG_TAG=latest # Compile the gaiad binary -FROM golang:1.21-alpine AS gaiad-builder +FROM golang:1.21-alpine3.18 AS gaiad-builder WORKDIR /src/app/ +ENV PACKAGES="curl make git libc-dev bash file gcc linux-headers eudev-dev python3" +RUN apk add --no-cache $PACKAGES + +# See https://github.com/CosmWasm/wasmvm/releases +ARG WASMVM_VERSION=v1.5.0 +ADD https://github.com/CosmWasm/wasmvm/releases/download/${WASMVM_VERSION}/libwasmvm_muslc.aarch64.a /lib/libwasmvm_muslc.aarch64.a +ADD https://github.com/CosmWasm/wasmvm/releases/download/${WASMVM_VERSION}/libwasmvm_muslc.x86_64.a /lib/libwasmvm_muslc.x86_64.a +RUN sha256sum /lib/libwasmvm_muslc.aarch64.a | grep 2687afbdae1bc6c7c8b05ae20dfb8ffc7ddc5b4e056697d0f37853dfe294e913 +RUN sha256sum /lib/libwasmvm_muslc.x86_64.a | grep 465e3a088e96fd009a11bfd234c69fb8a0556967677e54511c084f815cf9ce63 +RUN cp "/lib/libwasmvm_muslc.$(uname -m).a" /lib/libwasmvm_muslc.a + COPY go.mod go.sum* ./ RUN go mod download + COPY . . -ENV PACKAGES curl make git libc-dev bash gcc linux-headers eudev-dev python3 -RUN apk add --no-cache $PACKAGES -RUN CGO_ENABLED=0 make install +RUN LEDGER_ENABLED=false LINK_STATICALLY=true BUILD_TAGS=muslc make build +RUN echo "Ensuring binary is statically linked ..." \ + && file /src/app/build/gaiad | grep "statically linked" # Add to a distroless container FROM cgr.dev/chainguard/static:$IMG_TAG ARG IMG_TAG -COPY --from=gaiad-builder /go/bin/gaiad /usr/local/bin/ +COPY --from=gaiad-builder /src/app/build/gaiad /usr/local/bin/ EXPOSE 26656 26657 1317 9090 USER 0 diff --git a/Makefile b/Makefile index 973971b80b3..94bbd5a30ae 100644 --- a/Makefile +++ b/Makefile @@ -74,6 +74,9 @@ ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=gaia \ ifeq (cleveldb,$(findstring cleveldb,$(GAIA_BUILD_OPTIONS))) ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=cleveldb endif +ifeq ($(LINK_STATICALLY),true) + ldflags += -linkmode=external -extldflags "-Wl,-z,muldefs -static" +endif ifeq (,$(findstring nostrip,$(GAIA_BUILD_OPTIONS))) ldflags += -w -s endif diff --git a/ante/ante.go b/ante/ante.go index 5ac37a30ebb..6833dedceff 100644 --- a/ante/ante.go +++ b/ante/ante.go @@ -10,10 +10,14 @@ import ( errorsmod "cosmossdk.io/errors" "github.com/cosmos/cosmos-sdk/codec" + storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth/ante" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + gaiaerrors "github.com/cosmos/gaia/v18/types/errors" ) @@ -24,11 +28,13 @@ var UseFeeMarketDecorator = true // channel keeper. type HandlerOptions struct { ante.HandlerOptions - Codec codec.BinaryCodec - IBCkeeper *ibckeeper.Keeper - StakingKeeper *stakingkeeper.Keeper - FeeMarketKeeper *feemarketkeeper.Keeper - TxFeeChecker ante.TxFeeChecker + Codec codec.BinaryCodec + IBCkeeper *ibckeeper.Keeper + StakingKeeper *stakingkeeper.Keeper + FeeMarketKeeper *feemarketkeeper.Keeper + TxFeeChecker ante.TxFeeChecker + TxCounterStoreKey storetypes.StoreKey + WasmConfig *wasmtypes.WasmConfig } func NewAnteHandler(opts HandlerOptions) (sdk.AnteHandler, error) { @@ -58,7 +64,9 @@ func NewAnteHandler(opts HandlerOptions) (sdk.AnteHandler, error) { } anteDecorators := []sdk.AnteDecorator{ - ante.NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first + ante.NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first + wasmkeeper.NewLimitSimulationGasDecorator(opts.WasmConfig.SimulationGasLimit), // after setup context to enforce limits early + wasmkeeper.NewCountTXDecorator(opts.TxCounterStoreKey), ante.NewExtensionOptionsDecorator(opts.ExtensionOptionChecker), ante.NewValidateBasicDecorator(), ante.NewTxTimeoutHeightDecorator(), diff --git a/app/app.go b/app/app.go index 590e0aced5f..e81243547c7 100644 --- a/app/app.go +++ b/app/app.go @@ -20,6 +20,7 @@ import ( tmjson "github.com/cometbft/cometbft/libs/json" "github.com/cometbft/cometbft/libs/log" tmos "github.com/cometbft/cometbft/libs/os" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" ibctesting "github.com/cosmos/ibc-go/v7/testing" providertypes "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" @@ -52,6 +53,10 @@ import ( govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + wasm "github.com/CosmWasm/wasmd/x/wasm" + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + gaiaante "github.com/cosmos/gaia/v18/ante" "github.com/cosmos/gaia/v18/app/keepers" "github.com/cosmos/gaia/v18/app/params" @@ -112,6 +117,7 @@ func NewGaiaApp( homePath string, encodingConfig params.EncodingConfig, appOpts servertypes.AppOptions, + wasmOpts []wasmkeeper.Option, baseAppOptions ...func(*baseapp.BaseApp), ) *GaiaApp { appCodec := encodingConfig.Marshaler @@ -159,6 +165,7 @@ func NewGaiaApp( invCheckPeriod, logger, appOpts, + wasmOpts, ) // NOTE: Any module instantiated in the module manager that is later modified @@ -214,6 +221,11 @@ func NewGaiaApp( app.MountTransientStores(app.GetTransientStoreKey()) app.MountMemoryStores(app.GetMemoryStoreKey()) + wasmConfig, err := wasm.ReadWasmConfig(appOpts) + if err != nil { + panic("error while reading wasm config: " + err.Error()) + } + anteHandler, err := gaiaante.NewAnteHandler( gaiaante.HandlerOptions{ HandlerOptions: ante.HandlerOptions{ @@ -223,10 +235,12 @@ func NewGaiaApp( SignModeHandler: encodingConfig.TxConfig.SignModeHandler(), SigGasConsumer: ante.DefaultSigVerificationGasConsumer, }, - Codec: appCodec, - IBCkeeper: app.IBCKeeper, - StakingKeeper: app.StakingKeeper, - FeeMarketKeeper: app.FeeMarketKeeper, + Codec: appCodec, + IBCkeeper: app.IBCKeeper, + StakingKeeper: app.StakingKeeper, + FeeMarketKeeper: app.FeeMarketKeeper, + WasmConfig: &wasmConfig, + TxCounterStoreKey: app.AppKeepers.GetKey(wasmtypes.StoreKey), TxFeeChecker: func(ctx sdk.Context, tx sdk.Tx) (sdk.Coins, int64, error) { return minTxFeesChecker(ctx, tx, *app.FeeMarketKeeper) }, @@ -255,6 +269,13 @@ func NewGaiaApp( app.SetBeginBlocker(app.BeginBlocker) app.SetEndBlocker(app.EndBlocker) + if manager := app.SnapshotManager(); manager != nil { + err = manager.RegisterExtensions(wasmkeeper.NewWasmSnapshotter(app.CommitMultiStore(), &app.AppKeepers.WasmKeeper)) + if err != nil { + panic("failed to register snapshot extension: " + err.Error()) + } + } + app.setupUpgradeHandlers() app.setupUpgradeStoreLoaders() @@ -262,6 +283,12 @@ func NewGaiaApp( if err := app.LoadLatestVersion(); err != nil { tmos.Exit(fmt.Sprintf("failed to load latest version: %s", err)) } + + ctx := app.BaseApp.NewUncachedContext(true, tmproto.Header{}) + + if err := app.AppKeepers.WasmKeeper.InitializePinnedCodes(ctx); err != nil { + tmos.Exit(fmt.Sprintf("WasmKeeper failed initialize pinned codes %s", err)) + } } return app @@ -451,6 +478,9 @@ func (app *GaiaApp) GetTxConfig() client.TxConfig { // EmptyAppOptions is a stub implementing AppOptions type EmptyAppOptions struct{} +// EmptyWasmOptions is a stub implementing Wasmkeeper Option +var EmptyWasmOptions []wasmkeeper.Option + // Get implements AppOptions func (ao EmptyAppOptions) Get(_ string) interface{} { return nil diff --git a/app/app_test.go b/app/app_test.go index 267462d81ad..cd50d09ae8d 100644 --- a/app/app_test.go +++ b/app/app_test.go @@ -11,12 +11,16 @@ import ( authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" + gaia "github.com/cosmos/gaia/v18/app" gaiahelpers "github.com/cosmos/gaia/v18/app/helpers" ) type EmptyAppOptions struct{} +var emptyWasmOption []wasmkeeper.Option + func (ao EmptyAppOptions) Get(_ string) interface{} { return nil } @@ -32,6 +36,7 @@ func TestGaiaApp_BlockedModuleAccountAddrs(t *testing.T) { gaia.DefaultNodeHome, encConfig, EmptyAppOptions{}, + emptyWasmOption, ) moduleAccountAddresses := app.ModuleAccountAddrs() diff --git a/app/helpers/test_helpers.go b/app/helpers/test_helpers.go index 3092214150a..894d921c0e7 100644 --- a/app/helpers/test_helpers.go +++ b/app/helpers/test_helpers.go @@ -24,6 +24,8 @@ import ( banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" + gaiaapp "github.com/cosmos/gaia/v18/app" ) @@ -121,6 +123,7 @@ func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs func setup() (*gaiaapp.GaiaApp, gaiaapp.GenesisState) { db := dbm.NewMemDB() appOptions := make(simtestutil.AppOptionsMap, 0) + emptyWasmOpts := []wasmkeeper.Option{} appOptions[server.FlagInvCheckPeriod] = 5 appOptions[server.FlagMinGasPrices] = "0uatom" @@ -135,6 +138,7 @@ func setup() (*gaiaapp.GaiaApp, gaiaapp.GenesisState) { gaiaapp.DefaultNodeHome, encConfig, appOptions, + emptyWasmOpts, ) return gaiaApp, gaiaapp.NewDefaultGenesisState(encConfig) } diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index 7f9a5774964..d9279ec7c6c 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -3,6 +3,7 @@ package keepers import ( "fmt" "os" + "strings" ratelimit "github.com/Stride-Labs/ibc-rate-limiting/ratelimit" ratelimitkeeper "github.com/Stride-Labs/ibc-rate-limiting/ratelimit/keeper" @@ -80,6 +81,11 @@ import ( "github.com/cosmos/cosmos-sdk/x/upgrade" upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + + wasmapp "github.com/CosmWasm/wasmd/app" + "github.com/CosmWasm/wasmd/x/wasm" + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" ) type AppKeepers struct { @@ -100,6 +106,7 @@ type AppKeepers struct { CrisisKeeper *crisiskeeper.Keeper UpgradeKeeper *upgradekeeper.Keeper ParamsKeeper paramskeeper.Keeper + WasmKeeper wasmkeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly IBCKeeper *ibckeeper.Keeper ICAHostKeeper icahostkeeper.Keeper @@ -131,6 +138,7 @@ type AppKeepers struct { ScopedICAHostKeeper capabilitykeeper.ScopedKeeper ScopedICAControllerKeeper capabilitykeeper.ScopedKeeper ScopedICSproviderkeeper capabilitykeeper.ScopedKeeper + scopedWasmKeeper capabilitykeeper.ScopedKeeper } func NewAppKeeper( @@ -145,6 +153,7 @@ func NewAppKeeper( invCheckPeriod uint, logger log.Logger, appOpts servertypes.AppOptions, + wasmOpts []wasmkeeper.Option, ) AppKeepers { appKeepers := AppKeepers{} @@ -189,6 +198,7 @@ func NewAppKeeper( appKeepers.ScopedICAControllerKeeper = appKeepers.CapabilityKeeper.ScopeToModule(icacontrollertypes.SubModuleName) appKeepers.ScopedTransferKeeper = appKeepers.CapabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName) appKeepers.ScopedICSproviderkeeper = appKeepers.CapabilityKeeper.ScopeToModule(providertypes.ModuleName) + appKeepers.scopedWasmKeeper = appKeepers.CapabilityKeeper.ScopeToModule(wasmtypes.ModuleName) // Applications that wish to enforce statically created ScopedKeepers should call `Seal` after creating // their scoped modules in `NewApp` with `ScopeToModule` @@ -447,6 +457,31 @@ func NewAppKeeper( // Must be called on PFMRouter AFTER TransferKeeper initialized appKeepers.PFMRouterKeeper.SetTransferKeeper(appKeepers.TransferKeeper) + wasmConfig, err := wasm.ReadWasmConfig(appOpts) + if err != nil { + panic("error while reading wasm config: " + err.Error()) + } + + appKeepers.WasmKeeper = wasmkeeper.NewKeeper( + appCodec, + appKeepers.keys[wasmtypes.StoreKey], + appKeepers.AccountKeeper, + appKeepers.BankKeeper, + appKeepers.StakingKeeper, + distrkeeper.NewQuerier(appKeepers.DistrKeeper), + appKeepers.IBCKeeper.ChannelKeeper, + appKeepers.IBCKeeper.ChannelKeeper, + &appKeepers.IBCKeeper.PortKeeper, + appKeepers.scopedWasmKeeper, + appKeepers.TransferKeeper, + bApp.MsgServiceRouter(), + bApp.GRPCQueryRouter(), + homePath, + wasmConfig, + strings.Join(wasmapp.AllCapabilities(), ","), + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + // Middleware Stacks appKeepers.ICAModule = ica.NewAppModule(&appKeepers.ICAControllerKeeper, &appKeepers.ICAHostKeeper) appKeepers.TransferModule = transfer.NewAppModule(appKeepers.TransferKeeper) @@ -484,12 +519,17 @@ func NewAppKeeper( // Create Interchain Accounts Controller Stack var icaControllerStack porttypes.IBCModule = icacontroller.NewIBCMiddleware(nil, appKeepers.ICAControllerKeeper) + var wasmStack porttypes.IBCModule + wasmStack = wasm.NewIBCHandler(appKeepers.WasmKeeper, appKeepers.IBCKeeper.ChannelKeeper, appKeepers.IBCFeeKeeper) + wasmStack = ibcfee.NewIBCMiddleware(wasmStack, appKeepers.IBCFeeKeeper) + // Create IBC Router & seal ibcRouter := porttypes.NewRouter(). AddRoute(icahosttypes.SubModuleName, icaHostStack). AddRoute(icacontrollertypes.SubModuleName, icaControllerStack). AddRoute(ibctransfertypes.ModuleName, transferStack). - AddRoute(providertypes.ModuleName, appKeepers.ProviderModule) + AddRoute(providertypes.ModuleName, appKeepers.ProviderModule). + AddRoute(wasmtypes.ModuleName, wasmStack) appKeepers.IBCKeeper.SetRouter(ibcRouter) @@ -509,8 +549,7 @@ func (appKeepers *AppKeepers) GetSubspace(moduleName string) paramstypes.Subspac func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino, key, tkey storetypes.StoreKey) paramskeeper.Keeper { paramsKeeper := paramskeeper.NewKeeper(appCodec, legacyAmino, key, tkey) - //nolint: staticcheck // SA1019: moduletypes.ParamKeyTable is deprecated - paramsKeeper.Subspace(authtypes.ModuleName).WithKeyTable(authtypes.ParamKeyTable()) + paramsKeeper.Subspace(authtypes.ModuleName).WithKeyTable(authtypes.ParamKeyTable()) //nolint: staticcheck // SA1019 paramsKeeper.Subspace(stakingtypes.ModuleName).WithKeyTable(stakingtypes.ParamKeyTable()) paramsKeeper.Subspace(banktypes.ModuleName).WithKeyTable(banktypes.ParamKeyTable()) //nolint: staticcheck // SA1019 paramsKeeper.Subspace(minttypes.ModuleName).WithKeyTable(minttypes.ParamKeyTable()) //nolint: staticcheck // SA1019 @@ -525,6 +564,7 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino paramsKeeper.Subspace(pfmroutertypes.ModuleName).WithKeyTable(pfmroutertypes.ParamKeyTable()) paramsKeeper.Subspace(ratelimittypes.ModuleName) paramsKeeper.Subspace(providertypes.ModuleName) + paramsKeeper.Subspace(wasmtypes.ModuleName) return paramsKeeper } diff --git a/app/keepers/keys.go b/app/keepers/keys.go index 4b036dc9f28..d1857a9ec43 100644 --- a/app/keepers/keys.go +++ b/app/keepers/keys.go @@ -29,6 +29,8 @@ import ( slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" ) func (appKeepers *AppKeepers) GenerateKeys() { @@ -59,6 +61,7 @@ func (appKeepers *AppKeepers) GenerateKeys() { providertypes.StoreKey, consensusparamtypes.StoreKey, feemarkettypes.StoreKey, + wasmtypes.StoreKey, ) // Define transient store keys diff --git a/app/modules.go b/app/modules.go index 1e4f2858712..29a3a1e0d36 100644 --- a/app/modules.go +++ b/app/modules.go @@ -62,6 +62,9 @@ import ( upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + wasm "github.com/CosmWasm/wasmd/x/wasm" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + gaiaappparams "github.com/cosmos/gaia/v18/app/params" "github.com/cosmos/gaia/v18/x/metaprotocols" metaprotocolstypes "github.com/cosmos/gaia/v18/x/metaprotocols/types" @@ -79,6 +82,7 @@ var maccPerms = map[string][]string{ ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, ibcfeetypes.ModuleName: nil, providertypes.ConsumerRewardsPool: nil, + wasmtypes.ModuleName: {authtypes.Burner}, feemarkettypes.ModuleName: nil, feemarkettypes.FeeCollectorName: nil, } @@ -124,6 +128,7 @@ var ModuleBasics = module.NewBasicManager( icsprovider.AppModuleBasic{}, consensus.AppModuleBasic{}, metaprotocols.AppModuleBasic{}, + wasm.AppModuleBasic{}, feemarket.AppModuleBasic{}, ) @@ -158,6 +163,7 @@ func appModules( ibc.NewAppModule(app.IBCKeeper), sdkparams.NewAppModule(app.ParamsKeeper), consensus.NewAppModule(appCodec, app.ConsensusParamsKeeper), + wasm.NewAppModule(appCodec, &app.AppKeepers.WasmKeeper, app.AppKeepers.StakingKeeper, app.AppKeepers.AccountKeeper, app.AppKeepers.BankKeeper, app.MsgServiceRouter(), app.GetSubspace(wasmtypes.ModuleName)), ibcfee.NewAppModule(app.IBCFeeKeeper), app.TransferModule, app.ICAModule, @@ -192,6 +198,7 @@ func simulationModules( sdkparams.NewAppModule(app.ParamsKeeper), evidence.NewAppModule(app.EvidenceKeeper), authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), + wasm.NewAppModule(appCodec, &app.AppKeepers.WasmKeeper, app.AppKeepers.StakingKeeper, app.AppKeepers.AccountKeeper, app.AppKeepers.BankKeeper, app.MsgServiceRouter(), app.GetSubspace(wasmtypes.ModuleName)), ibc.NewAppModule(app.IBCKeeper), app.TransferModule, app.ICAModule, @@ -239,6 +246,7 @@ func orderBeginBlockers() []string { providertypes.ModuleName, consensusparamtypes.ModuleName, metaprotocolstypes.ModuleName, + wasmtypes.ModuleName, } } @@ -278,6 +286,7 @@ func orderEndBlockers() []string { providertypes.ModuleName, consensusparamtypes.ModuleName, metaprotocolstypes.ModuleName, + wasmtypes.ModuleName, } } @@ -324,5 +333,6 @@ func orderInitBlockers() []string { providertypes.ModuleName, consensusparamtypes.ModuleName, metaprotocolstypes.ModuleName, + wasmtypes.ModuleName, } } diff --git a/app/sim_bench_test.go b/app/sim_bench_test.go index 5ccec2dcdf7..6a293f7dd3c 100644 --- a/app/sim_bench_test.go +++ b/app/sim_bench_test.go @@ -53,6 +53,7 @@ func BenchmarkFullAppSimulation(b *testing.B) { gaia.DefaultNodeHome, encConfig, appOptions, + emptyWasmOption, interBlockCacheOpt(), baseapp.SetChainID(AppChainID), ) diff --git a/app/sim_test.go b/app/sim_test.go index 734ffc2e833..3aa99b6073e 100644 --- a/app/sim_test.go +++ b/app/sim_test.go @@ -99,6 +99,7 @@ func TestAppStateDeterminism(t *testing.T) { gaia.DefaultNodeHome, encConfig, appOptions, + emptyWasmOption, interBlockCacheOpt(), baseapp.SetChainID(AppChainID), ) diff --git a/app/upgrades/v18/constants.go b/app/upgrades/v18/constants.go index 59e39c16633..66ef6a0acaa 100644 --- a/app/upgrades/v18/constants.go +++ b/app/upgrades/v18/constants.go @@ -5,6 +5,8 @@ import ( store "github.com/cosmos/cosmos-sdk/store/types" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + "github.com/cosmos/gaia/v18/app/upgrades" ) @@ -20,6 +22,7 @@ var Upgrade = upgrades.Upgrade{ StoreUpgrades: store.StoreUpgrades{ Added: []string{ feemarkettypes.ModuleName, + wasmtypes.ModuleName, }, Deleted: []string{ GlobalFeeModuleName, diff --git a/app/upgrades/v18/upgrades.go b/app/upgrades/v18/upgrades.go index 762c1089522..99dbaa7b8f6 100644 --- a/app/upgrades/v18/upgrades.go +++ b/app/upgrades/v18/upgrades.go @@ -1,10 +1,14 @@ package v18 import ( + errorsmod "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + "github.com/cosmos/gaia/v18/app/keepers" "github.com/cosmos/gaia/v18/types" ) @@ -27,6 +31,15 @@ func CreateUpgradeHandler( return vm, err } + // Set CosmWasm params + wasmParams := wasmtypes.DefaultParams() + wasmParams.CodeUploadAccess = wasmtypes.AllowNobody + // TODO(reece): only allow specific addresses to instantiate contracts or anyone with AccessTypeEverybody? + wasmParams.InstantiateDefaultPermission = wasmtypes.AccessTypeAnyOfAddresses + if err := keepers.WasmKeeper.SetParams(ctx, wasmParams); err != nil { + return vm, errorsmod.Wrapf(err, "unable to set CosmWasm params") + } + ctx.Logger().Info("Upgrade v18 complete") return vm, nil } diff --git a/cmd/gaiad/cmd/root.go b/cmd/gaiad/cmd/root.go index de02103bf66..309c4f9dc62 100644 --- a/cmd/gaiad/cmd/root.go +++ b/cmd/gaiad/cmd/root.go @@ -6,6 +6,7 @@ import ( "os" "path/filepath" + "github.com/prometheus/client_golang/prometheus" "github.com/spf13/cast" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -40,6 +41,10 @@ import ( "github.com/cosmos/cosmos-sdk/x/crisis" genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" + "github.com/CosmWasm/wasmd/x/wasm" + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + gaia "github.com/cosmos/gaia/v18/app" "github.com/cosmos/gaia/v18/app/params" ) @@ -107,6 +112,8 @@ func initAppConfig() (string, interface{}) { // Embed additional configurations type CustomAppConfig struct { serverconfig.Config + + Wasm wasmtypes.WasmConfig `mapstructure:"wasm"` } // Can optionally overwrite the SDK's default server config. @@ -116,9 +123,10 @@ func initAppConfig() (string, interface{}) { customAppConfig := CustomAppConfig{ Config: *srvCfg, + Wasm: wasmtypes.DefaultWasmConfig(), } - defaultAppTemplate := serverconfig.DefaultConfigTemplate + defaultAppTemplate := serverconfig.DefaultConfigTemplate + wasmtypes.DefaultConfigTemplate() return defaultAppTemplate, customAppConfig } @@ -156,6 +164,7 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { func addModuleInitFlags(startCmd *cobra.Command) { crisis.AddModuleInitFlags(startCmd) + wasm.AddModuleInitFlags(startCmd) } // genesisCommand builds genesis-related `simd genesis` command. Users may provide application specific commands as a parameter @@ -236,6 +245,11 @@ func (a appCreator) newApp( cache = store.NewCommitKVStoreCacheManager() } + var wasmOpts []wasmkeeper.Option + if cast.ToBool(appOpts.Get("telemetry.enabled")) { + wasmOpts = append(wasmOpts, wasmkeeper.WithVMCacheMetrics(prometheus.DefaultRegisterer)) + } + pruningOpts, err := server.GetPruningOptionsFromFlags(appOpts) if err != nil { panic(err) @@ -297,6 +311,7 @@ func (a appCreator) newApp( cast.ToString(appOpts.Get(flags.FlagHome)), a.encCfg, appOpts, + wasmOpts, baseappOptions..., ) } @@ -332,6 +347,7 @@ func (a appCreator) appExport( loadLatest = true } + var emptyWasmOpts []wasmkeeper.Option gaiaApp = gaia.NewGaiaApp( logger, db, @@ -341,6 +357,7 @@ func (a appCreator) appExport( homePath, a.encCfg, appOpts, + emptyWasmOpts, ) if height != -1 { diff --git a/contrib/cw_template.wasm b/contrib/cw_template.wasm new file mode 100644 index 00000000000..909cbdd198c Binary files /dev/null and b/contrib/cw_template.wasm differ diff --git a/contrib/scripts/local-gaia.sh b/contrib/scripts/local-gaia.sh index 6e21ed13ea0..8d0e475c245 100755 --- a/contrib/scripts/local-gaia.sh +++ b/contrib/scripts/local-gaia.sh @@ -1,7 +1,7 @@ #!/bin/bash -set -eux +set -eux -# User balance of stake tokens +# User balance of stake tokens USER_COINS="100000000000stake" # Amount of stake tokens staked STAKE="100000000stake" @@ -9,7 +9,7 @@ STAKE="100000000stake" NODE_IP="127.0.0.1" # Home directory -HOME_DIR="/Users/msalopek" +HOME_DIR="$HOME" # Validator moniker MONIKER="coordinator" @@ -53,6 +53,7 @@ sleep 1 sed -i -r "/node =/ s/= .*/= \"tcp:\/\/${NODE_IP}:26658\"/" ${PROV_NODE_DIR}/config/client.toml sed -i -r 's/timeout_commit = "5s"/timeout_commit = "3s"/g' ${PROV_NODE_DIR}/config/config.toml sed -i -r 's/timeout_propose = "3s"/timeout_propose = "1s"/g' ${PROV_NODE_DIR}/config/config.toml +sed -i -r 's/minimum-gas-prices = ""/minimum-gas-prices = "0stake"/g' ${PROV_NODE_DIR}/config/app.toml # Start gaia diff --git a/contrib/single-node.sh b/contrib/single-node.sh index 6ba8863b913..38c7d492ec6 100755 --- a/contrib/single-node.sh +++ b/contrib/single-node.sh @@ -26,11 +26,12 @@ gaiad genesis collect-gentxs # Set proper defaults and change ports echo "Setting rpc listen address" -sed -i '' 's#"tcp://127.0.0.1:26657"#"tcp://0.0.0.0:26657"#g' ~/.gaia/config/config.toml -echo 2 -sed -i '' 's/timeout_commit = "5s"/timeout_commit = "1s"/g' ~/.gaia/config/config.toml -sed -i '' 's/timeout_propose = "3s"/timeout_propose = "1s"/g' ~/.gaia/config/config.toml -sed -i '' 's/index_all_keys = false/index_all_keys = true/g' ~/.gaia/config/config.toml +# sed -i '' 's#"tcp://127.0.0.1:26657"#"tcp://0.0.0.0:26657"#g' ~/.gaia/config/config.toml +sleep 1 +sed -i -r 's/timeout_commit = "5s"/timeout_commit = "1s"/g' ~/.gaia/config/config.toml +sed -i -r 's/timeout_propose = "3s"/timeout_propose = "1s"/g' ~/.gaia/config/config.toml +sed -i -r 's/index_all_keys = false/index_all_keys = true/g' ~/.gaia/config/config.toml +sed -i -r 's/minimum-gas-prices = ""/minimum-gas-prices = "0stake"/g' ~/.gaia/config/app.toml # Start the gaia gaiad start --pruning=nothing diff --git a/contrib/upload-contract.sh b/contrib/upload-contract.sh new file mode 100644 index 00000000000..f3e7f250108 --- /dev/null +++ b/contrib/upload-contract.sh @@ -0,0 +1,14 @@ +export GAIAD_NODE="tcp://localhost:26657" + +FLAGS="--gas=2500000 --from=validator --keyring-backend=test --chain-id=local-1 --output=json --yes" + +gaiad tx wasm store ./contrib/cw_template.wasm $FLAGS +sleep 2 + +txhash=$(gaiad tx wasm instantiate 1 '{"count":0}' --label=cw_template --no-admin $FLAGS | jq -r .txhash) && echo $txhash +sleep 2 + +addr=$(gaiad q tx $txhash --output=json | jq -r .logs[0].events[2].attributes[0].value) && echo $addr +sleep 2 + +gaiad q wasm contract $addr \ No newline at end of file diff --git a/e2e.Dockerfile b/e2e.Dockerfile index 41f22c0a1c8..732c025f2f0 100644 --- a/e2e.Dockerfile +++ b/e2e.Dockerfile @@ -3,18 +3,30 @@ ARG IMG_TAG=latest # Compile the gaiad binary FROM golang:1.22-alpine AS gaiad-builder WORKDIR /src/app/ +ENV PACKAGES="curl make git libc-dev bash file gcc linux-headers eudev-dev python3" +RUN apk add --no-cache $PACKAGES + +# See https://github.com/CosmWasm/wasmvm/releases +ARG WASMVM_VERSION=v1.5.0 +ADD https://github.com/CosmWasm/wasmvm/releases/download/${WASMVM_VERSION}/libwasmvm_muslc.aarch64.a /lib/libwasmvm_muslc.aarch64.a +ADD https://github.com/CosmWasm/wasmvm/releases/download/${WASMVM_VERSION}/libwasmvm_muslc.x86_64.a /lib/libwasmvm_muslc.x86_64.a +RUN sha256sum /lib/libwasmvm_muslc.aarch64.a | grep 2687afbdae1bc6c7c8b05ae20dfb8ffc7ddc5b4e056697d0f37853dfe294e913 +RUN sha256sum /lib/libwasmvm_muslc.x86_64.a | grep 465e3a088e96fd009a11bfd234c69fb8a0556967677e54511c084f815cf9ce63 +RUN cp "/lib/libwasmvm_muslc.$(uname -m).a" /lib/libwasmvm_muslc.a + COPY go.mod go.sum* ./ RUN go mod download COPY . . -ENV PACKAGES curl make git libc-dev bash gcc linux-headers eudev-dev python3 -RUN apk add --no-cache $PACKAGES -RUN CGO_ENABLED=0 make install +RUN LEDGER_ENABLED=false LINK_STATICALLY=true BUILD_TAGS=muslc make build +RUN echo "Ensuring binary is statically linked ..." \ + && file /src/app/build/gaiad | grep "statically linked" # Add to a distroless container FROM alpine:$IMG_TAG +RUN apk add --no-cache build-base RUN adduser -D nonroot ARG IMG_TAG -COPY --from=gaiad-builder /go/bin/gaiad /usr/local/bin/ +COPY --from=gaiad-builder /src/app/build/gaiad /usr/local/bin/ EXPOSE 26656 26657 1317 9090 USER nonroot diff --git a/go.mod b/go.mod index 49775f1f099..1de1aa1cdd8 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( cosmossdk.io/math v1.3.0 cosmossdk.io/simapp v0.0.0-20230602123434-616841b9704d cosmossdk.io/tools/rosetta v0.2.1 + github.com/CosmWasm/wasmd v0.45.0 github.com/Stride-Labs/ibc-rate-limiting v1.0.1 github.com/cometbft/cometbft v0.37.6 github.com/cometbft/cometbft-db v0.11.0 @@ -20,6 +21,7 @@ require ( github.com/google/gofuzz v1.2.0 github.com/gorilla/mux v1.8.1 github.com/ory/dockertest/v3 v3.10.0 + github.com/prometheus/client_golang v1.17.0 github.com/rakyll/statik v0.1.7 github.com/skip-mev/feemarket v1.0.3-sdk47 github.com/spf13/cast v1.6.0 @@ -52,6 +54,7 @@ require ( github.com/99designs/keyring v1.2.2 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/ChainSafe/go-schnorrkel v1.0.0 // indirect + github.com/CosmWasm/wasmvm v1.5.0 // indirect github.com/DataDog/zstd v1.5.0 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect @@ -90,6 +93,7 @@ require ( github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/docker/cli v20.10.17+incompatible // indirect + github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/docker v24.0.9+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect @@ -167,7 +171,6 @@ require ( github.com/petermattis/goid v0.0.0-20230904192822-1876fd5063bc // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_golang v1.17.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/common v0.45.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect diff --git a/go.sum b/go.sum index ac6ae349eb2..49051771417 100644 --- a/go.sum +++ b/go.sum @@ -557,6 +557,10 @@ github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg6 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/ChainSafe/go-schnorrkel v1.0.0 h1:3aDA67lAykLaG1y3AOjs88dMxC88PgUuHRrLeDnvGIM= github.com/ChainSafe/go-schnorrkel v1.0.0/go.mod h1:dpzHYVxLZcp8pjlV+O+UR8K0Hp/z7vcchBSbMBEhCw4= +github.com/CosmWasm/wasmd v0.45.0 h1:9zBqrturKJwC2kVsfHvbrA++EN0PS7UTXCffCGbg6JI= +github.com/CosmWasm/wasmd v0.45.0/go.mod h1:RnSAiqbNIZu4QhO+0pd7qGZgnYAMBPGmXpzTADag944= +github.com/CosmWasm/wasmvm v1.5.0 h1:3hKeT9SfwfLhxTGKH3vXaKFzBz1yuvP8SlfwfQXbQfw= +github.com/CosmWasm/wasmvm v1.5.0/go.mod h1:fXB+m2gyh4v9839zlIXdMZGeLAxqUdYdFQqYsTha2hc= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/zstd v1.5.0 h1:+K/VEwIAaPcHiMtQvpLD4lqW7f0Gk3xdYZmI1hD+CXo= @@ -820,6 +824,8 @@ github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/ github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/docker/cli v20.10.17+incompatible h1:eO2KS7ZFeov5UJeaDmIs1NFEDRf32PaqRpvoEkKBy5M= github.com/docker/cli v20.10.17+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= +github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v24.0.9+incompatible h1:HPGzNmwfLZWdxHqK9/II92pyi1EpYKsAqcl4G0Of9v0= github.com/docker/docker v24.0.9+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= diff --git a/tests/e2e/scripts/hermes_bootstrap.sh b/tests/e2e/scripts/hermes_bootstrap.sh index 3c662cba441..d8fd93a4714 100755 --- a/tests/e2e/scripts/hermes_bootstrap.sh +++ b/tests/e2e/scripts/hermes_bootstrap.sh @@ -54,7 +54,7 @@ key_name = 'rly01-gaia-a' store_prefix = 'ibc' max_gas = 6000000 gas_price = { price = 0.005, denom = 'uatom' } -gas_multiplier = 2 +gas_multiplier = 1.5 clock_drift = '1m' # to accomdate docker containers trusting_period = '14days' trust_threshold = { numerator = '1', denominator = '3' } @@ -72,7 +72,7 @@ key_name = 'rly01-gaia-b' store_prefix = 'ibc' max_gas = 6000000 gas_price = { price = 0.005, denom = 'uatom' } -gas_multiplier = 2 +gas_multiplier = 1.5 clock_drift = '1m' # to accomdate docker containers trusting_period = '14days' trust_threshold = { numerator = '1', denominator = '3' } @@ -124,7 +124,7 @@ key_name = 'rly01-gaia-a' store_prefix = 'ibc' max_gas = 6000000 gas_price = { price = 0, denom = 'uatom' } -gas_multiplier = 2 +gas_multiplier = 1.5 clock_drift = '1m' # to accommodate docker containers trusting_period = '14days' trust_threshold = { numerator = '1', denominator = '3' } @@ -142,7 +142,7 @@ key_name = 'rly01-gaia-b' store_prefix = 'ibc' max_gas = 6000000 gas_price = { price = 0, denom = 'uatom' } -gas_multiplier = 2 +gas_multiplier = 1.5 clock_drift = '1m' # to accommodate docker containers trusting_period = '14days' trust_threshold = { numerator = '1', denominator = '3' } @@ -154,5 +154,3 @@ EOF hermes keys add --key-name rly01-gaia-b --chain $GAIA_B_E2E_CHAIN_ID --mnemonic-file /root/.hermes/GAIA_B_E2E_RLY_MNEMONIC.txt sleep 5 hermes keys add --key-name rly01-gaia-a --chain $GAIA_A_E2E_CHAIN_ID --mnemonic-file /root/.hermes/GAIA_A_E2E_RLY_MNEMONIC.txt - - diff --git a/tests/integration/test_utils.go b/tests/integration/test_utils.go index 477a2926f17..54579b5d53c 100644 --- a/tests/integration/test_utils.go +++ b/tests/integration/test_utils.go @@ -35,7 +35,8 @@ func GaiaAppIniter() (ibctesting.TestingApp, map[string]json.RawMessage) { map[int64]bool{}, gaiaApp.DefaultNodeHome, encoding, - gaiaApp.EmptyAppOptions{}) + gaiaApp.EmptyAppOptions{}, + gaiaApp.EmptyWasmOptions) testApp := ibctesting.TestingApp(app)