Skip to content

Commit

Permalink
feat!: integrate cosmwasm (#3051)
Browse files Browse the repository at this point in the history
* integrate wasmd into gaia

* lint

* upload contract script example

* add to upgrade handler

* lint

* rm: windows & arm64

* docker libwasmvm_muslc wasmvm

* actually set wasmd params in upgrade

* add sleeps

* Dockerfile use alpine3.18

Co-authored-by: Simon Warta <[email protected]>

* arm64, WASMVM_VERSION, LINK_STATICALLY, AllCapabilities()

* security: sha256sum wasmvm libwasmvm

* appease linter

* tests: use CGO, use correct libwasm; add CGO to runner img

* tests: enable CGO in upgrade tests

* tests: bump hermes version

* tests: print output for upgrate test

* tests: print output for upgrate test

* attempt building in upgrade container

* attempt building in upgrade container

* tests: attempt building in upgrade container

* tests: correctly download libwasmvm DLLs

* chore: cleanup workflow file

* tests: increase hermes gas multiplier

* wasm: add wasmstack to ibc router

* e2e: update ibc failed multihop tests

* ante remove unused WasmKeeper

* add burner macc perm to wasm

* lint

* tests: reduce multipliers for hermes

---------

Co-authored-by: Simon Warta <[email protected]>
Co-authored-by: MSalopek <[email protected]>
  • Loading branch information
3 people authored Jun 18, 2024
1 parent 2758025 commit 3511d88
Show file tree
Hide file tree
Showing 26 changed files with 230 additions and 40 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 0 additions & 1 deletion .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ builds:
goos:
- darwin
- linux
- windows
goarch:
- amd64
- arm64
Expand Down
22 changes: 17 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -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

Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
20 changes: 14 additions & 6 deletions ante/ante.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand All @@ -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) {
Expand Down Expand Up @@ -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(),
Expand Down
38 changes: 34 additions & 4 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -159,6 +165,7 @@ func NewGaiaApp(
invCheckPeriod,
logger,
appOpts,
wasmOpts,
)

// NOTE: Any module instantiated in the module manager that is later modified
Expand Down Expand Up @@ -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{
Expand All @@ -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)
},
Expand Down Expand Up @@ -255,13 +269,26 @@ 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()

if loadLatest {
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
Expand Down Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions app/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand All @@ -32,6 +36,7 @@ func TestGaiaApp_BlockedModuleAccountAddrs(t *testing.T) {
gaia.DefaultNodeHome,
encConfig,
EmptyAppOptions{},
emptyWasmOption,
)

moduleAccountAddresses := app.ModuleAccountAddrs()
Expand Down
4 changes: 4 additions & 0 deletions app/helpers/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand Down Expand Up @@ -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"

Expand All @@ -135,6 +138,7 @@ func setup() (*gaiaapp.GaiaApp, gaiaapp.GenesisState) {
gaiaapp.DefaultNodeHome,
encConfig,
appOptions,
emptyWasmOpts,
)
return gaiaApp, gaiaapp.NewDefaultGenesisState(encConfig)
}
Expand Down
46 changes: 43 additions & 3 deletions app/keepers/keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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 {
Expand All @@ -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
Expand Down Expand Up @@ -131,6 +138,7 @@ type AppKeepers struct {
ScopedICAHostKeeper capabilitykeeper.ScopedKeeper
ScopedICAControllerKeeper capabilitykeeper.ScopedKeeper
ScopedICSproviderkeeper capabilitykeeper.ScopedKeeper
scopedWasmKeeper capabilitykeeper.ScopedKeeper
}

func NewAppKeeper(
Expand All @@ -145,6 +153,7 @@ func NewAppKeeper(
invCheckPeriod uint,
logger log.Logger,
appOpts servertypes.AppOptions,
wasmOpts []wasmkeeper.Option,
) AppKeepers {
appKeepers := AppKeepers{}

Expand Down Expand Up @@ -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`
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)

Expand All @@ -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
Expand All @@ -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
}
Expand Down
Loading

0 comments on commit 3511d88

Please sign in to comment.