Skip to content

Commit 3511d88

Browse files
Reecepbcupswebmaster128MSalopek
authored
feat!: integrate cosmwasm (#3051)
* 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]>
1 parent 2758025 commit 3511d88

26 files changed

+230
-40
lines changed

.github/workflows/test.yml

+4
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,10 @@ jobs:
171171
- name: Install New Gaiad
172172
run: |
173173
git checkout -
174+
curl -LO https://github.com/CosmWasm/wasmvm/releases/download/v1.5.0/libwasmvm.x86_64.so
175+
curl -LO https://github.com/CosmWasm/wasmvm/releases/download/v1.5.0/libwasmvm.aarch64.so
176+
uname -m
177+
sudo cp "./libwasmvm.$(uname -m).so" /usr/lib/
174178
make build
175179
cp ./build/gaiad ./build/gaiadnew
176180
go clean -modcache

.golangci.yml

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ linters-settings:
6868
- prefix(github.com/cosmos) # cosmos org
6969
- prefix(cosmossdk.io) # new modules
7070
- prefix(github.com/cosmos/cosmos-sdk) # cosmos sdk
71+
- prefix(github.com/CosmWasm/wasmd) # cosmwasm
7172
- prefix(github.com/cosmos/gaia) # Gaia
7273
dogsled:
7374
max-blank-identifiers: 3

.goreleaser.yml

-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ builds:
2020
goos:
2121
- darwin
2222
- linux
23-
- windows
2423
goarch:
2524
- amd64
2625
- arm64

Dockerfile

+17-5
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,31 @@
11
ARG IMG_TAG=latest
22

33
# Compile the gaiad binary
4-
FROM golang:1.21-alpine AS gaiad-builder
4+
FROM golang:1.21-alpine3.18 AS gaiad-builder
55
WORKDIR /src/app/
6+
ENV PACKAGES="curl make git libc-dev bash file gcc linux-headers eudev-dev python3"
7+
RUN apk add --no-cache $PACKAGES
8+
9+
# See https://github.com/CosmWasm/wasmvm/releases
10+
ARG WASMVM_VERSION=v1.5.0
11+
ADD https://github.com/CosmWasm/wasmvm/releases/download/${WASMVM_VERSION}/libwasmvm_muslc.aarch64.a /lib/libwasmvm_muslc.aarch64.a
12+
ADD https://github.com/CosmWasm/wasmvm/releases/download/${WASMVM_VERSION}/libwasmvm_muslc.x86_64.a /lib/libwasmvm_muslc.x86_64.a
13+
RUN sha256sum /lib/libwasmvm_muslc.aarch64.a | grep 2687afbdae1bc6c7c8b05ae20dfb8ffc7ddc5b4e056697d0f37853dfe294e913
14+
RUN sha256sum /lib/libwasmvm_muslc.x86_64.a | grep 465e3a088e96fd009a11bfd234c69fb8a0556967677e54511c084f815cf9ce63
15+
RUN cp "/lib/libwasmvm_muslc.$(uname -m).a" /lib/libwasmvm_muslc.a
16+
617
COPY go.mod go.sum* ./
718
RUN go mod download
19+
820
COPY . .
9-
ENV PACKAGES curl make git libc-dev bash gcc linux-headers eudev-dev python3
10-
RUN apk add --no-cache $PACKAGES
11-
RUN CGO_ENABLED=0 make install
21+
RUN LEDGER_ENABLED=false LINK_STATICALLY=true BUILD_TAGS=muslc make build
22+
RUN echo "Ensuring binary is statically linked ..." \
23+
&& file /src/app/build/gaiad | grep "statically linked"
1224

1325
# Add to a distroless container
1426
FROM cgr.dev/chainguard/static:$IMG_TAG
1527
ARG IMG_TAG
16-
COPY --from=gaiad-builder /go/bin/gaiad /usr/local/bin/
28+
COPY --from=gaiad-builder /src/app/build/gaiad /usr/local/bin/
1729
EXPOSE 26656 26657 1317 9090
1830
USER 0
1931

Makefile

