Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade to WasmVM v0.15.1 #548

Merged
merged 3 commits into from
Jul 21, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ WORKDIR /code
COPY . /code/

# See https://github.com/CosmWasm/wasmvm/releases
ADD https://github.com/CosmWasm/wasmvm/releases/download/v0.14.0/libwasmvm_muslc.a /lib/libwasmvm_muslc.a
RUN sha256sum /lib/libwasmvm_muslc.a | grep 220b85158d1ae72008f099a7ddafe27f6374518816dd5873fd8be272c5418026
ADD https://github.com/CosmWasm/wasmvm/releases/download/v0.15.1/libwasmvm_muslc.a /lib/libwasmvm_muslc.a
RUN sha256sum /lib/libwasmvm_muslc.a | grep 379c61d2e53f87f63639eaa8ba8bbe687e5833158bb10e0dc0523c3377248d01

# force it to use static lib (from above) not standard libgo_cosmwasm.so file
RUN LEDGER_ENABLED=false BUILD_TAGS=muslc make build
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ compatibility list:

| wasmd | cosmwasm-vm | cosmwasm-std |
| ----- | ----------- | ------------ |
| 0.18 | 0.15 | 0.15 |
| 0.17 | 0.14 | 0.14 |
| 0.16 | 0.14 | 0.14 |
| 0.15 | 0.13 | 0.11-0.13 |
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/CosmWasm/wasmd
go 1.15

require (
github.com/CosmWasm/wasmvm v0.14.0
github.com/CosmWasm/wasmvm v0.15.1
github.com/cosmos/cosmos-sdk v0.42.5
github.com/cosmos/iavl v0.16.0
github.com/dvsekhvalnov/jose2go v0.0.0-20200901110807-248326c1351b
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
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 v0.14.0 h1:oceacwdwD9d9GzqElOrB8Qu1topx4+zM47VEqnJ/9Jo=
github.com/CosmWasm/wasmvm v0.14.0/go.mod h1:Id107qllDJyJjVQQsKMOy2YYF98sqPJ2t+jX1QES40A=
github.com/CosmWasm/wasmvm v0.15.1 h1:5hPBqPzHzVGtISJy/Mr89PbNIe+a3Q6qaFbnOFu/m64=
github.com/CosmWasm/wasmvm v0.15.1/go.mod h1:Id107qllDJyJjVQQsKMOy2YYF98sqPJ2t+jX1QES40A=
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=
github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ=
Expand Down
3 changes: 1 addition & 2 deletions x/wasm/alias.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const (
MaxLabelSize = types.MaxLabelSize
BuildTagRegexp = types.BuildTagRegexp
MaxBuildTagSize = types.MaxBuildTagSize
CustomEventType = types.CustomEventType
WasmModuleEventType = types.WasmModuleEventType
AttributeKeyContractAddr = types.AttributeKeyContractAddr
ProposalTypeStoreCode = types.ProposalTypeStoreCode
ProposalTypeInstantiateContract = types.ProposalTypeInstantiateContract
Expand Down Expand Up @@ -53,7 +53,6 @@ var (
NewContractInfo = types.NewContractInfo
NewEnv = types.NewEnv
NewWasmCoins = types.NewWasmCoins
ParseEvents = types.ParseEvents
DefaultWasmConfig = types.DefaultWasmConfig
DefaultParams = types.DefaultParams
InitGenesis = keeper.InitGenesis
Expand Down
10 changes: 5 additions & 5 deletions x/wasm/ibc.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,14 +195,14 @@ func (i IBCHandler) OnRecvPacket(
if err != nil {
return nil, nil, sdkerrors.Wrapf(err, "contract port id")
}
msgBz, err := i.keeper.OnRecvPacket(ctx, contractAddr, newIBCPacket(packet))
ack, err := i.keeper.OnRecvPacket(ctx, contractAddr, newIBCPacket(packet))
if err != nil {
return nil, nil, err
}

return &sdk.Result{
return &sdk.Result{ // the response is ignored
Events: ctx.EventManager().Events().ToABCIEvents(),
}, msgBz, nil
}, ack, nil
}

// OnAcknowledgementPacket implements the IBCModule interface
Expand All @@ -212,8 +212,8 @@ func (i IBCHandler) OnAcknowledgementPacket(ctx sdk.Context, packet channeltypes
return nil, sdkerrors.Wrapf(err, "contract port id")
}

err = i.keeper.OnAckPacket(ctx, contractAddr, wasmvmtypes.IBCAcknowledgement{
Acknowledgement: acknowledgement,
err = i.keeper.OnAckPacket(ctx, contractAddr, wasmvmtypes.IBCAcknowledgementWithPacket{
Acknowledgement: wasmvmtypes.IBCAcknowledgement{Data: acknowledgement},
OriginalPacket: newIBCPacket(packet),
})
if err != nil {
Expand Down
12 changes: 10 additions & 2 deletions x/wasm/keeper/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package keeper
import (
"fmt"
wasmvm "github.com/CosmWasm/wasmvm"
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
sdk "github.com/cosmos/cosmos-sdk/types"
)

Expand All @@ -11,11 +12,18 @@ const (
DefaultGasCostHumanAddress = 5
// DefaultGasCostCanonicalAddress is how moch SDK gas we charge to convert to a canonical address format
DefaultGasCostCanonicalAddress = 4

// DefaultDeserializationCostPerByte The formular should be `len(data) * deserializationCostPerByte`
DefaultDeserializationCostPerByte = 1
)

var (
costHumanize = DefaultGasCostHumanAddress * DefaultGasMultiplier
costCanonical = DefaultGasCostCanonicalAddress * DefaultGasMultiplier
costHumanize = DefaultGasCostHumanAddress * DefaultGasMultiplier
costCanonical = DefaultGasCostCanonicalAddress * DefaultGasMultiplier
costJsonDeserialization = wasmvmtypes.UFraction{
Numerator: DefaultDeserializationCostPerByte * DefaultGasMultiplier,
Denominator: 1,
}
)

func humanAddress(canon []byte) (string, uint64, error) {
Expand Down
59 changes: 59 additions & 0 deletions x/wasm/keeper/events.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package keeper

import (
"fmt"
"github.com/CosmWasm/wasmd/x/wasm/types"
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
sdk "github.com/cosmos/cosmos-sdk/types"
)

// newWasmModuleEvent creates with wasm module event for interacting with the given contract. Adds custom attributes
// to this event.
func newWasmModuleEvent(customAttributes []wasmvmtypes.EventAttribute, contractAddr sdk.AccAddress) sdk.Events {
attrs := contractSDKEventAttributes(customAttributes, contractAddr)

// each wasm invocation always returns one sdk.Event
return sdk.Events{sdk.NewEvent(types.WasmModuleEventType, attrs...)}
}

// returns true when a wasm module event was emitted for this contract already
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice to avoid duplicates with reply, etc

func hasWasmModuleEvent(ctx sdk.Context, contractAddr sdk.AccAddress) bool {
for _, e := range ctx.EventManager().Events() {
if e.Type == types.WasmModuleEventType {
for _, a := range e.Attributes {
if string(a.Key) == types.AttributeKeyContractAddr && string(a.Value) == contractAddr.String() {
return true
}
}
}
}
return false
}

const eventTypeMinLength = 2

// newCustomEvents converts wasmvm events from a contract response to sdk type events
func newCustomEvents(evts wasmvmtypes.Events, contractAddr sdk.AccAddress) sdk.Events {
events := make(sdk.Events, 0, len(evts))
for _, e := range evts {
if len(e.Type) <= eventTypeMinLength {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like silent failures/filters. I would prefer returning an error (even panic-ing in Go), Devs learn quick when things panic. They ignore errors for months if they are silently ignored

continue
}
attributes := contractSDKEventAttributes(e.Attributes, contractAddr)
events = append(events, sdk.NewEvent(fmt.Sprintf("%s%s", types.CustomContractEventPrefix, e.Type), attributes...))
}
return events
}

// convert and add contract address issuing this event
func contractSDKEventAttributes(customAttributes []wasmvmtypes.EventAttribute, contractAddr sdk.AccAddress) []sdk.Attribute {
attrs := []sdk.Attribute{sdk.NewAttribute(types.AttributeKeyContractAddr, contractAddr.String())}
// append attributes from wasm to the sdk.Event
for _, l := range customAttributes {
// and reserve the contract_address key for our use (not contract)
if l.Key != types.AttributeKeyContractAddr {
attrs = append(attrs, sdk.NewAttribute(l.Key, l.Value))
}
}
return attrs
}
160 changes: 160 additions & 0 deletions x/wasm/keeper/events_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
package keeper

import (
"context"
"github.com/CosmWasm/wasmd/x/wasm/types"
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/assert"
"testing"
)

func TestHasWasmModuleEvent(t *testing.T) {
myContractAddr := RandomAccountAddress(t)
specs := map[string]struct {
srcEvents []sdk.Event
exp bool
}{
"event found": {
srcEvents: []sdk.Event{
sdk.NewEvent(types.WasmModuleEventType, sdk.NewAttribute("contract_address", myContractAddr.String())),
},
exp: true,
},
"different event: not found": {
srcEvents: []sdk.Event{
sdk.NewEvent(types.CustomContractEventPrefix, sdk.NewAttribute("contract_address", myContractAddr.String())),
},
exp: false,
},
"event with different address: not found": {
srcEvents: []sdk.Event{
sdk.NewEvent(types.WasmModuleEventType, sdk.NewAttribute("contract_address", RandomBech32AccountAddress(t))),
},
exp: false,
},
"no event": {
srcEvents: []sdk.Event{},
exp: false,
},
}
for name, spec := range specs {
t.Run(name, func(t *testing.T) {
em := sdk.NewEventManager()
em.EmitEvents(spec.srcEvents)
ctx := sdk.Context{}.WithContext(context.Background()).WithEventManager(em)

got := hasWasmModuleEvent(ctx, myContractAddr)
assert.Equal(t, spec.exp, got)
})
}
}

func TestNewCustomEvents(t *testing.T) {
myContract := RandomAccountAddress(t)
specs := map[string]struct {
src wasmvmtypes.Events
exp sdk.Events
}{
"all good": {
src: wasmvmtypes.Events{{
Type: "foo",
Attributes: []wasmvmtypes.EventAttribute{{Key: "myKey", Value: "myVal"}},
}},
exp: sdk.Events{sdk.NewEvent("wasm-foo",
sdk.NewAttribute("contract_address", myContract.String()),
sdk.NewAttribute("myKey", "myVal"))},
},
"multiple attributes": {
src: wasmvmtypes.Events{{
Type: "foo",
Attributes: []wasmvmtypes.EventAttribute{{Key: "myKey", Value: "myVal"},
{Key: "myOtherKey", Value: "myOtherVal"}},
}},
exp: sdk.Events{sdk.NewEvent("wasm-foo",
sdk.NewAttribute("contract_address", myContract.String()),
sdk.NewAttribute("myKey", "myVal"),
sdk.NewAttribute("myOtherKey", "myOtherVal"))},
},
"multiple events": {
src: wasmvmtypes.Events{{
Type: "foo",
Attributes: []wasmvmtypes.EventAttribute{{Key: "myKey", Value: "myVal"}},
}, {
Type: "bar",
Attributes: []wasmvmtypes.EventAttribute{{Key: "otherKey", Value: "otherVal"}},
}},
exp: sdk.Events{sdk.NewEvent("wasm-foo",
sdk.NewAttribute("contract_address", myContract.String()),
sdk.NewAttribute("myKey", "myVal")),
sdk.NewEvent("wasm-bar",
sdk.NewAttribute("contract_address", myContract.String()),
sdk.NewAttribute("otherKey", "otherVal"))},
},
"without attributes": {
src: wasmvmtypes.Events{{
Type: "foo",
}},
exp: sdk.Events{sdk.NewEvent("wasm-foo",
sdk.NewAttribute("contract_address", myContract.String()))},
},
"min length not reached": {
src: wasmvmtypes.Events{{
Type: "f",
}},
exp: sdk.Events{},
},
"overwrite contract_address": {
src: wasmvmtypes.Events{{
Type: "foo",
Attributes: []wasmvmtypes.EventAttribute{{Key: "contract_address", Value: RandomBech32AccountAddress(t)}},
}},
exp: sdk.Events{sdk.NewEvent("wasm-foo",
sdk.NewAttribute("contract_address", myContract.String()))},
},
}
for name, spec := range specs {
t.Run(name, func(t *testing.T) {
gotEvent := newCustomEvents(spec.src, myContract)
assert.Equal(t, spec.exp, gotEvent)
})
}
}

func TestNewWasmModuleEvent(t *testing.T) {
myContract := RandomAccountAddress(t)
specs := map[string]struct {
src []wasmvmtypes.EventAttribute
exp sdk.Events
}{
"all good": {
src: []wasmvmtypes.EventAttribute{{Key: "myKey", Value: "myVal"}},
exp: sdk.Events{sdk.NewEvent("wasm",
sdk.NewAttribute("contract_address", myContract.String()),
sdk.NewAttribute("myKey", "myVal"))},
},
"multiple attributes": {
src: []wasmvmtypes.EventAttribute{{Key: "myKey", Value: "myVal"},
{Key: "myOtherKey", Value: "myOtherVal"}},
exp: sdk.Events{sdk.NewEvent("wasm",
sdk.NewAttribute("contract_address", myContract.String()),
sdk.NewAttribute("myKey", "myVal"),
sdk.NewAttribute("myOtherKey", "myOtherVal"))},
},
"without attributes": {
exp: sdk.Events{sdk.NewEvent("wasm",
sdk.NewAttribute("contract_address", myContract.String()))},
},
"overwrite contract_address": {
src: []wasmvmtypes.EventAttribute{{Key: "contract_address", Value: RandomBech32AccountAddress(t)}},
exp: sdk.Events{sdk.NewEvent("wasm",
sdk.NewAttribute("contract_address", myContract.String()))},
},
}
for name, spec := range specs {
t.Run(name, func(t *testing.T) {
gotEvent := newWasmModuleEvent(spec.src, myContract)
assert.Equal(t, spec.exp, gotEvent)
})
}
}
Loading