diff --git a/Dockerfile b/Dockerfile index 902a61859d..3c0ff55178 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,10 +16,10 @@ WORKDIR /code COPY . /code/ # See https://github.com/CosmWasm/wasmvm/releases -ADD https://github.com/CosmWasm/wasmvm/releases/download/v1.0.0-rc.0/libwasmvm_muslc.aarch64.a /lib/libwasmvm_muslc.aarch64.a -ADD https://github.com/CosmWasm/wasmvm/releases/download/v1.0.0-rc.0/libwasmvm_muslc.x86_64.a /lib/libwasmvm_muslc.x86_64.a -RUN sha256sum /lib/libwasmvm_muslc.aarch64.a | grep 91a3f54e209345afa9a49aff50786d0a1ece510aa8e8530f5e68d9b42f6e0868 -RUN sha256sum /lib/libwasmvm_muslc.x86_64.a | grep eda70adcd2f09a0ae0a6c1e53ecc318809e6d57244bda7b7a29ccd9cf591aa37 +ADD https://github.com/CosmWasm/wasmvm/releases/download/v1.0.0/libwasmvm_muslc.aarch64.a /lib/libwasmvm_muslc.aarch64.a +ADD https://github.com/CosmWasm/wasmvm/releases/download/v1.0.0/libwasmvm_muslc.x86_64.a /lib/libwasmvm_muslc.x86_64.a +RUN sha256sum /lib/libwasmvm_muslc.aarch64.a | grep 7d2239e9f25e96d0d4daba982ce92367aacf0cbd95d2facb8442268f2b1cc1fc +RUN sha256sum /lib/libwasmvm_muslc.x86_64.a | grep f6282df732a13dec836cda1f399dd874b1e3163504dbd9607c6af915b2740479 # Copy the library you want to the final location that will be found by the linker flag `-lwasmvm_muslc` RUN cp /lib/libwasmvm_muslc.${arch}.a /lib/libwasmvm_muslc.a diff --git a/README.md b/README.md index 5b220a318b..c487e9f057 100644 --- a/README.md +++ b/README.md @@ -25,8 +25,8 @@ version is communicated by the contract via a Wasm export. This is the current compatibility list: | wasmd | wasmvm | cosmwasm-vm | cosmwasm-std | -|-------|--------------| ----------- | ------------ | -| 0.27 | v1.0.0-rc.0 | | 1.0 | +| ----- | ------------ | ----------- | ------------ | +| 0.27 | v1.0.0 | | 1.0 | | 0.26 | 1.0.0-beta10 | | 1.0 | | 0.25 | 1.0.0-beta10 | | 1.0 | | 0.24 | 1.0.0-beta7 | 1.0.0-beta6 | 1.0 | diff --git a/go.mod b/go.mod index ebdf4078ef..7a99fc1b93 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/CosmWasm/wasmd go 1.17 require ( - github.com/CosmWasm/wasmvm v1.0.0-rc.0 + github.com/CosmWasm/wasmvm v1.0.0 github.com/cosmos/cosmos-sdk v0.45.4 github.com/cosmos/iavl v0.17.3 github.com/cosmos/ibc-go/v3 v3.0.0 diff --git a/go.sum b/go.sum index 09cb25ca72..a2239dce57 100644 --- a/go.sum +++ b/go.sum @@ -81,8 +81,8 @@ github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= -github.com/CosmWasm/wasmvm v1.0.0-rc.0 h1:YI0ytwQZewPhSNxlqsrZ3/bVKTYXmrR1bfVapleCXWk= -github.com/CosmWasm/wasmvm v1.0.0-rc.0/go.mod h1:ei0xpvomwSdONsxDuONzV7bL1jSET1M8brEx0FCXc+A= +github.com/CosmWasm/wasmvm v1.0.0 h1:NRmnHe3xXsKn2uEcB1F5Ha323JVAhON+BI6L177dlKc= +github.com/CosmWasm/wasmvm v1.0.0/go.mod h1:ei0xpvomwSdONsxDuONzV7bL1jSET1M8brEx0FCXc+A= github.com/DATA-DOG/go-sqlmock v1.5.0/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.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= diff --git a/x/wasm/client/cli/query.go b/x/wasm/client/cli/query.go index 18f2390459..49cea64ea4 100644 --- a/x/wasm/client/cli/query.go +++ b/x/wasm/client/cli/query.go @@ -10,14 +10,13 @@ import ( "io/ioutil" "strconv" + wasmvm "github.com/CosmWasm/wasmvm" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/spf13/cobra" flag "github.com/spf13/pflag" - wasmvmapi "github.com/CosmWasm/wasmvm/api" - "github.com/CosmWasm/wasmd/x/wasm/types" ) @@ -52,7 +51,7 @@ func GetCmdLibVersion() *cobra.Command { Aliases: []string{"lib-version"}, Args: cobra.ExactArgs(0), RunE: func(cmd *cobra.Command, args []string) error { - version, err := wasmvmapi.LibwasmvmVersion() + version, err := wasmvm.LibwasmvmVersion() if err != nil { return fmt.Errorf("error retrieving libwasmvm version: %w", err) } diff --git a/x/wasm/ibc.go b/x/wasm/ibc.go index 6c138e9ab8..4d99b0f244 100644 --- a/x/wasm/ibc.go +++ b/x/wasm/ibc.go @@ -59,7 +59,7 @@ func (i IBCHandler) OnChanOpenInit( }, }, } - err = i.keeper.OnOpenChannel(ctx, contractAddr, msg) + _, err = i.keeper.OnOpenChannel(ctx, contractAddr, msg) if err != nil { return err } @@ -103,11 +103,15 @@ func (i IBCHandler) OnChanOpenTry( }, } - // DESIGN V3: Allow contracts to return a version (or default to counterpartyVersion if unset) - err = i.keeper.OnOpenChannel(ctx, contractAddr, msg) + // Allow contracts to return a version (or default to counterpartyVersion if unset) + version, err := i.keeper.OnOpenChannel(ctx, contractAddr, msg) if err != nil { return "", err } + if version == "" { + version = counterpartyVersion + } + // Module may have already claimed capability in OnChanOpenInit in the case of crossing hellos // (ie chainA and chainB both call ChanOpenInit before one of them calls ChanOpenTry) // If module can already authenticate the capability then module already owns it so we don't need to claim @@ -119,9 +123,7 @@ func (i IBCHandler) OnChanOpenTry( } } - // In the future, we can negotiate (see design comment above), but for now, we only error if we disagee - // with the proposed version - return counterpartyVersion, nil + return version, nil } // OnChanOpenAck implements the IBCModule interface @@ -240,7 +242,7 @@ func (i IBCHandler) OnRecvPacket( if err != nil { return channeltypes.NewErrorAcknowledgement(sdkerrors.Wrapf(err, "contract port id").Error()) } - msg := wasmvmtypes.IBCPacketReceiveMsg{Packet: newIBCPacket(packet)} + msg := wasmvmtypes.IBCPacketReceiveMsg{Packet: newIBCPacket(packet), Relayer: relayer.String()} ack, err := i.keeper.OnRecvPacket(ctx, contractAddr, msg) if err != nil { return channeltypes.NewErrorAcknowledgement(err.Error()) @@ -275,6 +277,7 @@ func (i IBCHandler) OnAcknowledgementPacket( err = i.keeper.OnAckPacket(ctx, contractAddr, wasmvmtypes.IBCPacketAckMsg{ Acknowledgement: wasmvmtypes.IBCAcknowledgement{Data: acknowledgement}, OriginalPacket: newIBCPacket(packet), + Relayer: relayer.String(), }) if err != nil { return sdkerrors.Wrap(err, "on ack") @@ -288,7 +291,7 @@ func (i IBCHandler) OnTimeoutPacket(ctx sdk.Context, packet channeltypes.Packet, if err != nil { return sdkerrors.Wrapf(err, "contract port id") } - msg := wasmvmtypes.IBCPacketTimeoutMsg{Packet: newIBCPacket(packet)} + msg := wasmvmtypes.IBCPacketTimeoutMsg{Packet: newIBCPacket(packet), Relayer: relayer.String()} err = i.keeper.OnTimeoutPacket(ctx, contractAddr, msg) if err != nil { return sdkerrors.Wrap(err, "on timeout") diff --git a/x/wasm/keeper/querier_test.go b/x/wasm/keeper/querier_test.go index 667f841c9d..f473f52fac 100644 --- a/x/wasm/keeper/querier_test.go +++ b/x/wasm/keeper/querier_test.go @@ -12,7 +12,7 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - cosmwasm "github.com/CosmWasm/wasmvm" + wasmvm "github.com/CosmWasm/wasmvm" wasmvmtypes "github.com/CosmWasm/wasmvm/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkErrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -185,7 +185,7 @@ func TestQuerySmartContractPanics(t *testing.T) { } for msg, spec := range specs { t.Run(msg, func(t *testing.T) { - keepers.WasmKeeper.wasmVM = &wasmtesting.MockWasmer{QueryFn: func(checksum cosmwasm.Checksum, env wasmvmtypes.Env, queryMsg []byte, store cosmwasm.KVStore, goapi cosmwasm.GoAPI, querier cosmwasm.Querier, gasMeter cosmwasm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) ([]byte, uint64, error) { + keepers.WasmKeeper.wasmVM = &wasmtesting.MockWasmer{QueryFn: func(checksum wasmvm.Checksum, env wasmvmtypes.Env, queryMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) ([]byte, uint64, error) { spec.doInContract() return nil, 0, nil }} diff --git a/x/wasm/keeper/relay.go b/x/wasm/keeper/relay.go index 9c1948dd2e..5a74ebe2ca 100644 --- a/x/wasm/keeper/relay.go +++ b/x/wasm/keeper/relay.go @@ -22,25 +22,30 @@ func (k Keeper) OnOpenChannel( ctx sdk.Context, contractAddr sdk.AccAddress, msg wasmvmtypes.IBCChannelOpenMsg, -) error { +) (string, error) { defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "ibc-open-channel") + version := "" _, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) if err != nil { - return err + return "", err } env := types.NewEnv(ctx, contractAddr) querier := k.newQueryHandler(ctx, contractAddr) gas := k.runtimeGasForContract(ctx) - gasUsed, execErr := k.wasmVM.IBCChannelOpen(codeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, costJSONDeserialization) + res, gasUsed, execErr := k.wasmVM.IBCChannelOpen(codeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, costJSONDeserialization) k.consumeRuntimeGas(ctx, gasUsed) if execErr != nil { - return sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) + return "", sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) + } + + if res != nil { + version = res.Version } - return nil + return version, nil } // OnConnectChannel calls the contract to let it know the IBC channel was established. diff --git a/x/wasm/keeper/relay_test.go b/x/wasm/keeper/relay_test.go index 64bf0aaa97..e6ed619606 100644 --- a/x/wasm/keeper/relay_test.go +++ b/x/wasm/keeper/relay_test.go @@ -57,9 +57,9 @@ func TestOnOpenChannel(t *testing.T) { t.Run(name, func(t *testing.T) { myChannel := wasmvmtypes.IBCChannel{Version: "my test channel"} myMsg := wasmvmtypes.IBCChannelOpenMsg{OpenTry: &wasmvmtypes.IBCOpenTry{Channel: myChannel, CounterpartyVersion: "foo"}} - m.IBCChannelOpenFn = func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelOpenMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (uint64, error) { + m.IBCChannelOpenFn = func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelOpenMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBC3ChannelOpenResponse, uint64, error) { assert.Equal(t, myMsg, msg) - return spec.contractGas * DefaultGasMultiplier, spec.contractErr + return &wasmvmtypes.IBC3ChannelOpenResponse{}, spec.contractGas * DefaultGasMultiplier, spec.contractErr } ctx, _ := parentCtx.CacheContext() @@ -72,7 +72,7 @@ func TestOnOpenChannel(t *testing.T) { CounterpartyVersion: "foo", }, } - err := keepers.WasmKeeper.OnOpenChannel(ctx, spec.contractAddr, msg) + _, err := keepers.WasmKeeper.OnOpenChannel(ctx, spec.contractAddr, msg) // then if spec.expErr { diff --git a/x/wasm/keeper/wasmtesting/mock_engine.go b/x/wasm/keeper/wasmtesting/mock_engine.go index 6a7dc7c137..ebf7dbcf19 100644 --- a/x/wasm/keeper/wasmtesting/mock_engine.go +++ b/x/wasm/keeper/wasmtesting/mock_engine.go @@ -27,7 +27,7 @@ type MockWasmer struct { ReplyFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, reply wasmvmtypes.Reply, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) GetCodeFn func(codeID wasmvm.Checksum) (wasmvm.WasmCode, error) CleanupFn func() - IBCChannelOpenFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelOpenMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (uint64, error) + IBCChannelOpenFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelOpenMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBC3ChannelOpenResponse, uint64, error) IBCChannelConnectFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelConnectMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) IBCChannelCloseFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelCloseMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) IBCPacketReceiveFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCPacketReceiveMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCReceiveResult, uint64, error) @@ -38,7 +38,7 @@ type MockWasmer struct { GetMetricsFn func() (*wasmvmtypes.Metrics, error) } -func (m *MockWasmer) IBCChannelOpen(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelOpenMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (uint64, error) { +func (m *MockWasmer) IBCChannelOpen(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelOpenMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBC3ChannelOpenResponse, uint64, error) { if m.IBCChannelOpenFn == nil { panic("not supposed to be called!") } @@ -210,7 +210,7 @@ type IBCContractCallbacks interface { gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction, - ) (uint64, error) + ) (*wasmvmtypes.IBC3ChannelOpenResponse, uint64, error) IBCChannelConnect( codeID wasmvm.Checksum, diff --git a/x/wasm/relay_pingpong_test.go b/x/wasm/relay_pingpong_test.go index 45dd73c48e..46c32497b3 100644 --- a/x/wasm/relay_pingpong_test.go +++ b/x/wasm/relay_pingpong_test.go @@ -180,11 +180,11 @@ func (p *player) Execute(code wasmvm.Checksum, env wasmvmtypes.Env, info wasmvmt } // OnIBCChannelOpen ensures to accept only configured version -func (p player) IBCChannelOpen(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelOpenMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (uint64, error) { +func (p player) IBCChannelOpen(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelOpenMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBC3ChannelOpenResponse, uint64, error) { if msg.GetChannel().Version != p.actor { - return 0, nil + return &wasmvmtypes.IBC3ChannelOpenResponse{}, 0, nil } - return 0, nil + return &wasmvmtypes.IBC3ChannelOpenResponse{}, 0, nil } // OnIBCChannelConnect persists connection endpoints diff --git a/x/wasm/relay_test.go b/x/wasm/relay_test.go index eca882db3d..5edd182d59 100644 --- a/x/wasm/relay_test.go +++ b/x/wasm/relay_test.go @@ -605,8 +605,8 @@ func (c *errorReceiverContract) IBCPacketReceive(codeID wasmvm.Checksum, env was // simple helper struct that implements connection setup methods. type contractStub struct{} -func (s *contractStub) IBCChannelOpen(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelOpenMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (uint64, error) { - return 0, nil +func (s *contractStub) IBCChannelOpen(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelOpenMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBC3ChannelOpenResponse, uint64, error) { + return &wasmvmtypes.IBC3ChannelOpenResponse{}, 0, nil } func (s *contractStub) IBCChannelConnect(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelConnectMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) { diff --git a/x/wasm/types/exported_keepers.go b/x/wasm/types/exported_keepers.go index c48a3615c5..bb919a3189 100644 --- a/x/wasm/types/exported_keepers.go +++ b/x/wasm/types/exported_keepers.go @@ -64,7 +64,7 @@ type IBCContractKeeper interface { ctx sdk.Context, contractAddr sdk.AccAddress, msg wasmvmtypes.IBCChannelOpenMsg, - ) error + ) (string, error) OnConnectChannel( ctx sdk.Context, contractAddr sdk.AccAddress, diff --git a/x/wasm/types/wasmer_engine.go b/x/wasm/types/wasmer_engine.go index 416a0dc691..e35cf331d1 100644 --- a/x/wasm/types/wasmer_engine.go +++ b/x/wasm/types/wasmer_engine.go @@ -148,7 +148,7 @@ type WasmerEngine interface { gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction, - ) (uint64, error) + ) (*wasmvmtypes.IBC3ChannelOpenResponse, uint64, error) // IBCChannelConnect is available on IBC-enabled contracts and is a hook to call into // during the handshake pahse