+3
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=gaia \
7474
ifeq (cleveldb,$(findstring cleveldb,$(GAIA_BUILD_OPTIONS)))
7575
ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=cleveldb
7676
endif
77+
ifeq ($(LINK_STATICALLY),true)
78+
ldflags += -linkmode=external -extldflags "-Wl,-z,muldefs -static"
79+
endif
7780
ifeq (,$(findstring nostrip,$(GAIA_BUILD_OPTIONS)))
7881
ldflags += -w -s
7982
endif

ante/ante.go

+14-6
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,14 @@ import (
1010
errorsmod "cosmossdk.io/errors"
1111

1212
"github.com/cosmos/cosmos-sdk/codec"
13+
storetypes "github.com/cosmos/cosmos-sdk/store/types"
1314
sdk "github.com/cosmos/cosmos-sdk/types"
1415
"github.com/cosmos/cosmos-sdk/x/auth/ante"
1516
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
1617

18+
wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
19+
wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"
20+
1721
gaiaerrors "github.com/cosmos/gaia/v18/types/errors"
1822
)
1923

@@ -24,11 +28,13 @@ var UseFeeMarketDecorator = true
2428
// channel keeper.
2529
type HandlerOptions struct {
2630
ante.HandlerOptions
27-
Codec codec.BinaryCodec
28-
IBCkeeper *ibckeeper.Keeper
29-
StakingKeeper *stakingkeeper.Keeper
30-
FeeMarketKeeper *feemarketkeeper.Keeper
31-
TxFeeChecker ante.TxFeeChecker
31+
Codec codec.BinaryCodec
32+
IBCkeeper *ibckeeper.Keeper
33+
StakingKeeper *stakingkeeper.Keeper
34+
FeeMarketKeeper *feemarketkeeper.Keeper
35+
TxFeeChecker ante.TxFeeChecker
36+
TxCounterStoreKey storetypes.StoreKey
37+
WasmConfig *wasmtypes.WasmConfig
3238
}
3339

