From 4368bb96181a49c8073c3fff01429fac91e091dc Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Thu, 19 Dec 2024 16:07:10 +0100 Subject: [PATCH 1/3] Fix --- x/wasm/keeper/keeper.go | 24 ++++++++++++++++++------ x/wasm/keeper/wasmtesting/mock_engine.go | 8 ++++++++ x/wasm/types/wasmer_engine.go | 5 +++++ 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/x/wasm/keeper/keeper.go b/x/wasm/keeper/keeper.go index 585696c64c..0458cc885f 100644 --- a/x/wasm/keeper/keeper.go +++ b/x/wasm/keeper/keeper.go @@ -178,17 +178,29 @@ func (k Keeper) create(ctx context.Context, creator sdk.AccAddress, wasmCode []b } gasLeft := k.runtimeGasForContract(sdkCtx) - checksum, gasUsed, err := k.wasmVM.StoreCode(wasmCode, gasLeft) + var gasUsed uint64 + isSimulation := sdkCtx.ExecMode() == sdk.ExecModeSimulate + if isSimulation { + // only simulate storing the code, no files are written + checksum, gasUsed, err = k.wasmVM.SimulateStoreCode(wasmCode, gasLeft) + } else { + checksum, gasUsed, err = k.wasmVM.StoreCode(wasmCode, gasLeft) + } k.consumeRuntimeGas(sdkCtx, gasUsed) if err != nil { return 0, checksum, errorsmod.Wrap(types.ErrCreateFailed, err.Error()) } - report, err := k.wasmVM.AnalyzeCode(checksum) - if err != nil { - return 0, checksum, errorsmod.Wrap(types.ErrCreateFailed, err.Error()) + // simulation gets default value for capabilities + var requiredCapabilities string + if !isSimulation { + report, err := k.wasmVM.AnalyzeCode(checksum) + if err != nil { + return 0, checksum, errorsmod.Wrap(types.ErrCreateFailed, err.Error()) + } + requiredCapabilities = report.RequiredCapabilities } codeID = k.mustAutoIncrementID(sdkCtx, types.KeySequenceCodeID) - k.Logger(sdkCtx).Debug("storing new contract", "capabilities", report.RequiredCapabilities, "code_id", codeID) + k.Logger(sdkCtx).Debug("storing new contract", "capabilities", requiredCapabilities, "code_id", codeID) codeInfo := types.NewCodeInfo(checksum, creator, *instantiateAccess) k.mustStoreCodeInfo(sdkCtx, codeID, codeInfo) @@ -197,7 +209,7 @@ func (k Keeper) create(ctx context.Context, creator sdk.AccAddress, wasmCode []b sdk.NewAttribute(types.AttributeKeyChecksum, hex.EncodeToString(checksum)), sdk.NewAttribute(types.AttributeKeyCodeID, strconv.FormatUint(codeID, 10)), // last element to be compatible with scripts ) - for _, f := range strings.Split(report.RequiredCapabilities, ",") { + for _, f := range strings.Split(requiredCapabilities, ",") { evt.AppendAttributes(sdk.NewAttribute(types.AttributeKeyRequiredCapability, strings.TrimSpace(f))) } sdkCtx.EventManager().EmitEvent(evt) diff --git a/x/wasm/keeper/wasmtesting/mock_engine.go b/x/wasm/keeper/wasmtesting/mock_engine.go index ca42c534a9..4af3709c6f 100644 --- a/x/wasm/keeper/wasmtesting/mock_engine.go +++ b/x/wasm/keeper/wasmtesting/mock_engine.go @@ -24,6 +24,7 @@ var _ types.WasmEngine = &MockWasmEngine{} type MockWasmEngine struct { StoreCodeFn func(codeID wasmvm.WasmCode, gasLimit uint64) (wasmvm.Checksum, uint64, error) StoreCodeUncheckedFn func(codeID wasmvm.WasmCode) (wasmvm.Checksum, error) + SimulateStoreCodeFn func(codeID wasmvm.WasmCode, gasLimit uint64) (wasmvm.Checksum, uint64, error) AnalyzeCodeFn func(codeID wasmvm.Checksum) (*wasmvmtypes.AnalysisReport, error) InstantiateFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, info wasmvmtypes.MessageInfo, initMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.ContractResult, uint64, error) ExecuteFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, info wasmvmtypes.MessageInfo, executeMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.ContractResult, uint64, error) @@ -118,6 +119,13 @@ func (m *MockWasmEngine) StoreCodeUnchecked(codeID wasmvm.WasmCode) (wasmvm.Chec return m.StoreCodeUncheckedFn(codeID) } +func (m *MockWasmEngine) SimulateStoreCode(codeID wasmvm.WasmCode, gasLimit uint64) (wasmvm.Checksum, uint64, error) { + if m.SimulateStoreCodeFn == nil { + panic("not supposed to be called!") + } + return m.SimulateStoreCodeFn(codeID, gasLimit) +} + func (m *MockWasmEngine) AnalyzeCode(codeID wasmvm.Checksum) (*wasmvmtypes.AnalysisReport, error) { if m.AnalyzeCodeFn == nil { panic("not supposed to be called!") diff --git a/x/wasm/types/wasmer_engine.go b/x/wasm/types/wasmer_engine.go index 4dab6957d5..6233e06414 100644 --- a/x/wasm/types/wasmer_engine.go +++ b/x/wasm/types/wasmer_engine.go @@ -30,6 +30,11 @@ type WasmEngine interface { // Use this for adding code that was checked before, particularly in the case of state sync. StoreCodeUnchecked(code wasmvm.WasmCode) (wasmvm.Checksum, error) + // SimulateStoreCode works like StoreCode, but does not actually store the code. + // Instead, it just does all the validation and compilation steps without storing the result on disk. + // Returns both the checksum, as well as the gas cost of compilation (in CosmWasm Gas) or an error. + SimulateStoreCode(code wasmvm.WasmCode, gasLimit uint64) (wasmvm.Checksum, uint64, error) + // AnalyzeCode will statically analyze the code. // Currently just reports if it exposes all IBC entry points. AnalyzeCode(checksum wasmvm.Checksum) (*wasmvmtypes.AnalysisReport, error) From cb91d774da6112b2ac49d53a683ccf2b2a1082e9 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Thu, 19 Dec 2024 16:09:25 +0100 Subject: [PATCH 2/3] Add test for StoreCode simulation --- tests/integration/module_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/integration/module_test.go b/tests/integration/module_test.go index 3fec04c563..8edd94fa67 100644 --- a/tests/integration/module_test.go +++ b/tests/integration/module_test.go @@ -112,6 +112,21 @@ var ( oldContract = mustLoad("./testdata/escrow_0.7.wasm") ) +func TestStoreCodeSimulation(t *testing.T) { + data := setupTest(t) + data.ctx = data.ctx.WithExecMode(sdk.ExecModeSimulate) + + msg := &types.MsgStoreCode{ + Sender: addr1, + WASMByteCode: testContract, + } + + h := data.msgServiceRouter.Handler(msg) + + _, err := h(data.ctx, msg) + require.NoError(t, err) +} + func TestHandleCreate(t *testing.T) { cases := map[string]struct { msg sdk.Msg From 0b784841ab4fa53a54e93bb7741876f493902b65 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Thu, 19 Dec 2024 19:01:46 +0100 Subject: [PATCH 3/3] Update wasmvm --- Dockerfile | 8 ++++---- go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Dockerfile b/Dockerfile index 0b8e523a65..750f203aaa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,10 +15,10 @@ RUN apk add git WORKDIR /code COPY . /code/ # See https://github.com/CosmWasm/wasmvm/releases -ADD https://github.com/CosmWasm/wasmvm/releases/download/v2.2.0/libwasmvm_muslc.aarch64.a /lib/libwasmvm_muslc.aarch64.a -ADD https://github.com/CosmWasm/wasmvm/releases/download/v2.2.0/libwasmvm_muslc.x86_64.a /lib/libwasmvm_muslc.x86_64.a -RUN sha256sum /lib/libwasmvm_muslc.aarch64.a | grep f7e3c97481d7d9ce9469c5e14c76e1c45d17e7735d18bdec04782ab2645b382c -RUN sha256sum /lib/libwasmvm_muslc.x86_64.a | grep 7ee83ec96bfb962465000b12d0abc758528e36a4fafb49cdef15708059be0d2b +ADD https://github.com/CosmWasm/wasmvm/releases/download/v2.2.1/libwasmvm_muslc.aarch64.a /lib/libwasmvm_muslc.aarch64.a +ADD https://github.com/CosmWasm/wasmvm/releases/download/v2.2.1/libwasmvm_muslc.x86_64.a /lib/libwasmvm_muslc.x86_64.a +RUN sha256sum /lib/libwasmvm_muslc.aarch64.a | grep ba6cb5db6b14a265c8556326c045880908db9b1d2ffb5d4aa9f09ac09b24cecc +RUN sha256sum /lib/libwasmvm_muslc.x86_64.a | grep b3bd755efac0ff39c01b59b8110f961c48aa3eb93588071d7a628270cc1f2326 # force it to use static lib (from above) not standard libgo_cosmwasm.so file RUN LEDGER_ENABLED=false BUILD_TAGS=muslc LINK_STATICALLY=true make build diff --git a/go.mod b/go.mod index bfa6a34bcf..a08131a4c7 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/CosmWasm/wasmd go 1.23.1 require ( - github.com/CosmWasm/wasmvm/v2 v2.2.0 + github.com/CosmWasm/wasmvm/v2 v2.2.1 github.com/cosmos/cosmos-proto v1.0.0-beta.5 github.com/cosmos/cosmos-sdk v0.50.10 github.com/cosmos/gogogateway v1.2.0 // indirect diff --git a/go.sum b/go.sum index 7d08616693..9ad3cc0b6a 100644 --- a/go.sum +++ b/go.sum @@ -223,8 +223,8 @@ github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25 github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/CosmWasm/wasmvm/v2 v2.2.0 h1:PWHqwzltJYRyPPiBZiwBJ3Rkkbr6NESIz03u2TRGQfc= -github.com/CosmWasm/wasmvm/v2 v2.2.0/go.mod h1:bMhLQL4Yp9CzJi9A83aR7VO9wockOsSlZbT4ztOl6bg= +github.com/CosmWasm/wasmvm/v2 v2.2.1 h1:cmOnM+TDfUl2VRugeo1eJBw4U/Lw0WLviuQHKSo9DVQ= +github.com/CosmWasm/wasmvm/v2 v2.2.1/go.mod h1:bMhLQL4Yp9CzJi9A83aR7VO9wockOsSlZbT4ztOl6bg= github.com/DataDog/datadog-go v3.2.0+incompatible h1:qSG2N4FghB1He/r2mFrWKCaL7dXCilEuNEeAn20fdD4= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ=