diff --git a/x/wasm/module.go b/x/wasm/module.go index c7ea6339c0..7973c8db97 100644 --- a/x/wasm/module.go +++ b/x/wasm/module.go @@ -3,7 +3,10 @@ package wasm import ( "context" "encoding/json" + "fmt" "math/rand" + "runtime/debug" + "strings" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" @@ -24,6 +27,7 @@ import ( "github.com/CosmWasm/wasmd/x/wasm/keeper" "github.com/CosmWasm/wasmd/x/wasm/simulation" "github.com/CosmWasm/wasmd/x/wasm/types" + wasmvm "github.com/CosmWasm/wasmvm" ) var ( @@ -217,6 +221,8 @@ func AddModuleInitFlags(startCmd *cobra.Command) { startCmd.Flags().Uint32(flagWasmMemoryCacheSize, defaults.MemoryCacheSize, "Sets the size in MiB (NOT bytes) of an in-memory cache for Wasm modules. Set to 0 to disable.") startCmd.Flags().Uint64(flagWasmQueryGasLimit, defaults.SmartQueryGasLimit, "Set the max gas that can be spent on executing a query with a Wasm contract") startCmd.Flags().String(flagWasmSimulationGasLimit, "", "Set the max gas that can be spent when executing a simulation TX") + + startCmd.PreRunE = chainPreRuns(checkLibwasmVersion, startCmd.PreRunE) } // ReadWasmConfig reads the wasm specifig configuration @@ -250,3 +256,50 @@ func ReadWasmConfig(opts servertypes.AppOptions) (types.WasmConfig, error) { } return cfg, nil } + +func getExpectedLibwasmVersion() string { + buildInfo, ok := debug.ReadBuildInfo() + if !ok { + panic("can't read build info") + } + for _, d := range buildInfo.Deps { + if d.Path != "github.com/CosmWasm/wasmvm" { + continue + } + if d.Replace != nil { + return d.Replace.Version + } + return d.Version + } + return "" +} + +func checkLibwasmVersion(cmd *cobra.Command, args []string) error { + wasmVersion, err := wasmvm.LibwasmvmVersion() + if err != nil { + return fmt.Errorf("unable to retrieve libwasmversion %w", err) + } + wasmExpectedVersion := getExpectedLibwasmVersion() + if wasmExpectedVersion == "" { + return fmt.Errorf("wasmvm module not exist") + } + if !strings.Contains(wasmExpectedVersion, wasmVersion) { + return fmt.Errorf("libwasmversion mismatch. got: %s; expected: %s", wasmVersion, wasmExpectedVersion) + } + return nil +} + +type preRunFn func(cmd *cobra.Command, args []string) error + +func chainPreRuns(pfns ...preRunFn) preRunFn { + return func(cmd *cobra.Command, args []string) error { + for _, pfn := range pfns { + if pfn != nil { + if err := pfn(cmd, args); err != nil { + return err + } + } + } + return nil + } +}