3440
func NewAnteHandler(opts HandlerOptions) (sdk.AnteHandler, error) {
@@ -58,7 +64,9 @@ func NewAnteHandler(opts HandlerOptions) (sdk.AnteHandler, error) {
5864
}
5965

6066
anteDecorators := []sdk.AnteDecorator{
61-
ante.NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first
67+
ante.NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first
68+
wasmkeeper.NewLimitSimulationGasDecorator(opts.WasmConfig.SimulationGasLimit), // after setup context to enforce limits early
69+
wasmkeeper.NewCountTXDecorator(opts.TxCounterStoreKey),
6270
ante.NewExtensionOptionsDecorator(opts.ExtensionOptionChecker),
6371
ante.NewValidateBasicDecorator(),
6472
ante.NewTxTimeoutHeightDecorator(),

app/app.go

+34-4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
tmjson "github.com/cometbft/cometbft/libs/json"
2121
"github.com/cometbft/cometbft/libs/log"
2222
tmos "github.com/cometbft/cometbft/libs/os"
23+
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
2324

2425
ibctesting "github.com/cosmos/ibc-go/v7/testing"
2526
providertypes "github.com/cosmos/interchain-security/v4/x/ccv/provider/types"
@@ -52,6 +53,10 @@ import (
5253
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
5354
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
5455

56+
wasm "github.com/CosmWasm/wasmd/x/wasm"
57+
wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
58+
wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"
59+
5560
gaiaante "github.com/cosmos/gaia/v18/ante"
5661
"github.com/cosmos/gaia/v18/app/keepers"
5762
"github.com/cosmos/gaia/v18/app/params"
@@ -112,6 +117,7 @@ func NewGaiaApp(
112117
homePath string,
113118
encodingConfig params.EncodingConfig,
114119
appOpts servertypes.AppOptions,
120+
wasmOpts []wasmkeeper.Option,
115121
baseAppOptions ...func(*baseapp.BaseApp),
116122
) *GaiaApp {
117123
appCodec := encodingConfig.Marshaler
@@ -159,6 +165,7 @@ func NewGaiaApp(
159165
invCheckPeriod,
160166
logger,
161167
appOpts,
168+
wasmOpts,
162169
)
163170

164171
// NOTE: Any module instantiated in the module manager that is later modified
@@ -214,6 +221,11 @@ func NewGaiaApp(
214221
app.MountTransientStores(app.GetTransientStoreKey())
215222
app.MountMemoryStores(app.GetMemoryStoreKey())
216223

224+
wasmConfig, err := wasm.ReadWasmConfig(appOpts)
225+
if err != nil {
226+
panic("error while reading wasm config: " + err.Error())
227+
}
228+
217229
anteHandler, err := gaiaante.NewAnteHandler(
218230
gaiaante.HandlerOptions{
219231
HandlerOptions: ante.HandlerOptions{
@@ -223,10 +235,12 @@ func NewGaiaApp(
223235
SignModeHandler: encodingConfig.TxConfig.SignModeHandler(),
224236
SigGasConsumer: ante.DefaultSigVerificationGasConsumer,
225237
},
226-
Codec: appCodec,
227-
IBCkeeper: app.IBCKeeper,
228-
StakingKeeper: app.StakingKeeper,
229-
FeeMarketKeeper: app.FeeMarketKeeper,
238+
Codec: appCodec,
239+
IBCkeeper: app.IBCKeeper,
240+
StakingKeeper: app.StakingKeeper,
241+
FeeMarketKeeper: app.FeeMarketKeeper,
242+
WasmConfig: &wasmConfig,
243+
TxCounterStoreKey: app.AppKeepers.GetKey(wasmtypes.StoreKey),
230244
TxFeeChecker: func(ctx sdk.Context, tx sdk.Tx) (sdk.Coins, int64, error) {
231245
return minTxFeesChecker(ctx, tx, *app.FeeMarketKeeper)
232246
},
@@ -255,13 +269,26 @@ func NewGaiaApp(
255269
app.SetBeginBlocker(app.BeginBlocker)
256270
app.SetEndBlocker(app.EndBlocker)
257271

272+
if manager := app.SnapshotManager(); manager != nil {
273+
err = manager.RegisterExtensions(wasmkeeper.NewWasmSnapshotter(app.CommitMultiStore(), &app.AppKeepers.WasmKeeper))
274+
if err != nil {
275+
panic("failed to register snapshot extension: " + err.Error())
276+
}
277+
}
278+
258279
app.setupUpgradeHandlers()
259280
app.setupUpgradeStoreLoaders()
260281

261282
if loadLatest {
262283
if err := app.LoadLatestVersion(); err != nil {
263284
tmos.Exit(fmt.Sprintf("failed to load latest version: %s", err))
264285
}
286+
287+
ctx := app.BaseApp.NewUncachedContext(true, tmproto.Header{})
288+
289+
if err := app.AppKeepers.WasmKeeper.InitializePinnedCodes(ctx); err != nil {
290+
tmos.Exit(fmt.Sprintf("WasmKeeper failed initialize pinned codes %s", err))
291+
}
265292
}
266293

267294
return app
@@ -451,6 +478,9 @@ func (app *GaiaApp) GetTxConfig() client.TxConfig {
451478
// EmptyAppOptions is a stub implementing AppOptions
452479
type EmptyAppOptions struct{}
453480

481+
// EmptyWasmOptions is a stub implementing Wasmkeeper Option
482+
var EmptyWasmOptions []wasmkeeper.Option
483+
454484
// Get implements AppOptions
455485
func (ao EmptyAppOptions) Get(_ string) interface{} {
456486
return nil

app/app_test.go

+5
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,16 @@ import (
1111
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
1212
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
1313

14+
wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
15+
1416
gaia "github.com/cosmos/gaia/v18/app"
1517
gaiahelpers "github.com/cosmos/gaia/v18/app/helpers"
1618
)
1719

1820
type EmptyAppOptions struct{}
1921

22+
var emptyWasmOption []wasmkeeper.Option
23+
2024
func (ao EmptyAppOptions) Get(_ string) interface{} {
2125
return nil
2226
}
@@ -32,6 +36,7 @@ func TestGaiaApp_BlockedModuleAccountAddrs(t *testing.T) {
3236
gaia.DefaultNodeHome,
3337
encConfig,
3438
EmptyAppOptions{},
39+
emptyWasmOption,
3540
)
3641

3742
moduleAccountAddresses := app.ModuleAccountAddrs()

app/helpers/test_helpers.go

+4
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import (
2424
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
2525
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
2626

27+
wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
28+
2729
gaiaapp "github.com/cosmos/gaia/v18/app"
2830
)
2931

@@ -121,6 +123,7 @@ func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs
121123
func setup() (*gaiaapp.GaiaApp, gaiaapp.GenesisState) {
122124
db := dbm.NewMemDB()
123125
appOptions := make(simtestutil.AppOptionsMap, 0)
126+
emptyWasmOpts := []wasmkeeper.Option{}
124127
appOptions[server.FlagInvCheckPeriod] = 5
125128
appOptions[server.FlagMinGasPrices] = "0uatom"
126129

@@ -135,6 +138,7 @@ func setup() (*gaiaapp.GaiaApp, gaiaapp.GenesisState) {
135138
gaiaapp.DefaultNodeHome,
136139
encConfig,
137140
appOptions,
141+
emptyWasmOpts,
138142
)
139143
return gaiaApp, gaiaapp.NewDefaultGenesisState(encConfig)
140144
}

app/keepers/keepers.go

+43-3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package keepers
33
import (
44
"fmt"
55
"os"
6+
"strings"
67

78
ratelimit "github.com/Stride-Labs/ibc-rate-limiting/ratelimit"
89
ratelimitkeeper "github.com/Stride-Labs/ibc-rate-limiting/ratelimit/keeper"
@@ -80,6 +81,11 @@ import (
8081
"github.com/cosmos/cosmos-sdk/x/upgrade"
8182
upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper"
8283
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
84+
85+
wasmapp "github.com/CosmWasm/wasmd/app"
86+
"github.com/CosmWasm/wasmd/x/wasm"
87+
wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
88+
wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"
8389
)
8490

8591
type AppKeepers struct {
@@ -100,6 +106,7 @@ type AppKeepers struct {
100106
CrisisKeeper *crisiskeeper.Keeper
101107
UpgradeKeeper *upgradekeeper.Keeper
102108
ParamsKeeper paramskeeper.Keeper
109+
WasmKeeper wasmkeeper.Keeper
103110
// IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly
104111
IBCKeeper *ibckeeper.Keeper
105112
ICAHostKeeper icahostkeeper.Keeper
@@ -131,6 +138,7 @@ type AppKeepers struct {
131138
ScopedICAHostKeeper capabilitykeeper.ScopedKeeper
132139
ScopedICAControllerKeeper capabilitykeeper.ScopedKeeper
133140
ScopedICSproviderkeeper capabilitykeeper.ScopedKeeper
141+
scopedWasmKeeper capabilitykeeper.ScopedKeeper
134142
}
135143

136144
func NewAppKeeper(
@@ -145,6 +153,7 @@ func NewAppKeeper(
145153
invCheckPeriod uint,
146154
logger log.Logger,
147155
appOpts servertypes.AppOptions,
156+
wasmOpts []wasmkeeper.Option,
148157
) AppKeepers {
149158
appKeepers := AppKeepers{}
150159

@@ -189,6 +198,7 @@ func NewAppKeeper(
189198
appKeepers.ScopedICAControllerKeeper = appKeepers.CapabilityKeeper.ScopeToModule(icacontrollertypes.SubModuleName)
190199
appKeepers.ScopedTransferKeeper = appKeepers.CapabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName)
191200
appKeepers.ScopedICSproviderkeeper = appKeepers.CapabilityKeeper.ScopeToModule(providertypes.ModuleName)
201+
appKeepers.scopedWasmKeeper = appKeepers.CapabilityKeeper.ScopeToModule(wasmtypes.ModuleName)
192202

193203
// Applications that wish to enforce statically created ScopedKeepers should call `Seal` after creating
194204
// their scoped modules in `NewApp` with `ScopeToModule`
@@ -447,6 +457,31 @@ func NewAppKeeper(
447457
// Must be called on PFMRouter AFTER TransferKeeper initialized
448458
appKeepers.PFMRouterKeeper.SetTransferKeeper(appKeepers.TransferKeeper)
449459

460+
wasmConfig, err := wasm.ReadWasmConfig(appOpts)
461+
if err != nil {
462+
panic("error while reading wasm config: " + err.Error())
463+
}
464+
465+
appKeepers.WasmKeeper = wasmkeeper.NewKeeper(
466+
appCodec,
467+
appKeepers.keys[wasmtypes.StoreKey],
468+
appKeepers.AccountKeeper,
469+
appKeepers.BankKeeper,
470+
appKeepers.StakingKeeper,
471+
distrkeeper.NewQuerier(appKeepers.DistrKeeper),
472+
appKeepers.IBCKeeper.ChannelKeeper,
473+
appKeepers.IBCKeeper.ChannelKeeper,
474+
&appKeepers.IBCKeeper.PortKeeper,
475+
appKeepers.scopedWasmKeeper,
476+
appKeepers.TransferKeeper,
477+
bApp.MsgServiceRouter(),
478+
bApp.GRPCQueryRouter(),
479+
homePath,
480+
wasmConfig,
481+
strings.Join(wasmapp.AllCapabilities(), ","),
482+
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
483+
)
484+
450485
// Middleware Stacks
451486
appKeepers.ICAModule = ica.NewAppModule(&appKeepers.ICAControllerKeeper, &appKeepers.ICAHostKeeper)
452487
appKeepers.TransferModule = transfer.NewAppModule(appKeepers.TransferKeeper)
@@ -484,12 +519,17 @@ func NewAppKeeper(
484519
// Create Interchain Accounts Controller Stack
485520
var icaControllerStack porttypes.IBCModule = icacontroller.NewIBCMiddleware(nil, appKeepers.ICAControllerKeeper)
486521

522+
var wasmStack porttypes.IBCModule
523+
wasmStack = wasm.NewIBCHandler(appKeepers.WasmKeeper, appKeepers.IBCKeeper.ChannelKeeper, appKeepers.IBCFeeKeeper)
524+
wasmStack = ibcfee.NewIBCMiddleware(wasmStack, appKeepers.IBCFeeKeeper)
525+
487526
// Create IBC Router & seal
488527
ibcRouter := porttypes.NewRouter().
489528
AddRoute(icahosttypes.SubModuleName, icaHostStack).
490529
AddRoute(icacontrollertypes.SubModuleName, icaControllerStack).
491530
AddRoute(ibctransfertypes.ModuleName, transferStack).
492-
AddRoute(providertypes.ModuleName, appKeepers.ProviderModule)
531+
AddRoute(providertypes.ModuleName, appKeepers.ProviderModule).
532+
AddRoute(wasmtypes.ModuleName, wasmStack)
493533

494534
appKeepers.IBCKeeper.SetRouter(ibcRouter)
495535

@@ -509,8 +549,7 @@ func (appKeepers *AppKeepers) GetSubspace(moduleName string) paramstypes.Subspac
509549
func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino, key, tkey storetypes.StoreKey) paramskeeper.Keeper {
510550
paramsKeeper := paramskeeper.NewKeeper(appCodec, legacyAmino, key, tkey)
511551

512-
//nolint: staticcheck // SA1019: moduletypes.ParamKeyTable is deprecated
513-
paramsKeeper.Subspace(authtypes.ModuleName).WithKeyTable(authtypes.ParamKeyTable())
552+
paramsKeeper.Subspace(authtypes.ModuleName).WithKeyTable(authtypes.ParamKeyTable()) //nolint: staticcheck // SA1019
514553
paramsKeeper.Subspace(stakingtypes.ModuleName).WithKeyTable(stakingtypes.ParamKeyTable())
515554
paramsKeeper.Subspace(banktypes.ModuleName).WithKeyTable(banktypes.ParamKeyTable()) //nolint: staticcheck // SA1019
516555
paramsKeeper.Subspace(minttypes.ModuleName).WithKeyTable(minttypes.ParamKeyTable()) //nolint: staticcheck // SA1019
@@ -525,6 +564,7 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino
525564
paramsKeeper.Subspace(pfmroutertypes.ModuleName).WithKeyTable(pfmroutertypes.ParamKeyTable())
526565
paramsKeeper.Subspace(ratelimittypes.ModuleName)
527566
paramsKeeper.Subspace(providertypes.ModuleName)
567+
paramsKeeper.Subspace(wasmtypes.ModuleName)
528568

529569
return paramsKeeper
530570
}

0 commit comments

Comments
 (0)