Upgrade wasmvm v0.15.x

This commit is contained in:
Alex Peters 2021-06-25 15:51:37 +02:00
parent a29b298ea3
commit b0b1fa88bc
No known key found for this signature in database
GPG Key ID: 55CCC24B5703B7D6
39 changed files with 725 additions and 330 deletions

2
go.mod
View File

@ -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

4
go.sum
View File

@ -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=

View File

@ -22,7 +22,7 @@ const (
MaxLabelSize = types.MaxLabelSize
BuildTagRegexp = types.BuildTagRegexp
MaxBuildTagSize = types.MaxBuildTagSize
CustomEventType = types.CustomEventType
CustomEventType = types.WasmModuleEventType
AttributeKeyContractAddr = types.AttributeKeyContractAddr
ProposalTypeStoreCode = types.ProposalTypeStoreCode
ProposalTypeInstantiateContract = types.ProposalTypeInstantiateContract
@ -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

View File

@ -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
@ -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 {

View File

@ -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"
)
@ -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) {

59
x/wasm/keeper/events.go Normal file
View File

@ -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
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 {
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
}

View File

@ -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)
})
}
}

View File

@ -29,6 +29,8 @@ const (
DefaultContractMessageDataCost uint64 = 1
// DefaultPerAttributeCost is how much SDK gas we charge per attribute count.
DefaultPerAttributeCost uint64 = 10
// DefaultPerCustomEventCost is how much SDK gas we charge per event count.
DefaultPerCustomEventCost uint64 = 20
// DefaultEventAttributeDataFreeTier number of bytes of total attribute data we do not charge.
DefaultEventAttributeDataFreeTier = 100
)
@ -44,7 +46,7 @@ type GasRegister interface {
// ReplyCosts costs to to handle a message reply
ReplyCosts(pinned bool, reply wasmvmtypes.Reply) sdk.Gas
// EventCosts costs to persist an event
EventCosts(evts []wasmvmtypes.EventAttribute) sdk.Gas
EventCosts(attrs []wasmvmtypes.EventAttribute, events wasmvmtypes.Events) sdk.Gas
// ToWasmVMGas converts from sdk gas to wasmvm gas
ToWasmVMGas(source sdk.Gas) uint64
// FromWasmVMGas converts from wasmvm gas to sdk gas
@ -67,10 +69,12 @@ type WasmGasRegisterConfig struct {
// This is used with len(key) + len(value)
EventAttributeDataCost sdk.Gas
// EventAttributeDataFreeTier number of bytes of total attribute data that is free of charge
EventAttributeDataFreeTier int
EventAttributeDataFreeTier uint64
// ContractMessageDataCost SDK gas charged *per byte* of the message that goes to the contract
// This is used with len(msg)
ContractMessageDataCost sdk.Gas
// CustomEventCost cost per custom event
CustomEventCost uint64
}
// DefaultGasRegisterConfig default values
@ -80,6 +84,7 @@ func DefaultGasRegisterConfig() WasmGasRegisterConfig {
CompileCost: DefaultCompileCost,
GasMultiplier: DefaultGasMultiplier,
EventPerAttributeCost: DefaultPerAttributeCost,
CustomEventCost: DefaultPerCustomEventCost,
EventAttributeDataCost: DefaultEventAttributeDataCost,
EventAttributeDataFreeTier: DefaultEventAttributeDataFreeTier,
ContractMessageDataCost: DefaultContractMessageDataCost,
@ -143,33 +148,49 @@ func (g WasmGasRegister) ReplyCosts(pinned bool, reply wasmvmtypes.Reply) sdk.Ga
attrs = append(e.Attributes)
}
// apply free tier on the whole set not per event
eventGas += g.EventCosts(attrs)
eventGas += g.EventCosts(attrs, nil)
}
return eventGas + g.InstantiateContractCosts(pinned, msgLen)
}
// EventCosts costs to persist an event
func (g WasmGasRegister) EventCosts(evts []wasmvmtypes.EventAttribute) sdk.Gas {
if len(evts) == 0 {
return 0
func (g WasmGasRegister) EventCosts(attrs []wasmvmtypes.EventAttribute, events wasmvmtypes.Events) sdk.Gas {
gas, remainingFreeTier := g.eventAttributeCosts(attrs, g.c.EventAttributeDataFreeTier)
for _, e := range events {
gas += g.c.CustomEventCost
gas += sdk.Gas(len(e.Type)) * g.c.EventAttributeDataCost // no free tier with event type
var attrCost sdk.Gas
attrCost, remainingFreeTier = g.eventAttributeCosts(e.Attributes, remainingFreeTier)
gas += attrCost
}
var storedBytes int
for _, l := range evts {
storedBytes += len(l.Key) + len(l.Value)
return gas
}
func (g WasmGasRegister) eventAttributeCosts(attrs []wasmvmtypes.EventAttribute, freeTier uint64) (sdk.Gas, uint64) {
if len(attrs) == 0 {
return 0, freeTier
}
// apply free tier
if storedBytes <= g.c.EventAttributeDataFreeTier {
storedBytes = 0
} else {
storedBytes -= g.c.EventAttributeDataFreeTier
var storedBytes uint64
for _, l := range attrs {
storedBytes += uint64(len(l.Key)) + uint64(len(l.Value))
}
storedBytes, freeTier = calcWithFreeTier(storedBytes, freeTier)
// total Length * costs + attribute count * costs
r := sdk.NewIntFromUint64(g.c.EventAttributeDataCost).Mul(sdk.NewIntFromUint64(uint64(storedBytes))).
Add(sdk.NewIntFromUint64(g.c.EventPerAttributeCost).Mul(sdk.NewIntFromUint64(uint64(len(evts)))))
r := sdk.NewIntFromUint64(g.c.EventAttributeDataCost).Mul(sdk.NewIntFromUint64(storedBytes)).
Add(sdk.NewIntFromUint64(g.c.EventPerAttributeCost).Mul(sdk.NewIntFromUint64(uint64(len(attrs)))))
if !r.IsUint64() {
panic(sdk.ErrorOutOfGas{Descriptor: "overflow"})
}
return r.Uint64()
return r.Uint64(), freeTier
}
// apply free tier
func calcWithFreeTier(storedBytes uint64, freeTier uint64) (uint64, uint64) {
if storedBytes <= freeTier {
return 0, freeTier - storedBytes
}
storedBytes -= freeTier
return storedBytes, 0
}
// ToWasmVMGas convert to wasmVM contract runtime gas unit

View File

@ -10,6 +10,7 @@ import (
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
ibctransfertypes "github.com/cosmos/cosmos-sdk/x/ibc/applications/transfer/types"
ibcclienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types"
channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types"
@ -32,6 +33,7 @@ type MessageEncoders struct {
Staking func(sender sdk.AccAddress, msg *wasmvmtypes.StakingMsg) ([]sdk.Msg, error)
Stargate func(sender sdk.AccAddress, msg *wasmvmtypes.StargateMsg) ([]sdk.Msg, error)
Wasm func(sender sdk.AccAddress, msg *wasmvmtypes.WasmMsg) ([]sdk.Msg, error)
Gov func(sender sdk.AccAddress, msg *wasmvmtypes.GovMsg) ([]sdk.Msg, error)
}
func DefaultEncoders(unpacker codectypes.AnyUnpacker, portSource types.ICS20TransferPortSource) MessageEncoders {
@ -43,6 +45,7 @@ func DefaultEncoders(unpacker codectypes.AnyUnpacker, portSource types.ICS20Tran
Staking: EncodeStakingMsg,
Stargate: EncodeStargateMsg(unpacker),
Wasm: EncodeWasmMsg,
Gov: EncodeGovMsg,
}
}
@ -71,6 +74,9 @@ func (e MessageEncoders) Merge(o *MessageEncoders) MessageEncoders {
if o.Wasm != nil {
e.Wasm = o.Wasm
}
if o.Gov != nil {
e.Gov = o.Gov
}
return e
}
@ -90,6 +96,8 @@ func (e MessageEncoders) Encode(ctx sdk.Context, contractAddr sdk.AccAddress, co
return e.Stargate(contractAddr, msg.Stargate)
case msg.Wasm != nil:
return e.Wasm(contractAddr, msg.Wasm)
case msg.Gov != nil:
return EncodeGovMsg(contractAddr, msg.Gov)
}
return nil, sdkerrors.Wrap(types.ErrUnknownMsg, "unknown variant of Wasm")
}
@ -198,7 +206,7 @@ func EncodeStargateMsg(unpacker codectypes.AnyUnpacker) StargateEncoder {
func EncodeWasmMsg(sender sdk.AccAddress, msg *wasmvmtypes.WasmMsg) ([]sdk.Msg, error) {
switch {
case msg.Execute != nil:
coins, err := convertWasmCoinsToSdkCoins(msg.Execute.Send)
coins, err := convertWasmCoinsToSdkCoins(msg.Execute.Funds)
if err != nil {
return nil, err
}
@ -211,7 +219,7 @@ func EncodeWasmMsg(sender sdk.AccAddress, msg *wasmvmtypes.WasmMsg) ([]sdk.Msg,
}
return []sdk.Msg{&sdkMsg}, nil
case msg.Instantiate != nil:
coins, err := convertWasmCoinsToSdkCoins(msg.Instantiate.Send)
coins, err := convertWasmCoinsToSdkCoins(msg.Instantiate.Funds)
if err != nil {
return nil, err
}
@ -280,6 +288,27 @@ func EncodeIBCMsg(portSource types.ICS20TransferPortSource) func(ctx sdk.Context
}
}
}
func EncodeGovMsg(sender sdk.AccAddress, msg *wasmvmtypes.GovMsg) ([]sdk.Msg, error) {
var option govtypes.VoteOption
switch msg.Vote.Vote {
case wasmvmtypes.Yes:
option = govtypes.OptionYes
case wasmvmtypes.No:
option = govtypes.OptionNo
case wasmvmtypes.NoWithVeto:
option = govtypes.OptionNoWithVeto
case wasmvmtypes.Abstain:
option = govtypes.OptionAbstain
}
vote := &govtypes.MsgVote{
ProposalId: msg.Vote.ProposalId,
Voter: sender.String(),
Option: option,
}
return []sdk.Msg{vote}, nil
}
func convertWasmIBCTimeoutHeightToCosmosHeight(ibcTimeoutBlock *wasmvmtypes.IBCTimeoutBlock) ibcclienttypes.Height {
if ibcTimeoutBlock == nil {
return ibcclienttypes.NewHeight(0, 0)

View File

@ -147,7 +147,7 @@ func TestEncoding(t *testing.T) {
Execute: &wasmvmtypes.ExecuteMsg{
ContractAddr: addr2.String(),
Msg: jsonMsg,
Send: []wasmvmtypes.Coin{
Funds: []wasmvmtypes.Coin{
wasmvmtypes.NewCoin(12, "eth"),
},
},
@ -169,7 +169,7 @@ func TestEncoding(t *testing.T) {
Instantiate: &wasmvmtypes.InstantiateMsg{
CodeID: 7,
Msg: jsonMsg,
Send: []wasmvmtypes.Coin{
Funds: []wasmvmtypes.Coin{
wasmvmtypes.NewCoin(123, "eth"),
},
Label: "myLabel",
@ -499,6 +499,70 @@ func TestEncoding(t *testing.T) {
},
},
},
"Gov vote: yes": {
sender: addr1,
srcContractIBCPort: "myIBCPort",
srcMsg: wasmvmtypes.CosmosMsg{
Gov: &wasmvmtypes.GovMsg{
Vote: &wasmvmtypes.VoteMsg{ProposalId: 1, Vote: wasmvmtypes.Yes},
},
},
output: []sdk.Msg{
&govtypes.MsgVote{
ProposalId: 1,
Voter: addr1.String(),
Option: govtypes.OptionYes,
},
},
},
"Gov vote: No": {
sender: addr1,
srcContractIBCPort: "myIBCPort",
srcMsg: wasmvmtypes.CosmosMsg{
Gov: &wasmvmtypes.GovMsg{
Vote: &wasmvmtypes.VoteMsg{ProposalId: 1, Vote: wasmvmtypes.No},
},
},
output: []sdk.Msg{
&govtypes.MsgVote{
ProposalId: 1,
Voter: addr1.String(),
Option: govtypes.OptionNo,
},
},
},
"Gov vote: Abstain": {
sender: addr1,
srcContractIBCPort: "myIBCPort",
srcMsg: wasmvmtypes.CosmosMsg{
Gov: &wasmvmtypes.GovMsg{
Vote: &wasmvmtypes.VoteMsg{ProposalId: 10, Vote: wasmvmtypes.Abstain},
},
},
output: []sdk.Msg{
&govtypes.MsgVote{
ProposalId: 10,
Voter: addr1.String(),
Option: govtypes.OptionAbstain,
},
},
},
"Gov vote: No with veto": {
sender: addr1,
srcContractIBCPort: "myIBCPort",
srcMsg: wasmvmtypes.CosmosMsg{
Gov: &wasmvmtypes.GovMsg{
Vote: &wasmvmtypes.VoteMsg{ProposalId: 1, Vote: wasmvmtypes.NoWithVeto},
},
},
output: []sdk.Msg{
&govtypes.MsgVote{
ProposalId: 1,
Voter: addr1.String(),
Option: govtypes.OptionNoWithVeto,
},
},
},
}
encodingConfig := MakeEncodingConfig(t)
for name, tc := range cases {

View File

@ -364,9 +364,9 @@ func TestBurnCoinMessageHandlerIntegration(t *testing.T) {
for name, spec := range specs {
t.Run(name, func(t *testing.T) {
ctx, _ = parentCtx.CacheContext()
k.wasmVM = &wasmtesting.MockWasmer{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) (*wasmvmtypes.Response, uint64, error) {
return &wasmvmtypes.Response{Messages: []wasmvmtypes.CosmosMsg{
{Bank: &wasmvmtypes.BankMsg{Burn: &spec.msg}},
k.wasmVM = &wasmtesting.MockWasmer{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.Response, uint64, error) {
return &wasmvmtypes.Response{Messages: []wasmvmtypes.SubMsg{
{Msg: wasmvmtypes.CosmosMsg{Bank: &wasmvmtypes.BankMsg{Burn: &spec.msg}}, ReplyOn: wasmvmtypes.ReplyNever},
},
}, 0, nil
}}

View File

@ -47,8 +47,7 @@ type WasmVMResponseHandler interface {
ctx sdk.Context,
contractAddr sdk.AccAddress,
ibcPort string,
submessages []wasmvmtypes.SubMsg,
messages []wasmvmtypes.CosmosMsg,
messages []wasmvmtypes.SubMsg,
origRspData []byte,
) ([]byte, error)
}
@ -259,7 +258,7 @@ func (k Keeper) instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.A
// instantiate wasm contract
gas := k.runtimeGasForContract(ctx)
res, gasUsed, err := k.wasmVM.Instantiate(codeInfo.CodeHash, env, info, initMsg, prefixStore, cosmwasmAPI, querier, k.gasMeter(ctx), gas)
res, gasUsed, err := k.wasmVM.Instantiate(codeInfo.CodeHash, env, info, initMsg, prefixStore, cosmwasmAPI, querier, k.gasMeter(ctx), gas, costJsonDeserialization)
k.consumeRuntimeGas(ctx, gasUsed)
if err != nil {
return contractAddress, nil, sdkerrors.Wrap(types.ErrInstantiateFailed, err.Error())
@ -290,7 +289,7 @@ func (k Keeper) instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.A
k.storeContractInfo(ctx, contractAddress, &contractInfo)
// dispatch submessages then messages
data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res.Submessages, res.Messages, res.Attributes, res.Data)
data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res.Messages, res.Attributes, res.Data, res.Events)
if err != nil {
return nil, nil, sdkerrors.Wrap(err, "dispatch")
}
@ -322,14 +321,14 @@ func (k Keeper) execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller
// prepare querier
querier := k.newQueryHandler(ctx, contractAddress)
gas := k.runtimeGasForContract(ctx)
res, gasUsed, execErr := k.wasmVM.Execute(codeInfo.CodeHash, env, info, msg, prefixStore, cosmwasmAPI, querier, k.gasMeter(ctx), gas)
res, gasUsed, execErr := k.wasmVM.Execute(codeInfo.CodeHash, env, info, msg, prefixStore, cosmwasmAPI, querier, k.gasMeter(ctx), gas, costJsonDeserialization)
k.consumeRuntimeGas(ctx, gasUsed)
if execErr != nil {
return nil, sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error())
}
// dispatch submessages then messages
data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res.Submessages, res.Messages, res.Attributes, res.Data)
data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res.Messages, res.Attributes, res.Data, res.Events)
if err != nil {
return nil, sdkerrors.Wrap(err, "dispatch")
}
@ -378,7 +377,7 @@ func (k Keeper) migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller
prefixStoreKey := types.GetContractStorePrefix(contractAddress)
prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), prefixStoreKey)
gas := k.runtimeGasForContract(ctx)
res, gasUsed, err := k.wasmVM.Migrate(newCodeInfo.CodeHash, env, msg, &prefixStore, cosmwasmAPI, &querier, k.gasMeter(ctx), gas)
res, gasUsed, err := k.wasmVM.Migrate(newCodeInfo.CodeHash, env, msg, &prefixStore, cosmwasmAPI, &querier, k.gasMeter(ctx), gas, costJsonDeserialization)
k.consumeRuntimeGas(ctx, gasUsed)
if err != nil {
return nil, sdkerrors.Wrap(types.ErrMigrationFailed, err.Error())
@ -393,7 +392,7 @@ func (k Keeper) migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller
k.storeContractInfo(ctx, contractAddress, contractInfo)
// dispatch submessages then messages
data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res.Submessages, res.Messages, res.Attributes, res.Data)
data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res.Messages, res.Attributes, res.Data, res.Events)
if err != nil {
return nil, sdkerrors.Wrap(err, "dispatch")
}
@ -418,14 +417,14 @@ func (k Keeper) Sudo(ctx sdk.Context, contractAddress sdk.AccAddress, msg []byte
// prepare querier
querier := k.newQueryHandler(ctx, contractAddress)
gas := k.runtimeGasForContract(ctx)
res, gasUsed, execErr := k.wasmVM.Sudo(codeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, k.gasMeter(ctx), gas)
res, gasUsed, execErr := k.wasmVM.Sudo(codeInfo.CodeHash, env, msg, prefixStore, cosmwasmAPI, querier, k.gasMeter(ctx), gas, costJsonDeserialization)
k.consumeRuntimeGas(ctx, gasUsed)
if execErr != nil {
return nil, sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error())
}
// dispatch submessages then messages
data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res.Submessages, res.Messages, res.Attributes, res.Data)
data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res.Messages, res.Attributes, res.Data, res.Events)
if err != nil {
return nil, sdkerrors.Wrap(err, "dispatch")
}
@ -451,14 +450,14 @@ func (k Keeper) reply(ctx sdk.Context, contractAddress sdk.AccAddress, reply was
Plugins: k.wasmVMQueryHandler,
}
gas := k.runtimeGasForContract(ctx)
res, gasUsed, execErr := k.wasmVM.Reply(codeInfo.CodeHash, env, reply, prefixStore, cosmwasmAPI, querier, k.gasMeter(ctx), gas)
res, gasUsed, execErr := k.wasmVM.Reply(codeInfo.CodeHash, env, reply, prefixStore, cosmwasmAPI, querier, k.gasMeter(ctx), gas, costJsonDeserialization)
k.consumeRuntimeGas(ctx, gasUsed)
if execErr != nil {
return nil, sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error())
}
// dispatch submessages then messages
data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res.Submessages, res.Messages, res.Attributes, res.Data)
data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res.Messages, res.Attributes, res.Data, res.Events)
if err != nil {
return nil, sdkerrors.Wrap(err, "dispatch")
}
@ -556,7 +555,7 @@ func (k Keeper) QuerySmart(ctx sdk.Context, contractAddr sdk.AccAddress, req []b
querier := k.newQueryHandler(ctx, contractAddr)
env := types.NewEnv(ctx, contractAddr)
queryResult, gasUsed, qErr := k.wasmVM.Query(codeInfo.CodeHash, env, req, prefixStore, cosmwasmAPI, querier, k.gasMeter(ctx), k.runtimeGasForContract(ctx))
queryResult, gasUsed, qErr := k.wasmVM.Query(codeInfo.CodeHash, env, req, prefixStore, cosmwasmAPI, querier, k.gasMeter(ctx), k.runtimeGasForContract(ctx), costJsonDeserialization)
k.consumeRuntimeGas(ctx, gasUsed)
if qErr != nil {
return nil, sdkerrors.Wrap(types.ErrQueryFailed, qErr.Error())
@ -763,17 +762,21 @@ func (k *Keeper) handleContractResponse(
ctx sdk.Context,
contractAddr sdk.AccAddress,
ibcPort string,
subMsg []wasmvmtypes.SubMsg,
msgs []wasmvmtypes.CosmosMsg,
msgs []wasmvmtypes.SubMsg,
attrs []wasmvmtypes.EventAttribute,
data []byte,
evts wasmvmtypes.Events,
) ([]byte, error) {
attributeGasCost := k.gasRegister.EventCosts(attrs)
attributeGasCost := k.gasRegister.EventCosts(attrs, evts)
ctx.GasMeter().ConsumeGas(attributeGasCost, "Custom contract event attributes")
// emit all events from this contract itself
events := types.ParseEvents(attrs, contractAddr)
ctx.EventManager().EmitEvents(events)
return k.wasmVMResponseHandler.Handle(ctx, contractAddr, ibcPort, subMsg, msgs, data)
if len(attrs) != 0 || !hasWasmModuleEvent(ctx, contractAddr) {
ctx.EventManager().EmitEvents(newWasmModuleEvent(attrs, contractAddr))
}
if len(evts) > 0 {
ctx.EventManager().EmitEvents(newCustomEvents(evts, contractAddr))
}
return k.wasmVMResponseHandler.Handle(ctx, contractAddr, ibcPort, msgs, data)
}
func (k Keeper) runtimeGasForContract(ctx sdk.Context) uint64 {
@ -952,7 +955,6 @@ func (c BankCoinTransferrer) TransferCoins(ctx sdk.Context, fromAddr sdk.AccAddr
}
type msgDispatcher interface {
DispatchMessages(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.CosmosMsg) error
DispatchSubmessages(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.SubMsg) ([]byte, error)
}
@ -968,21 +970,13 @@ func NewDefaultWasmVMContractResponseHandler(md msgDispatcher) *DefaultWasmVMCon
}
// Handle processes the data returned by a contract invocation.
func (h DefaultWasmVMContractResponseHandler) Handle(
ctx sdk.Context,
contractAddr sdk.AccAddress,
ibcPort string,
submessages []wasmvmtypes.SubMsg,
messages []wasmvmtypes.CosmosMsg,
origRspData []byte,
) ([]byte, error) {
func (h DefaultWasmVMContractResponseHandler) Handle(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, messages []wasmvmtypes.SubMsg, origRspData []byte) ([]byte, error) {
result := origRspData
switch rsp, err := h.md.DispatchSubmessages(ctx, contractAddr, ibcPort, submessages); {
switch rsp, err := h.md.DispatchSubmessages(ctx, contractAddr, ibcPort, messages); {
case err != nil:
return nil, sdkerrors.Wrap(err, "submessages")
case rsp != nil:
result = rsp
}
// then dispatch all the normal messages
return result, sdkerrors.Wrap(h.md.DispatchMessages(ctx, contractAddr, ibcPort, messages), "messages")
return result, nil
}

View File

@ -284,7 +284,7 @@ func TestInstantiate(t *testing.T) {
gasAfter := ctx.GasMeter().GasConsumed()
if types.EnableGasVerification {
require.Equal(t, uint64(0x12324), gasAfter-gasBefore)
require.Equal(t, uint64(0x12361), gasAfter-gasBefore)
}
// ensure it is stored properly
@ -443,7 +443,7 @@ func TestInstantiateWithContractDataResponse(t *testing.T) {
ctx, keepers := CreateTestInput(t, false, SupportedFeatures)
wasmerMock := &wasmtesting.MockWasmer{
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) (*wasmvmtypes.Response, uint64, 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.Response, uint64, error) {
return &wasmvmtypes.Response{Data: []byte("my-response-data")}, 0, nil
},
AnalyzeCodeFn: wasmtesting.WithoutIBCAnalyzeFn,
@ -517,7 +517,7 @@ func TestExecute(t *testing.T) {
// make sure gas is properly deducted from ctx
gasAfter := ctx.GasMeter().GasConsumed()
if types.EnableGasVerification {
require.Equal(t, uint64(0x12939), gasAfter-gasBefore)
require.Equal(t, uint64(0x12afd), gasAfter-gasBefore)
}
// ensure bob now exists and got both payments released
bobAcct = accKeeper.GetAccount(ctx, bob)
@ -1098,7 +1098,7 @@ func TestIterateContractsByCode(t *testing.T) {
func TestIterateContractsByCodeWithMigration(t *testing.T) {
// mock migration so that it does not fail when migrate example1 to example2.codeID
mockWasmVM := wasmtesting.MockWasmer{MigrateFn: func(codeID wasmvm.Checksum, env wasmvmtypes.Env, migrateMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.Response, uint64, error) {
mockWasmVM := wasmtesting.MockWasmer{MigrateFn: func(codeID wasmvm.Checksum, env wasmvmtypes.Env, migrateMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) {
return &wasmvmtypes.Response{}, 1, nil
}}
wasmtesting.MakeInstantiable(&mockWasmVM)
@ -1402,10 +1402,10 @@ func TestPinnedContractLoops(t *testing.T) {
require.NoError(t, k.pinCode(ctx, example.CodeID))
var loops int
anyMsg := []byte(`{}`)
mock.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) (*wasmvmtypes.Response, uint64, error) {
mock.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.Response, uint64, error) {
loops++
return &wasmvmtypes.Response{
Submessages: []wasmvmtypes.SubMsg{
Messages: []wasmvmtypes.SubMsg{
{
ID: 1,
ReplyOn: wasmvmtypes.ReplyError,
@ -1431,10 +1431,6 @@ func TestPinnedContractLoops(t *testing.T) {
}
func TestNewDefaultWasmVMContractResponseHandler(t *testing.T) {
noopDMsgs := func(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.CosmosMsg) error {
return nil
}
specs := map[string]struct {
srcData []byte
setup func(m *wasmtesting.MockMsgDispatcher)
@ -1447,7 +1443,6 @@ func TestNewDefaultWasmVMContractResponseHandler(t *testing.T) {
m.DispatchSubmessagesFn = func(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.SubMsg) ([]byte, error) {
return []byte("mySubMsgData"), nil
}
m.DispatchMessagesFn = noopDMsgs
},
expErr: false,
expData: []byte("mySubMsgData"),
@ -1458,7 +1453,6 @@ func TestNewDefaultWasmVMContractResponseHandler(t *testing.T) {
m.DispatchSubmessagesFn = func(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.SubMsg) ([]byte, error) {
return []byte(""), nil
}
m.DispatchMessagesFn = noopDMsgs
},
expErr: false,
expData: []byte(""),
@ -1469,7 +1463,6 @@ func TestNewDefaultWasmVMContractResponseHandler(t *testing.T) {
m.DispatchSubmessagesFn = func(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.SubMsg) ([]byte, error) {
return nil, nil
}
m.DispatchMessagesFn = noopDMsgs
},
expErr: false,
expData: []byte("otherData"),
@ -1482,30 +1475,18 @@ func TestNewDefaultWasmVMContractResponseHandler(t *testing.T) {
},
expErr: true,
},
"message error aborts process": {
setup: func(m *wasmtesting.MockMsgDispatcher) {
m.DispatchSubmessagesFn = func(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.SubMsg) ([]byte, error) {
return []byte("mySubMsgData"), nil
}
m.DispatchMessagesFn = func(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.CosmosMsg) error {
return errors.New("test - ignore")
}
},
expErr: true,
},
}
for name, spec := range specs {
t.Run(name, func(t *testing.T) {
var (
subMsgs []wasmvmtypes.SubMsg
msgs []wasmvmtypes.CosmosMsg
msgs []wasmvmtypes.SubMsg
)
var mock wasmtesting.MockMsgDispatcher
spec.setup(&mock)
d := NewDefaultWasmVMContractResponseHandler(&mock)
// when
gotData, gotErr := d.Handle(sdk.Context{}, RandomAccountAddress(t), "ibc-port", subMsgs, msgs, spec.srcData)
gotData, gotErr := d.Handle(sdk.Context{}, RandomAccountAddress(t), "ibc-port", msgs, spec.srcData)
if spec.expErr {
require.Error(t, gotErr)
return

View File

@ -76,12 +76,14 @@ func (d MessageDispatcher) DispatchSubmessages(ctx sdk.Context, contractAddr sdk
var rsp []byte
for _, msg := range msgs {
switch msg.ReplyOn {
case wasmvmtypes.ReplySuccess, wasmvmtypes.ReplyError, wasmvmtypes.ReplyAlways:
case wasmvmtypes.ReplySuccess, wasmvmtypes.ReplyError, wasmvmtypes.ReplyAlways, wasmvmtypes.ReplyNever:
default:
return nil, sdkerrors.Wrap(types.ErrInvalid, "replyOn value")
}
// first, we build a sub-context which we can use inside the submessages
subCtx, commit := ctx.CacheContext()
em := sdk.NewEventManager()
subCtx = subCtx.WithEventManager(em)
// check how much gas left locally, optionally wrap the gas meter
gasRemaining := ctx.GasMeter().Limit() - ctx.GasMeter().GasConsumed()
@ -99,15 +101,15 @@ func (d MessageDispatcher) DispatchSubmessages(ctx sdk.Context, contractAddr sdk
// if it succeeds, commit state changes from submessage, and pass on events to Event Manager
if err == nil {
commit()
ctx.EventManager().EmitEvents(em.Events())
ctx.EventManager().EmitEvents(events)
}
// on failure, revert state from sandbox, and ignore events (just skip doing the above)
} // on failure, revert state from sandbox, and ignore events (just skip doing the above)
// we only callback if requested. Short-circuit here the two cases we don't want to
if msg.ReplyOn == wasmvmtypes.ReplySuccess && err != nil {
// we only callback if requested. Short-circuit here the cases we don't want to
if (msg.ReplyOn == wasmvmtypes.ReplySuccess || msg.ReplyOn == wasmvmtypes.ReplyNever) && err != nil {
return nil, err
}
if msg.ReplyOn == wasmvmtypes.ReplyError && err == nil {
if msg.ReplyOn == wasmvmtypes.ReplyNever || (msg.ReplyOn == wasmvmtypes.ReplyError && err == nil) {
continue
}

View File

@ -101,6 +101,39 @@ func TestDispatchSubmessages(t *testing.T) {
Attributes: []abci.EventAttribute{{Key: []byte("foo"), Value: []byte("bar")}},
}},
},
"with context events - released on commit": {
msgs: []wasmvmtypes.SubMsg{{
ReplyOn: wasmvmtypes.ReplyNever,
}},
replyer: &mockReplyer{},
msgHandler: &wasmtesting.MockMessageHandler{
DispatchMsgFn: func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) {
myEvents := []sdk.Event{{Type: "myEvent", Attributes: []abci.EventAttribute{{Key: []byte("foo"), Value: []byte("bar")}}}}
ctx.EventManager().EmitEvents(myEvents)
return nil, nil, nil
},
},
expCommits: []bool{true},
expEvents: []sdk.Event{{
Type: "myEvent",
Attributes: []abci.EventAttribute{{Key: []byte("foo"), Value: []byte("bar")}},
}},
},
"with context events - discarded on failure": {
msgs: []wasmvmtypes.SubMsg{{
ReplyOn: wasmvmtypes.ReplyNever,
}},
replyer: &mockReplyer{},
msgHandler: &wasmtesting.MockMessageHandler{
DispatchMsgFn: func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) {
myEvents := []sdk.Event{{Type: "myEvent", Attributes: []abci.EventAttribute{{Key: []byte("foo"), Value: []byte("bar")}}}}
ctx.EventManager().EmitEvents(myEvents)
return nil, nil, errors.New("testing")
},
},
expCommits: []bool{false},
expErr: true,
},
"reply returns error": {
msgs: []wasmvmtypes.SubMsg{{
ReplyOn: wasmvmtypes.ReplySuccess,
@ -151,7 +184,38 @@ func TestDispatchSubmessages(t *testing.T) {
},
expCommits: []bool{true},
},
"multiple msg - last reply": {
"never reply - with nil response": {
msgs: []wasmvmtypes.SubMsg{{ID: 1, ReplyOn: wasmvmtypes.ReplyNever}, {ID: 2, ReplyOn: wasmvmtypes.ReplyNever}},
replyer: &mockReplyer{},
msgHandler: &wasmtesting.MockMessageHandler{
DispatchMsgFn: func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) {
return nil, [][]byte{nil}, nil
},
},
expCommits: []bool{true, true},
},
"never reply - with any non nil response": {
msgs: []wasmvmtypes.SubMsg{{ID: 1, ReplyOn: wasmvmtypes.ReplyNever}, {ID: 2, ReplyOn: wasmvmtypes.ReplyNever}},
replyer: &mockReplyer{},
msgHandler: &wasmtesting.MockMessageHandler{
DispatchMsgFn: func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) {
return nil, [][]byte{{}}, nil
},
},
expCommits: []bool{true, true},
},
"never reply - with error": {
msgs: []wasmvmtypes.SubMsg{{ID: 1, ReplyOn: wasmvmtypes.ReplyNever}, {ID: 2, ReplyOn: wasmvmtypes.ReplyNever}},
replyer: &mockReplyer{},
msgHandler: &wasmtesting.MockMessageHandler{
DispatchMsgFn: func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) {
return nil, [][]byte{{}}, errors.New("testing")
},
},
expCommits: []bool{false, false},
expErr: true,
},
"multiple msg - last reply returned": {
msgs: []wasmvmtypes.SubMsg{{ID: 1, ReplyOn: wasmvmtypes.ReplyError}, {ID: 2, ReplyOn: wasmvmtypes.ReplyError}},
replyer: &mockReplyer{
replyFn: func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) ([]byte, error) {
@ -166,7 +230,7 @@ func TestDispatchSubmessages(t *testing.T) {
expData: []byte("myReplyData:2"),
expCommits: []bool{false, false},
},
"multiple msg - last non nil reply to overwrite responose": {
"multiple msg - last non nil reply returned": {
msgs: []wasmvmtypes.SubMsg{{ID: 1, ReplyOn: wasmvmtypes.ReplyError}, {ID: 2, ReplyOn: wasmvmtypes.ReplyError}},
replyer: &mockReplyer{
replyFn: func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) ([]byte, error) {
@ -202,19 +266,6 @@ func TestDispatchSubmessages(t *testing.T) {
expData: []byte{},
expCommits: []bool{false, false},
},
"empty replyOn rejected": {
msgs: []wasmvmtypes.SubMsg{{}},
replyer: noReplyCalled,
msgHandler: &wasmtesting.MockMessageHandler{},
expErr: true,
},
"invalid replyOn rejected": {
msgs: []wasmvmtypes.SubMsg{{ReplyOn: "invalid"}},
replyer: noReplyCalled,
msgHandler: &wasmtesting.MockMessageHandler{},
expCommits: []bool{false},
expErr: true,
},
}
for name, spec := range specs {
t.Run(name, func(t *testing.T) {
@ -227,6 +278,7 @@ func TestDispatchSubmessages(t *testing.T) {
gotData, gotErr := d.DispatchSubmessages(ctx, RandomAccountAddress(t), "any_port", spec.msgs)
if spec.expErr {
require.Error(t, gotErr)
assert.Empty(t, em.Events())
return
} else {
require.NoError(t, gotErr)

View File

@ -179,7 +179,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) ([]byte, uint64, error) {
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) {
spec.doInContract()
return nil, 0, nil
}}

View File

@ -57,12 +57,12 @@ func initRecurseContract(t *testing.T) (contract sdk.AccAddress, creator sdk.Acc
func TestGasCostOnQuery(t *testing.T) {
const (
GasNoWork uint64 = 44_163
GasNoWork uint64 = 44_240
// Note: about 100 SDK gas (10k wasmer gas) for each round of sha256
GasWork50 uint64 = 49_856 // this is a little shy of 50k gas - to keep an eye on the limit
GasWork50 uint64 = 49_901 // this is a little shy of 50k gas - to keep an eye on the limit
GasReturnUnhashed uint64 = 224
GasReturnHashed uint64 = 198
GasReturnUnhashed uint64 = 197
GasReturnHashed uint64 = 173
)
cases := map[string]struct {
@ -221,9 +221,9 @@ func TestLimitRecursiveQueryGas(t *testing.T) {
const (
// Note: about 100 SDK gas (10k wasmer gas) for each round of sha256
GasWork2k uint64 = 273_661 // = NewContractInstanceCosts + x // we have 6x gas used in cpu than in the instance
GasWork2k uint64 = 273_170 // = NewContractInstanceCosts + x // we have 6x gas used in cpu than in the instance
// This is overhead for calling into a sub-contract
GasReturnHashed uint64 = 203
GasReturnHashed uint64 = 177
)
cases := map[string]struct {

View File

@ -24,9 +24,9 @@ import (
// ReflectHandleMsg is used to encode handle messages
type ReflectHandleMsg struct {
Reflect *reflectPayload `json:"reflect_msg,omitempty"`
ReflectSubCall *reflectSubPayload `json:"reflect_sub_call,omitempty"`
Change *ownerPayload `json:"change_owner,omitempty"`
Reflect *reflectPayload `json:"reflect_msg,omitempty"`
ReflectSubMsg *reflectSubPayload `json:"reflect_sub_msg,omitempty"`
Change *ownerPayload `json:"change_owner,omitempty"`
}
type ownerPayload struct {
@ -43,10 +43,10 @@ type reflectSubPayload struct {
// ReflectQueryMsg is used to encode query messages
type ReflectQueryMsg struct {
Owner *struct{} `json:"owner,omitempty"`
Capitalized *Text `json:"capitalized,omitempty"`
Chain *ChainQuery `json:"chain,omitempty"`
SubCallResult *SubCall `json:"sub_call_result,omitempty"`
Owner *struct{} `json:"owner,omitempty"`
Capitalized *Text `json:"capitalized,omitempty"`
Chain *ChainQuery `json:"chain,omitempty"`
SubMsgResult *SubCall `json:"sub_msg_result,omitempty"`
}
type ChainQuery struct {
@ -139,7 +139,7 @@ func TestReflectContractSend(t *testing.T) {
Execute: &wasmvmtypes.ExecuteMsg{
ContractAddr: escrowAddr.String(),
Msg: approveMsg,
Send: []wasmvmtypes.Coin{{
Funds: []wasmvmtypes.Coin{{
Denom: "denom",
Amount: "14000",
}},

View File

@ -30,7 +30,7 @@ func (k Keeper) OnOpenChannel(
querier := k.newQueryHandler(ctx, contractAddr)
gas := k.runtimeGasForContract(ctx)
gasUsed, execErr := k.wasmVM.IBCChannelOpen(codeInfo.CodeHash, env, channel, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas)
gasUsed, execErr := k.wasmVM.IBCChannelOpen(codeInfo.CodeHash, env, channel, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, costJsonDeserialization)
k.consumeRuntimeGas(ctx, gasUsed)
if execErr != nil {
return sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error())
@ -61,7 +61,7 @@ func (k Keeper) OnConnectChannel(
querier := k.newQueryHandler(ctx, contractAddr)
gas := k.runtimeGasForContract(ctx)
res, gasUsed, execErr := k.wasmVM.IBCChannelConnect(codeInfo.CodeHash, env, channel, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas)
res, gasUsed, execErr := k.wasmVM.IBCChannelConnect(codeInfo.CodeHash, env, channel, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, costJsonDeserialization)
k.consumeRuntimeGas(ctx, gasUsed)
if execErr != nil {
return sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error())
@ -92,7 +92,7 @@ func (k Keeper) OnCloseChannel(
querier := k.newQueryHandler(ctx, contractAddr)
gas := k.runtimeGasForContract(ctx)
res, gasUsed, execErr := k.wasmVM.IBCChannelClose(codeInfo.CodeHash, params, channel, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas)
res, gasUsed, execErr := k.wasmVM.IBCChannelClose(codeInfo.CodeHash, params, channel, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, costJsonDeserialization)
k.consumeRuntimeGas(ctx, gasUsed)
if execErr != nil {
return sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error())
@ -122,13 +122,13 @@ func (k Keeper) OnRecvPacket(
querier := k.newQueryHandler(ctx, contractAddr)
gas := k.runtimeGasForContract(ctx)
res, gasUsed, execErr := k.wasmVM.IBCPacketReceive(codeInfo.CodeHash, env, packet, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas)
res, gasUsed, execErr := k.wasmVM.IBCPacketReceive(codeInfo.CodeHash, env, packet, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, costJsonDeserialization)
k.consumeRuntimeGas(ctx, gasUsed)
if execErr != nil {
return nil, sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error())
}
return k.handleContractResponse(ctx, contractAddr, contractInfo.IBCPortID, res.Submessages, res.Messages, res.Attributes, res.Acknowledgement)
// note submessage reply results can overwrite the `Acknowledgement` data
return k.handleContractResponse(ctx, contractAddr, contractInfo.IBCPortID, res.Messages, res.Attributes, res.Acknowledgement, nil)
}
// OnAckPacket calls the contract to handle the "acknowledgement" data which can contain success or failure of a packet
@ -141,7 +141,7 @@ func (k Keeper) OnRecvPacket(
func (k Keeper) OnAckPacket(
ctx sdk.Context,
contractAddr sdk.AccAddress,
acknowledgement wasmvmtypes.IBCAcknowledgement,
acknowledgement wasmvmtypes.IBCAcknowledgementWithPacket,
) error {
defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "ibc-ack-packet")
contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr)
@ -153,7 +153,7 @@ func (k Keeper) OnAckPacket(
querier := k.newQueryHandler(ctx, contractAddr)
gas := k.runtimeGasForContract(ctx)
res, gasUsed, execErr := k.wasmVM.IBCPacketAck(codeInfo.CodeHash, env, acknowledgement, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas)
res, gasUsed, execErr := k.wasmVM.IBCPacketAck(codeInfo.CodeHash, env, acknowledgement, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, costJsonDeserialization)
k.consumeRuntimeGas(ctx, gasUsed)
if execErr != nil {
return sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error())
@ -180,7 +180,7 @@ func (k Keeper) OnTimeoutPacket(
querier := k.newQueryHandler(ctx, contractAddr)
gas := k.runtimeGasForContract(ctx)
res, gasUsed, execErr := k.wasmVM.IBCPacketTimeout(codeInfo.CodeHash, env, packet, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas)
res, gasUsed, execErr := k.wasmVM.IBCPacketTimeout(codeInfo.CodeHash, env, packet, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas, costJsonDeserialization)
k.consumeRuntimeGas(ctx, gasUsed)
if execErr != nil {
return sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error())
@ -190,6 +190,6 @@ func (k Keeper) OnTimeoutPacket(
}
func (k Keeper) handleIBCBasicContractResponse(ctx sdk.Context, addr sdk.AccAddress, id string, res *wasmvmtypes.IBCBasicResponse) error {
_, err := k.handleContractResponse(ctx, addr, id, res.Submessages, res.Messages, res.Attributes, nil)
_, err := k.handleContractResponse(ctx, addr, id, res.Messages, res.Attributes, nil, nil)
return err
}

View File

@ -52,7 +52,7 @@ func TestOnOpenChannel(t *testing.T) {
for name, spec := range specs {
t.Run(name, func(t *testing.T) {
myChannel := wasmvmtypes.IBCChannel{Version: "my test channel"}
m.IBCChannelOpenFn = func(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannel, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (uint64, error) {
m.IBCChannelOpenFn = func(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannel, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (uint64, error) {
assert.Equal(t, myChannel, channel)
return spec.contractGas * DefaultGasMultiplier, spec.contractErr
}
@ -103,7 +103,7 @@ func TestOnConnectChannel(t *testing.T) {
contractAddr: example.Contract,
expContractGas: myContractGas,
contractResp: &wasmvmtypes.IBCBasicResponse{
Messages: []wasmvmtypes.CosmosMsg{{Bank: &wasmvmtypes.BankMsg{}}},
Messages: []wasmvmtypes.SubMsg{{ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{Bank: &wasmvmtypes.BankMsg{}}}},
Attributes: []wasmvmtypes.EventAttribute{{Key: "Foo", Value: "Bar"}},
},
contractErr: errors.New("test, ignore"),
@ -114,7 +114,7 @@ func TestOnConnectChannel(t *testing.T) {
contractAddr: example.Contract,
expContractGas: myContractGas,
contractResp: &wasmvmtypes.IBCBasicResponse{
Messages: []wasmvmtypes.CosmosMsg{{Bank: &wasmvmtypes.BankMsg{}}, {Custom: json.RawMessage(`{"foo":"bar"}`)}},
Messages: []wasmvmtypes.SubMsg{{ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{Bank: &wasmvmtypes.BankMsg{}}}, {ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{Custom: json.RawMessage(`{"foo":"bar"}`)}}},
},
},
"emit contract events on success": {
@ -129,7 +129,7 @@ func TestOnConnectChannel(t *testing.T) {
contractAddr: example.Contract,
expContractGas: myContractGas + 10,
contractResp: &wasmvmtypes.IBCBasicResponse{
Messages: []wasmvmtypes.CosmosMsg{{Bank: &wasmvmtypes.BankMsg{}}, {Custom: json.RawMessage(`{"foo":"bar"}`)}},
Messages: []wasmvmtypes.SubMsg{{ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{Bank: &wasmvmtypes.BankMsg{}}}, {ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{Custom: json.RawMessage(`{"foo":"bar"}`)}}},
Attributes: []wasmvmtypes.EventAttribute{{Key: "Foo", Value: "Bar"}},
},
overwriteMessenger: wasmtesting.NewErroringMessageHandler(),
@ -145,7 +145,7 @@ func TestOnConnectChannel(t *testing.T) {
for name, spec := range specs {
t.Run(name, func(t *testing.T) {
myChannel := wasmvmtypes.IBCChannel{Version: "my test channel"}
m.IBCChannelConnectFn = func(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannel, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
m.IBCChannelConnectFn = func(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannel, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
assert.Equal(t, channel, myChannel)
return spec.contractResp, myContractGas * DefaultGasMultiplier, spec.contractErr
}
@ -181,7 +181,12 @@ func TestOnConnectChannel(t *testing.T) {
const storageCosts = sdk.Gas(0xa9d)
assert.Equal(t, spec.expContractGas, ctx.GasMeter().GasConsumed()-before-storageCosts)
// verify msgs dispatched
assert.Equal(t, spec.contractResp.Messages, *capturedMsgs)
require.Len(t, *capturedMsgs, len(spec.contractResp.Messages))
for i, m := range spec.contractResp.Messages {
assert.Equal(t, (*capturedMsgs)[i], m.Msg)
}
// verify events
require.Len(t, events, 1)
assert.Len(t, events[0].Attributes, 1+spec.expContractEventAttrs)
})
}
@ -214,7 +219,7 @@ func TestOnCloseChannel(t *testing.T) {
contractAddr: example.Contract,
expContractGas: myContractGas,
contractResp: &wasmvmtypes.IBCBasicResponse{
Messages: []wasmvmtypes.CosmosMsg{{Bank: &wasmvmtypes.BankMsg{}}},
Messages: []wasmvmtypes.SubMsg{{ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{Bank: &wasmvmtypes.BankMsg{}}}},
Attributes: []wasmvmtypes.EventAttribute{{Key: "Foo", Value: "Bar"}},
},
contractErr: errors.New("test, ignore"),
@ -225,7 +230,7 @@ func TestOnCloseChannel(t *testing.T) {
contractAddr: example.Contract,
expContractGas: myContractGas,
contractResp: &wasmvmtypes.IBCBasicResponse{
Messages: []wasmvmtypes.CosmosMsg{{Bank: &wasmvmtypes.BankMsg{}}, {Custom: json.RawMessage(`{"foo":"bar"}`)}},
Messages: []wasmvmtypes.SubMsg{{ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{Bank: &wasmvmtypes.BankMsg{}}}, {ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{Custom: json.RawMessage(`{"foo":"bar"}`)}}},
},
},
"emit contract events on success": {
@ -240,7 +245,7 @@ func TestOnCloseChannel(t *testing.T) {
contractAddr: example.Contract,
expContractGas: myContractGas + 10,
contractResp: &wasmvmtypes.IBCBasicResponse{
Messages: []wasmvmtypes.CosmosMsg{{Bank: &wasmvmtypes.BankMsg{}}, {Custom: json.RawMessage(`{"foo":"bar"}`)}},
Messages: []wasmvmtypes.SubMsg{{ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{Bank: &wasmvmtypes.BankMsg{}}}, {ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{Custom: json.RawMessage(`{"foo":"bar"}`)}}},
Attributes: []wasmvmtypes.EventAttribute{{Key: "Foo", Value: "Bar"}},
},
overwriteMessenger: wasmtesting.NewErroringMessageHandler(),
@ -256,7 +261,7 @@ func TestOnCloseChannel(t *testing.T) {
for name, spec := range specs {
t.Run(name, func(t *testing.T) {
myChannel := wasmvmtypes.IBCChannel{Version: "my test channel"}
m.IBCChannelCloseFn = func(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannel, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
m.IBCChannelCloseFn = func(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannel, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
assert.Equal(t, channel, myChannel)
return spec.contractResp, myContractGas * DefaultGasMultiplier, spec.contractErr
}
@ -291,7 +296,10 @@ func TestOnCloseChannel(t *testing.T) {
const storageCosts = sdk.Gas(0xa9d)
assert.Equal(t, spec.expContractGas, ctx.GasMeter().GasConsumed()-before-storageCosts)
// verify msgs dispatched
assert.Equal(t, spec.contractResp.Messages, *capturedMsgs)
require.Len(t, *capturedMsgs, len(spec.contractResp.Messages))
for i, m := range spec.contractResp.Messages {
assert.Equal(t, (*capturedMsgs)[i], m.Msg)
}
require.Len(t, events, 1)
assert.Len(t, events[0].Attributes, 1+spec.expContractEventAttrs)
})
@ -311,7 +319,9 @@ func TestOnRecvPacket(t *testing.T) {
contractResp *wasmvmtypes.IBCReceiveResponse
contractErr error
overwriteMessenger *wasmtesting.MockMessageHandler
mockReplyFn 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)
expContractGas sdk.Gas
expAck []byte
expErr bool
expContractEventAttrs int
expNoEvents bool
@ -322,6 +332,7 @@ func TestOnRecvPacket(t *testing.T) {
contractResp: &wasmvmtypes.IBCReceiveResponse{
Acknowledgement: []byte("myAck"),
},
expAck: []byte("myAck"),
},
"can return empty ack": {
contractAddr: example.Contract,
@ -333,7 +344,7 @@ func TestOnRecvPacket(t *testing.T) {
expContractGas: myContractGas,
contractResp: &wasmvmtypes.IBCReceiveResponse{
Acknowledgement: []byte("myAck"),
Messages: []wasmvmtypes.CosmosMsg{{Bank: &wasmvmtypes.BankMsg{}}},
Messages: []wasmvmtypes.SubMsg{{ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{Bank: &wasmvmtypes.BankMsg{}}}},
Attributes: []wasmvmtypes.EventAttribute{{Key: "Foo", Value: "Bar"}},
},
contractErr: errors.New("test, ignore"),
@ -345,8 +356,9 @@ func TestOnRecvPacket(t *testing.T) {
expContractGas: myContractGas,
contractResp: &wasmvmtypes.IBCReceiveResponse{
Acknowledgement: []byte("myAck"),
Messages: []wasmvmtypes.CosmosMsg{{Bank: &wasmvmtypes.BankMsg{}}, {Custom: json.RawMessage(`{"foo":"bar"}`)}},
Messages: []wasmvmtypes.SubMsg{{ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{Bank: &wasmvmtypes.BankMsg{}}}, {ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{Custom: json.RawMessage(`{"foo":"bar"}`)}}},
},
expAck: []byte("myAck"),
},
"emit contract events on success": {
contractAddr: example.Contract,
@ -356,19 +368,32 @@ func TestOnRecvPacket(t *testing.T) {
Attributes: []wasmvmtypes.EventAttribute{{Key: "Foo", Value: "Bar"}},
},
expContractEventAttrs: 1,
expAck: []byte("myAck"),
},
"messenger errors returned, events stored": {
contractAddr: example.Contract,
expContractGas: myContractGas + 10,
contractResp: &wasmvmtypes.IBCReceiveResponse{
Acknowledgement: []byte("myAck"),
Messages: []wasmvmtypes.CosmosMsg{{Bank: &wasmvmtypes.BankMsg{}}, {Custom: json.RawMessage(`{"foo":"bar"}`)}},
Messages: []wasmvmtypes.SubMsg{{ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{Bank: &wasmvmtypes.BankMsg{}}}, {ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{Custom: json.RawMessage(`{"foo":"bar"}`)}}},
Attributes: []wasmvmtypes.EventAttribute{{Key: "Foo", Value: "Bar"}},
},
overwriteMessenger: wasmtesting.NewErroringMessageHandler(),
expErr: true,
expContractEventAttrs: 1,
},
"submessage reply can overwrite ack data": {
contractAddr: example.Contract,
expContractGas: myContractGas + 10 + DefaultInstanceCost + 3708,
contractResp: &wasmvmtypes.IBCReceiveResponse{
Acknowledgement: []byte("myAck"),
Messages: []wasmvmtypes.SubMsg{{ReplyOn: wasmvmtypes.ReplyAlways, Msg: wasmvmtypes.CosmosMsg{Bank: &wasmvmtypes.BankMsg{}}}},
},
mockReplyFn: 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) {
return &wasmvmtypes.Response{Data: []byte("myBetterAck")}, 0, nil
},
expAck: []byte("myBetterAck"),
},
"unknown contract address": {
contractAddr: RandomAccountAddress(t),
expErr: true,
@ -379,10 +404,16 @@ func TestOnRecvPacket(t *testing.T) {
t.Run(name, func(t *testing.T) {
myPacket := wasmvmtypes.IBCPacket{Data: []byte("my data")}
m.IBCPacketReceiveFn = func(codeID wasmvm.Checksum, env wasmvmtypes.Env, packet wasmvmtypes.IBCPacket, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.IBCReceiveResponse, uint64, error) {
m.IBCPacketReceiveFn = func(codeID wasmvm.Checksum, env wasmvmtypes.Env, packet wasmvmtypes.IBCPacket, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCReceiveResponse, uint64, error) {
assert.Equal(t, myPacket, packet)
return spec.contractResp, myContractGas * DefaultGasMultiplier, spec.contractErr
}
if spec.mockReplyFn != nil {
m.ReplyFn = spec.mockReplyFn
h, ok := keepers.WasmKeeper.wasmVMResponseHandler.(*DefaultWasmVMContractResponseHandler)
require.True(t, ok)
h.md = NewMessageDispatcher(messenger, keepers.WasmKeeper)
}
ctx, _ := parentCtx.CacheContext()
before := ctx.GasMeter().GasConsumed()
@ -411,13 +442,16 @@ func TestOnRecvPacket(t *testing.T) {
return
}
require.NoError(t, err)
require.Equal(t, spec.contractResp.Acknowledgement, gotAck)
require.Equal(t, spec.expAck, gotAck)
// verify gas consumed
const storageCosts = sdk.Gas(0xa9d)
assert.Equal(t, spec.expContractGas, ctx.GasMeter().GasConsumed()-before-storageCosts)
// verify msgs dispatched
assert.Equal(t, spec.contractResp.Messages, *capturedMsgs)
require.Len(t, *capturedMsgs, len(spec.contractResp.Messages))
for i, m := range spec.contractResp.Messages {
assert.Equal(t, (*capturedMsgs)[i], m.Msg)
}
require.Len(t, events, 1)
assert.Len(t, events[0].Attributes, 1+spec.expContractEventAttrs)
})
@ -451,7 +485,7 @@ func TestOnAckPacket(t *testing.T) {
contractAddr: example.Contract,
expContractGas: myContractGas,
contractResp: &wasmvmtypes.IBCBasicResponse{
Messages: []wasmvmtypes.CosmosMsg{{Bank: &wasmvmtypes.BankMsg{}}},
Messages: []wasmvmtypes.SubMsg{{ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{Bank: &wasmvmtypes.BankMsg{}}}},
Attributes: []wasmvmtypes.EventAttribute{{Key: "Foo", Value: "Bar"}},
},
contractErr: errors.New("test, ignore"),
@ -462,7 +496,7 @@ func TestOnAckPacket(t *testing.T) {
contractAddr: example.Contract,
expContractGas: myContractGas,
contractResp: &wasmvmtypes.IBCBasicResponse{
Messages: []wasmvmtypes.CosmosMsg{{Bank: &wasmvmtypes.BankMsg{}}, {Custom: json.RawMessage(`{"foo":"bar"}`)}},
Messages: []wasmvmtypes.SubMsg{{ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{Bank: &wasmvmtypes.BankMsg{}}}, {ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{Custom: json.RawMessage(`{"foo":"bar"}`)}}},
},
},
"emit contract events on success": {
@ -477,7 +511,7 @@ func TestOnAckPacket(t *testing.T) {
contractAddr: example.Contract,
expContractGas: myContractGas + 10,
contractResp: &wasmvmtypes.IBCBasicResponse{
Messages: []wasmvmtypes.CosmosMsg{{Bank: &wasmvmtypes.BankMsg{}}, {Custom: json.RawMessage(`{"foo":"bar"}`)}},
Messages: []wasmvmtypes.SubMsg{{ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{Bank: &wasmvmtypes.BankMsg{}}}, {ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{Custom: json.RawMessage(`{"foo":"bar"}`)}}},
Attributes: []wasmvmtypes.EventAttribute{{Key: "Foo", Value: "Bar"}},
},
overwriteMessenger: wasmtesting.NewErroringMessageHandler(),
@ -493,8 +527,8 @@ func TestOnAckPacket(t *testing.T) {
for name, spec := range specs {
t.Run(name, func(t *testing.T) {
myAck := wasmvmtypes.IBCAcknowledgement{Acknowledgement: []byte("myAck")}
m.IBCPacketAckFn = func(codeID wasmvm.Checksum, env wasmvmtypes.Env, ack wasmvmtypes.IBCAcknowledgement, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
myAck := wasmvmtypes.IBCAcknowledgementWithPacket{Acknowledgement: wasmvmtypes.IBCAcknowledgement{Data: []byte("myAck")}}
m.IBCPacketAckFn = func(codeID wasmvm.Checksum, env wasmvmtypes.Env, ack wasmvmtypes.IBCAcknowledgementWithPacket, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
assert.Equal(t, myAck, ack)
return spec.contractResp, myContractGas * DefaultGasMultiplier, spec.contractErr
}
@ -529,7 +563,11 @@ func TestOnAckPacket(t *testing.T) {
const storageCosts = sdk.Gas(0xa9d)
assert.Equal(t, spec.expContractGas, ctx.GasMeter().GasConsumed()-before-storageCosts)
// verify msgs dispatched
assert.Equal(t, spec.contractResp.Messages, *capturedMsgs)
require.Len(t, *capturedMsgs, len(spec.contractResp.Messages))
for i, m := range spec.contractResp.Messages {
assert.Equal(t, (*capturedMsgs)[i], m.Msg)
}
require.Len(t, events, 1)
assert.Len(t, events[0].Attributes, 1+spec.expContractEventAttrs)
})
@ -563,7 +601,7 @@ func TestOnTimeoutPacket(t *testing.T) {
contractAddr: example.Contract,
expContractGas: myContractGas,
contractResp: &wasmvmtypes.IBCBasicResponse{
Messages: []wasmvmtypes.CosmosMsg{{Bank: &wasmvmtypes.BankMsg{}}},
Messages: []wasmvmtypes.SubMsg{{ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{Bank: &wasmvmtypes.BankMsg{}}}},
Attributes: []wasmvmtypes.EventAttribute{{Key: "Foo", Value: "Bar"}},
},
contractErr: errors.New("test, ignore"),
@ -574,7 +612,7 @@ func TestOnTimeoutPacket(t *testing.T) {
contractAddr: example.Contract,
expContractGas: myContractGas,
contractResp: &wasmvmtypes.IBCBasicResponse{
Messages: []wasmvmtypes.CosmosMsg{{Bank: &wasmvmtypes.BankMsg{}}, {Custom: json.RawMessage(`{"foo":"bar"}`)}},
Messages: []wasmvmtypes.SubMsg{{ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{Bank: &wasmvmtypes.BankMsg{}}}, {ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{Custom: json.RawMessage(`{"foo":"bar"}`)}}},
},
},
"emit contract events on success": {
@ -589,7 +627,7 @@ func TestOnTimeoutPacket(t *testing.T) {
contractAddr: example.Contract,
expContractGas: myContractGas + 10,
contractResp: &wasmvmtypes.IBCBasicResponse{
Messages: []wasmvmtypes.CosmosMsg{{Bank: &wasmvmtypes.BankMsg{}}, {Custom: json.RawMessage(`{"foo":"bar"}`)}},
Messages: []wasmvmtypes.SubMsg{{ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{Bank: &wasmvmtypes.BankMsg{}}}, {ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{Custom: json.RawMessage(`{"foo":"bar"}`)}}},
Attributes: []wasmvmtypes.EventAttribute{{Key: "Foo", Value: "Bar"}},
},
overwriteMessenger: wasmtesting.NewErroringMessageHandler(),
@ -605,7 +643,7 @@ func TestOnTimeoutPacket(t *testing.T) {
for name, spec := range specs {
t.Run(name, func(t *testing.T) {
myPacket := wasmvmtypes.IBCPacket{Data: []byte("my test packet")}
m.IBCPacketTimeoutFn = func(codeID wasmvm.Checksum, env wasmvmtypes.Env, packet wasmvmtypes.IBCPacket, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
m.IBCPacketTimeoutFn = func(codeID wasmvm.Checksum, env wasmvmtypes.Env, packet wasmvmtypes.IBCPacket, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
assert.Equal(t, myPacket, packet)
return spec.contractResp, myContractGas * DefaultGasMultiplier, spec.contractErr
}
@ -640,7 +678,10 @@ func TestOnTimeoutPacket(t *testing.T) {
const storageCosts = sdk.Gas(0xa9d)
assert.Equal(t, spec.expContractGas, ctx.GasMeter().GasConsumed()-before-storageCosts)
// verify msgs dispatched
assert.Equal(t, spec.contractResp.Messages, *capturedMsgs)
require.Len(t, *capturedMsgs, len(spec.contractResp.Messages))
for i, m := range spec.contractResp.Messages {
assert.Equal(t, (*capturedMsgs)[i], m.Msg)
}
require.Len(t, events, 1)
assert.Len(t, events[0].Attributes, 1+spec.expContractEventAttrs)
})

View File

@ -57,7 +57,7 @@ func TestDispatchSubMsgSuccessCase(t *testing.T) {
},
}
reflectSend := ReflectHandleMsg{
ReflectSubCall: &reflectSubPayload{
ReflectSubMsg: &reflectSubPayload{
Msgs: []wasmvmtypes.SubMsg{{
ID: 7,
Msg: msg,
@ -78,7 +78,7 @@ func TestDispatchSubMsgSuccessCase(t *testing.T) {
// query the reflect state to ensure the result was stored
query := ReflectQueryMsg{
SubCallResult: &SubCall{ID: 7},
SubMsgResult: &SubCall{ID: 7},
}
queryBz, err := json.Marshal(query)
require.NoError(t, err)
@ -318,7 +318,7 @@ func TestDispatchSubMsgErrorHandling(t *testing.T) {
msg := tc.msg(contractAddr.String(), empty.String())
reflectSend := ReflectHandleMsg{
ReflectSubCall: &reflectSubPayload{
ReflectSubMsg: &reflectSubPayload{
Msgs: []wasmvmtypes.SubMsg{{
ID: tc.submsgID,
Msg: msg,
@ -349,7 +349,7 @@ func TestDispatchSubMsgErrorHandling(t *testing.T) {
// query the reply
query := ReflectQueryMsg{
SubCallResult: &SubCall{ID: tc.submsgID},
SubMsgResult: &SubCall{ID: tc.submsgID},
}
queryBz, err := json.Marshal(query)
require.NoError(t, err)
@ -421,7 +421,7 @@ func TestDispatchSubMsgEncodeToNoSdkMsg(t *testing.T) {
},
}
reflectSend := ReflectHandleMsg{
ReflectSubCall: &reflectSubPayload{
ReflectSubMsg: &reflectSubPayload{
Msgs: []wasmvmtypes.SubMsg{{
ID: 7,
Msg: msg,
@ -436,7 +436,7 @@ func TestDispatchSubMsgEncodeToNoSdkMsg(t *testing.T) {
// query the reflect state to ensure the result was stored
query := ReflectQueryMsg{
SubCallResult: &SubCall{ID: 7},
SubMsgResult: &SubCall{ID: 7},
}
queryBz, err := json.Marshal(query)
require.NoError(t, err)
@ -547,7 +547,7 @@ func TestDispatchSubMsgConditionalReplyOn(t *testing.T) {
}
reflectSend := ReflectHandleMsg{
ReflectSubCall: &reflectSubPayload{
ReflectSubMsg: &reflectSubPayload{
Msgs: []wasmvmtypes.SubMsg{subMsg},
},
}
@ -563,7 +563,7 @@ func TestDispatchSubMsgConditionalReplyOn(t *testing.T) {
// query the reflect state to check if the result was stored
query := ReflectQueryMsg{
SubCallResult: &SubCall{ID: id},
SubMsgResult: &SubCall{ID: id},
}
queryBz, err := json.Marshal(query)
require.NoError(t, err)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -44,7 +44,7 @@ func (m MockGasRegister) ReplyCosts(pinned bool, reply wasmvmtypes.Reply) sdk.Ga
return m.ReplyCostFn(pinned, reply)
}
func (m MockGasRegister) EventCosts(evts []wasmvmtypes.EventAttribute) sdk.Gas {
func (m MockGasRegister) EventCosts(evts []wasmvmtypes.EventAttribute, events wasmvmtypes.Events) sdk.Gas {
if m.EventCostsFn == nil {
panic("not expected to be called")
}

View File

@ -12,6 +12,9 @@ type MockMessageHandler struct {
}
func (m *MockMessageHandler) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) {
if m.DispatchMsgFn == nil {
panic("not expected to be called")
}
return m.DispatchMsgFn(ctx, contractAddr, contractIBCPortID, msg)
}

View File

@ -17,65 +17,65 @@ var _ types.WasmerEngine = &MockWasmer{}
type MockWasmer struct {
CreateFn func(codeID wasmvm.WasmCode) (wasmvm.Checksum, 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) (*wasmvmtypes.Response, 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) (*wasmvmtypes.Response, uint64, error)
QueryFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, queryMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) ([]byte, uint64, error)
MigrateFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, migrateMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.Response, uint64, error)
SudoFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, sudoMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.Response, uint64, error)
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) (*wasmvmtypes.Response, uint64, 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.Response, 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.Response, uint64, error)
QueryFn func(codeID 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)
MigrateFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, migrateMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error)
SudoFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, sudoMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error)
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, channel wasmvmtypes.IBCChannel, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (uint64, error)
IBCChannelConnectFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannel, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.IBCBasicResponse, uint64, error)
IBCChannelCloseFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannel, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.IBCBasicResponse, uint64, error)
IBCPacketReceiveFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, packet wasmvmtypes.IBCPacket, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.IBCReceiveResponse, uint64, error)
IBCPacketAckFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, ack wasmvmtypes.IBCAcknowledgement, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.IBCBasicResponse, uint64, error)
IBCPacketTimeoutFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, packet wasmvmtypes.IBCPacket, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.IBCBasicResponse, uint64, error)
IBCChannelOpenFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannel, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (uint64, error)
IBCChannelConnectFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannel, 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, channel wasmvmtypes.IBCChannel, 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, packet wasmvmtypes.IBCPacket, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCReceiveResponse, uint64, error)
IBCPacketAckFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, ack wasmvmtypes.IBCAcknowledgementWithPacket, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error)
IBCPacketTimeoutFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, packet wasmvmtypes.IBCPacket, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error)
PinFn func(checksum wasmvm.Checksum) error
UnpinFn func(checksum wasmvm.Checksum) error
GetMetricsFn func() (*wasmvmtypes.Metrics, error)
}
func (m *MockWasmer) IBCChannelOpen(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannel, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (uint64, error) {
func (m *MockWasmer) IBCChannelOpen(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannel, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (uint64, error) {
if m.IBCChannelOpenFn == nil {
panic("not supposed to be called!")
}
return m.IBCChannelOpenFn(codeID, env, channel, store, goapi, querier, gasMeter, gasLimit)
return m.IBCChannelOpenFn(codeID, env, channel, store, goapi, querier, gasMeter, gasLimit, deserCost)
}
func (m *MockWasmer) IBCChannelConnect(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannel, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
func (m *MockWasmer) IBCChannelConnect(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannel, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
if m.IBCChannelConnectFn == nil {
panic("not supposed to be called!")
}
return m.IBCChannelConnectFn(codeID, env, channel, store, goapi, querier, gasMeter, gasLimit)
return m.IBCChannelConnectFn(codeID, env, channel, store, goapi, querier, gasMeter, gasLimit, deserCost)
}
func (m *MockWasmer) IBCChannelClose(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannel, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
func (m *MockWasmer) IBCChannelClose(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannel, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
if m.IBCChannelCloseFn == nil {
panic("not supposed to be called!")
}
return m.IBCChannelCloseFn(codeID, env, channel, store, goapi, querier, gasMeter, gasLimit)
return m.IBCChannelCloseFn(codeID, env, channel, store, goapi, querier, gasMeter, gasLimit, deserCost)
}
func (m *MockWasmer) IBCPacketReceive(codeID wasmvm.Checksum, env wasmvmtypes.Env, packet wasmvmtypes.IBCPacket, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.IBCReceiveResponse, uint64, error) {
func (m *MockWasmer) IBCPacketReceive(codeID wasmvm.Checksum, env wasmvmtypes.Env, packet wasmvmtypes.IBCPacket, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCReceiveResponse, uint64, error) {
if m.IBCPacketReceiveFn == nil {
panic("not supposed to be called!")
}
return m.IBCPacketReceiveFn(codeID, env, packet, store, goapi, querier, gasMeter, gasLimit)
return m.IBCPacketReceiveFn(codeID, env, packet, store, goapi, querier, gasMeter, gasLimit, deserCost)
}
func (m *MockWasmer) IBCPacketAck(codeID wasmvm.Checksum, env wasmvmtypes.Env, ack wasmvmtypes.IBCAcknowledgement, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
func (m *MockWasmer) IBCPacketAck(codeID wasmvm.Checksum, env wasmvmtypes.Env, ack wasmvmtypes.IBCAcknowledgementWithPacket, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
if m.IBCPacketAckFn == nil {
panic("not supposed to be called!")
}
return m.IBCPacketAckFn(codeID, env, ack, store, goapi, querier, gasMeter, gasLimit)
return m.IBCPacketAckFn(codeID, env, ack, store, goapi, querier, gasMeter, gasLimit, deserCost)
}
func (m *MockWasmer) IBCPacketTimeout(codeID wasmvm.Checksum, env wasmvmtypes.Env, packet wasmvmtypes.IBCPacket, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
func (m *MockWasmer) IBCPacketTimeout(codeID wasmvm.Checksum, env wasmvmtypes.Env, packet wasmvmtypes.IBCPacket, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
if m.IBCPacketTimeoutFn == nil {
panic("not supposed to be called!")
}
return m.IBCPacketTimeoutFn(codeID, env, packet, store, goapi, querier, gasMeter, gasLimit)
return m.IBCPacketTimeoutFn(codeID, env, packet, store, goapi, querier, gasMeter, gasLimit, deserCost)
}
func (m *MockWasmer) Create(codeID wasmvm.WasmCode) (wasmvm.Checksum, error) {
@ -92,47 +92,47 @@ func (m *MockWasmer) AnalyzeCode(codeID wasmvm.Checksum) (*wasmvmtypes.AnalysisR
return m.AnalyzeCodeFn(codeID)
}
func (m *MockWasmer) Instantiate(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) (*wasmvmtypes.Response, uint64, error) {
func (m *MockWasmer) Instantiate(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.Response, uint64, error) {
if m.InstantiateFn == nil {
panic("not supposed to be called!")
}
return m.InstantiateFn(codeID, env, info, initMsg, store, goapi, querier, gasMeter, gasLimit)
return m.InstantiateFn(codeID, env, info, initMsg, store, goapi, querier, gasMeter, gasLimit, deserCost)
}
func (m *MockWasmer) Execute(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) (*wasmvmtypes.Response, uint64, error) {
func (m *MockWasmer) Execute(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.Response, uint64, error) {
if m.ExecuteFn == nil {
panic("not supposed to be called!")
}
return m.ExecuteFn(codeID, env, info, executeMsg, store, goapi, querier, gasMeter, gasLimit)
return m.ExecuteFn(codeID, env, info, executeMsg, store, goapi, querier, gasMeter, gasLimit, deserCost)
}
func (m *MockWasmer) Query(codeID wasmvm.Checksum, env wasmvmtypes.Env, queryMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) ([]byte, uint64, error) {
func (m *MockWasmer) Query(codeID 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) {
if m.QueryFn == nil {
panic("not supposed to be called!")
}
return m.QueryFn(codeID, env, queryMsg, store, goapi, querier, gasMeter, gasLimit)
return m.QueryFn(codeID, env, queryMsg, store, goapi, querier, gasMeter, gasLimit, deserCost)
}
func (m *MockWasmer) Migrate(codeID wasmvm.Checksum, env wasmvmtypes.Env, migrateMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.Response, uint64, error) {
func (m *MockWasmer) Migrate(codeID wasmvm.Checksum, env wasmvmtypes.Env, migrateMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) {
if m.MigrateFn == nil {
panic("not supposed to be called!")
}
return m.MigrateFn(codeID, env, migrateMsg, store, goapi, querier, gasMeter, gasLimit)
return m.MigrateFn(codeID, env, migrateMsg, store, goapi, querier, gasMeter, gasLimit, deserCost)
}
func (m *MockWasmer) Sudo(codeID wasmvm.Checksum, env wasmvmtypes.Env, sudoMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.Response, uint64, error) {
func (m *MockWasmer) Sudo(codeID wasmvm.Checksum, env wasmvmtypes.Env, sudoMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) {
if m.SudoFn == nil {
panic("not supposed to be called!")
}
return m.SudoFn(codeID, env, sudoMsg, store, goapi, querier, gasMeter, gasLimit)
return m.SudoFn(codeID, env, sudoMsg, store, goapi, querier, gasMeter, gasLimit, deserCost)
}
func (m *MockWasmer) Reply(codeID wasmvm.Checksum, env wasmvmtypes.Env, reply wasmvmtypes.Reply, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.Response, uint64, error) {
func (m *MockWasmer) Reply(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) {
if m.ReplyFn == nil {
panic("not supposed to be called!")
}
return m.ReplyFn(codeID, env, reply, store, goapi, querier, gasMeter, gasLimit)
return m.ReplyFn(codeID, env, reply, store, goapi, querier, gasMeter, gasLimit, deserCost)
}
func (m *MockWasmer) GetCode(codeID wasmvm.Checksum) (wasmvm.WasmCode, error) {
@ -180,15 +180,17 @@ func SelfCallingInstMockWasmer(executeCalled *bool) *MockWasmer {
anyCodeID := bytes.Repeat([]byte{0x1}, 32)
return anyCodeID, nil
},
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) (*wasmvmtypes.Response, uint64, 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.Response, uint64, error) {
return &wasmvmtypes.Response{
Messages: []wasmvmtypes.CosmosMsg{
{Wasm: &wasmvmtypes.WasmMsg{Execute: &wasmvmtypes.ExecuteMsg{ContractAddr: env.Contract.Address, Msg: []byte(`{}`)}}},
Messages: []wasmvmtypes.SubMsg{
{Msg: wasmvmtypes.CosmosMsg{
Wasm: &wasmvmtypes.WasmMsg{Execute: &wasmvmtypes.ExecuteMsg{ContractAddr: env.Contract.Address, Msg: []byte(`{}`)}},
}},
},
}, 1, nil
},
AnalyzeCodeFn: WithoutIBCAnalyzeFn,
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) (*wasmvmtypes.Response, 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.Response, uint64, error) {
*executeCalled = true
return &wasmvmtypes.Response{}, 1, nil
},
@ -207,6 +209,7 @@ type IBCContractCallbacks interface {
querier wasmvm.Querier,
gasMeter wasmvm.GasMeter,
gasLimit uint64,
deserCost wasmvmtypes.UFraction,
) (uint64, error)
IBCChannelConnect(
@ -218,6 +221,7 @@ type IBCContractCallbacks interface {
querier wasmvm.Querier,
gasMeter wasmvm.GasMeter,
gasLimit uint64,
deserCost wasmvmtypes.UFraction,
) (*wasmvmtypes.IBCBasicResponse, uint64, error)
IBCChannelClose(
@ -229,6 +233,7 @@ type IBCContractCallbacks interface {
querier wasmvm.Querier,
gasMeter wasmvm.GasMeter,
gasLimit uint64,
deserCost wasmvmtypes.UFraction,
) (*wasmvmtypes.IBCBasicResponse, uint64, error)
IBCPacketReceive(
@ -240,17 +245,19 @@ type IBCContractCallbacks interface {
querier wasmvm.Querier,
gasMeter wasmvm.GasMeter,
gasLimit uint64,
deserCost wasmvmtypes.UFraction,
) (*wasmvmtypes.IBCReceiveResponse, uint64, error)
IBCPacketAck(
codeID wasmvm.Checksum,
env wasmvmtypes.Env,
ack wasmvmtypes.IBCAcknowledgement,
ack wasmvmtypes.IBCAcknowledgementWithPacket,
store wasmvm.KVStore,
goapi wasmvm.GoAPI,
querier wasmvm.Querier,
gasMeter wasmvm.GasMeter,
gasLimit uint64,
deserCost wasmvmtypes.UFraction,
) (*wasmvmtypes.IBCBasicResponse, uint64, error)
IBCPacketTimeout(
@ -262,6 +269,7 @@ type IBCContractCallbacks interface {
querier wasmvm.Querier,
gasMeter wasmvm.GasMeter,
gasLimit uint64,
deserCost wasmvmtypes.UFraction,
) (*wasmvmtypes.IBCBasicResponse, uint64, error)
}
@ -276,6 +284,7 @@ type contractExecutable interface {
querier wasmvm.Querier,
gasMeter wasmvm.GasMeter,
gasLimit uint64,
deserCost wasmvmtypes.UFraction,
) (*wasmvmtypes.Response, uint64, error)
}
@ -320,7 +329,7 @@ func HashOnlyCreateFn(code wasmvm.WasmCode) (wasmvm.Checksum, error) {
return hash[:], nil
}
func NoOpInstantiateFn(wasmvm.Checksum, wasmvmtypes.Env, wasmvmtypes.MessageInfo, []byte, wasmvm.KVStore, wasmvm.GoAPI, wasmvm.Querier, wasmvm.GasMeter, uint64) (*wasmvmtypes.Response, uint64, error) {
func NoOpInstantiateFn(wasmvm.Checksum, wasmvmtypes.Env, wasmvmtypes.MessageInfo, []byte, wasmvm.KVStore, wasmvm.GoAPI, wasmvm.Querier, wasmvm.GasMeter, uint64, wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) {
return &wasmvmtypes.Response{}, 0, nil
}

View File

@ -6,17 +6,9 @@ import (
)
type MockMsgDispatcher struct {
DispatchMessagesFn func(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.CosmosMsg) error
DispatchSubmessagesFn func(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.SubMsg) ([]byte, error)
}
func (m MockMsgDispatcher) DispatchMessages(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.CosmosMsg) error {
if m.DispatchMessagesFn == nil {
panic("not expected to be called")
}
return m.DispatchMessagesFn(ctx, contractAddr, ibcPort, msgs)
}
func (m MockMsgDispatcher) DispatchSubmessages(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.SubMsg) ([]byte, error) {
if m.DispatchSubmessagesFn == nil {
panic("not expected to be called")

View File

@ -270,26 +270,30 @@ func TestHandleExecute(t *testing.T) {
// from https://github.com/CosmWasm/cosmwasm/blob/master/contracts/hackatom/src/contract.rs#L167
assertExecuteResponse(t, res.Data, []byte{0xf0, 0x0b, 0xaa})
// this should be standard x/wasm init event, plus 2 bank send event, plus a special event from the contract
require.Equal(t, 4, len(res.Events), prettyEvents(res.Events))
// this should be standard message event, plus x/wasm init event, plus 2 bank send event, plus a special event from the contract
require.Equal(t, 5, len(res.Events), prettyEvents(res.Events))
require.Equal(t, "transfer", res.Events[0].Type)
require.Len(t, res.Events[0].Attributes, 3)
assertAttribute(t, "recipient", contractBech32Addr, res.Events[0].Attributes[0])
assertAttribute(t, "sender", fred.String(), res.Events[0].Attributes[1])
assertAttribute(t, "amount", "5000denom", res.Events[0].Attributes[2])
// custom contract event
// custom contract event attribute
assert.Equal(t, "wasm", res.Events[1].Type)
assertAttribute(t, "contract_address", contractBech32Addr, res.Events[1].Attributes[0])
assertAttribute(t, "action", "release", res.Events[1].Attributes[1])
// custom contract event
assert.Equal(t, "wasm-hackatom", res.Events[2].Type)
assertAttribute(t, "contract_address", contractBech32Addr, res.Events[1].Attributes[0])
assertAttribute(t, "action", "release", res.Events[1].Attributes[1])
// second transfer (this without conflicting message)
assert.Equal(t, "transfer", res.Events[2].Type)
assertAttribute(t, "recipient", bob.String(), res.Events[2].Attributes[0])
assertAttribute(t, "sender", contractBech32Addr, res.Events[2].Attributes[1])
assertAttribute(t, "amount", "105000denom", res.Events[2].Attributes[2])
assert.Equal(t, "transfer", res.Events[3].Type)
assertAttribute(t, "recipient", bob.String(), res.Events[3].Attributes[0])
assertAttribute(t, "sender", contractBech32Addr, res.Events[3].Attributes[1])
assertAttribute(t, "amount", "105000denom", res.Events[3].Attributes[2])
// finally, standard x/wasm tag
assert.Equal(t, "message", res.Events[3].Type)
assertAttribute(t, "module", "wasm", res.Events[3].Attributes[0])
assert.Equal(t, "message", res.Events[4].Type)
assertAttribute(t, "module", "wasm", res.Events[4].Attributes[0])
// ensure bob now exists and got both payments released
bobAcct = data.acctKeeper.GetAccount(data.ctx, bob)

View File

@ -65,8 +65,7 @@ func TestPinPong(t *testing.T) {
connA.NextChannelVersion = ping
connB.NextChannelVersion = pong
channelA, channelB := coordinator.CreateChannel(chainA, chainB, connA, connB, sourcePortID, counterpartyPortID, channeltypes.UNORDERED)
var err error
channelA, _ := coordinator.CreateChannel(chainA, chainB, connA, connB, sourcePortID, counterpartyPortID, channeltypes.UNORDERED)
const startValue uint64 = 100
const rounds = 3
@ -80,43 +79,19 @@ func TestPinPong(t *testing.T) {
Msg: s.GetBytes(),
}
// send message to chainA
err = coordinator.SendMsg(chainA, chainB, clientB, startMsg)
err := coordinator.SendMsg(chainA, chainB, clientB, startMsg)
require.NoError(t, err)
t.Log("Duplicate messages are due to check/deliver tx calls")
var (
activePlayer = ping
pingBallValue = startValue
)
for i := 1; i <= rounds; i++ {
t.Logf("++ round: %d\n", i)
ball := NewHit(activePlayer, pingBallValue)
seq := uint64(i)
pkg := channeltypes.NewPacket(ball.GetBytes(), seq, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, doNotTimeout, 0)
ack := ball.BuildAck()
err = coordinator.RelayPacket(chainA, chainB, clientA, clientB, pkg, ack.GetBytes())
require.NoError(t, err)
//coordinator.CommitBlock(chainA, chainB)
err = coordinator.UpdateClient(chainA, chainB, clientA, ibcexported.Tendermint)
err := coordinator.RelayAndAckPendingPackets(chainA, chainB, clientA, clientB)
require.NoError(t, err)
// switch side
activePlayer = counterParty(activePlayer)
ball = NewHit(activePlayer, uint64(i))
pkg = channeltypes.NewPacket(ball.GetBytes(), seq, channelB.PortID, channelB.ID, channelA.PortID, channelA.ID, doNotTimeout, 0)
ack = ball.BuildAck()
err = coordinator.RelayPacket(chainB, chainA, clientB, clientA, pkg, ack.GetBytes())
err = coordinator.RelayAndAckPendingPackets(chainB, chainA, clientB, clientA)
require.NoError(t, err)
err = coordinator.UpdateClient(chainB, chainA, clientB, ibcexported.Tendermint)
require.NoError(t, err)
// switch side for next round
activePlayer = counterParty(activePlayer)
pingBallValue++
}
assert.Equal(t, startValue+rounds, pingContract.QueryState(lastBallSentKey))
assert.Equal(t, uint64(rounds), pingContract.QueryState(lastBallReceivedKey))
@ -145,7 +120,7 @@ type player struct {
// Execute starts the ping pong game
// Contracts finds all connected channels and broadcasts a ping message
func (p *player) Execute(code wasmvm.Checksum, env wasmvmtypes.Env, info wasmvmtypes.MessageInfo, executeMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.Response, uint64, error) {
func (p *player) Execute(code 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.Response, uint64, error) {
p.execCalls++
if p.execCalls%2 == 1 { // skip checkTx step because of no rollback with `chain.GetContext()`
return &wasmvmtypes.Response{}, 0, nil
@ -165,8 +140,8 @@ func (p *player) Execute(code wasmvm.Checksum, env wasmvmtypes.Env, info wasmvmt
p.incrementCounter(sentBallsCountKey, store)
store.Set(lastBallSentKey, sdk.Uint64ToBigEndian(start.Value))
return &wasmvmtypes.Response{
Messages: []wasmvmtypes.CosmosMsg{
{
Messages: []wasmvmtypes.SubMsg{
{Msg: wasmvmtypes.CosmosMsg{
IBC: &wasmvmtypes.IBCMsg{
SendPacket: &wasmvmtypes.SendPacketMsg{
ChannelID: start.ChannelID,
@ -178,12 +153,14 @@ func (p *player) Execute(code wasmvm.Checksum, env wasmvmtypes.Env, info wasmvmt
},
},
},
ReplyOn: wasmvmtypes.ReplyNever,
},
},
}, 0, nil
}
// OnIBCChannelOpen ensures to accept only configured version
func (p player) IBCChannelOpen(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannel, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (uint64, error) {
func (p player) IBCChannelOpen(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannel, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (uint64, error) {
if channel.Version != p.actor {
return 0, nil
}
@ -191,7 +168,7 @@ func (p player) IBCChannelOpen(codeID wasmvm.Checksum, env wasmvmtypes.Env, chan
}
// OnIBCChannelConnect persists connection endpoints
func (p player) IBCChannelConnect(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannel, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
func (p player) IBCChannelConnect(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannel, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
p.storeEndpoint(store, channel)
return &wasmvmtypes.IBCBasicResponse{}, 0, nil
}
@ -232,7 +209,7 @@ func (p player) storeEndpoint(store wasmvm.KVStore, channel wasmvmtypes.IBCChann
store.Set(ibcEndpointsKey, bz)
}
func (p player) IBCChannelClose(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannel, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
func (p player) IBCChannelClose(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannel, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
panic("implement me")
}
@ -245,7 +222,7 @@ var ( // store keys
)
// IBCPacketReceive receives the hit and serves a response hit via `wasmvmtypes.IBCPacket`
func (p player) IBCPacketReceive(codeID wasmvm.Checksum, env wasmvmtypes.Env, packet wasmvmtypes.IBCPacket, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.IBCReceiveResponse, uint64, error) {
func (p player) IBCPacketReceive(codeID wasmvm.Checksum, env wasmvmtypes.Env, packet wasmvmtypes.IBCPacket, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCReceiveResponse, uint64, error) {
// parse received data and store
var receivedBall hit
if err := json.Unmarshal(packet.Data, &receivedBall); err != nil {
@ -281,12 +258,12 @@ func (p player) IBCPacketReceive(codeID wasmvm.Checksum, env wasmvmtypes.Env, pa
return &wasmvmtypes.IBCReceiveResponse{
Acknowledgement: receivedBall.BuildAck().GetBytes(),
Messages: []wasmvmtypes.CosmosMsg{{IBC: respHit}},
Messages: []wasmvmtypes.SubMsg{{Msg: wasmvmtypes.CosmosMsg{IBC: respHit}, ReplyOn: wasmvmtypes.ReplyNever}},
}, 0, nil
}
// OnIBCPacketAcknowledgement handles the packet acknowledgment frame. Stops the game on an any error
func (p player) IBCPacketAck(codeID wasmvm.Checksum, env wasmvmtypes.Env, packetAck wasmvmtypes.IBCAcknowledgement, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
func (p player) IBCPacketAck(codeID wasmvm.Checksum, env wasmvmtypes.Env, packetAck wasmvmtypes.IBCAcknowledgementWithPacket, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
// parse received data and store
var sentBall hit
if err := json.Unmarshal(packetAck.OriginalPacket.Data, &sentBall); err != nil {
@ -294,7 +271,7 @@ func (p player) IBCPacketAck(codeID wasmvm.Checksum, env wasmvmtypes.Env, packet
}
var ack hitAcknowledgement
if err := json.Unmarshal(packetAck.Acknowledgement, &ack); err != nil {
if err := json.Unmarshal(packetAck.Acknowledgement.Data, &ack); err != nil {
return nil, 0, err
}
if ack.Success != nil {
@ -309,7 +286,7 @@ func (p player) IBCPacketAck(codeID wasmvm.Checksum, env wasmvmtypes.Env, packet
return &wasmvmtypes.IBCBasicResponse{}, 0, nil
}
func (p player) IBCPacketTimeout(codeID wasmvm.Checksum, env wasmvmtypes.Env, packet wasmvmtypes.IBCPacket, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
func (p player) IBCPacketTimeout(codeID wasmvm.Checksum, env wasmvmtypes.Env, packet wasmvmtypes.IBCPacket, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
panic("implement me")
}

View File

@ -302,7 +302,7 @@ type captureCloseContract struct {
closeCalled bool
}
func (c *captureCloseContract) IBCChannelClose(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannel, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
func (c *captureCloseContract) IBCChannelClose(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannel, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
c.closeCalled = true
return &wasmvmtypes.IBCBasicResponse{}, 1, nil
}
@ -315,7 +315,7 @@ type sendViaIBCTransferContract struct {
t *testing.T
}
func (s *sendViaIBCTransferContract) Execute(code wasmvm.Checksum, env wasmvmtypes.Env, info wasmvmtypes.MessageInfo, executeMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.Response, uint64, error) {
func (s *sendViaIBCTransferContract) Execute(code 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.Response, uint64, error) {
var in startTransfer
if err := json.Unmarshal(executeMsg, &in); err != nil {
return nil, 0, err
@ -332,7 +332,8 @@ func (s *sendViaIBCTransferContract) Execute(code wasmvm.Checksum, env wasmvmtyp
},
}
return &wasmvmtypes.Response{Messages: []wasmvmtypes.CosmosMsg{{IBC: ibcMsg}}}, 0, nil
return &wasmvmtypes.Response{Messages: []wasmvmtypes.SubMsg{{ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{IBC: ibcMsg}}}}, 0, nil
return &wasmvmtypes.Response{Messages: []wasmvmtypes.SubMsg{{ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{IBC: ibcMsg}}}}, 0, nil
}
var _ wasmtesting.IBCContractCallbacks = &sendEmulatedIBCTransferContract{}
@ -345,7 +346,7 @@ type sendEmulatedIBCTransferContract struct {
contractAddr string
}
func (s *sendEmulatedIBCTransferContract) Execute(code wasmvm.Checksum, env wasmvmtypes.Env, info wasmvmtypes.MessageInfo, executeMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.Response, uint64, error) {
func (s *sendEmulatedIBCTransferContract) Execute(code 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.Response, uint64, error) {
var in startTransfer
if err := json.Unmarshal(executeMsg, &in); err != nil {
return nil, 0, err
@ -365,10 +366,10 @@ func (s *sendEmulatedIBCTransferContract) Execute(code wasmvm.Checksum, env wasm
Timeout: wasmvmtypes.IBCTimeout{Timestamp: in.Timeout},
},
}
return &wasmvmtypes.Response{Messages: []wasmvmtypes.CosmosMsg{{IBC: ibcMsg}}}, 0, nil
return &wasmvmtypes.Response{Messages: []wasmvmtypes.SubMsg{{ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{IBC: ibcMsg}}}}, 0, nil
}
func (c *sendEmulatedIBCTransferContract) IBCPacketTimeout(codeID wasmvm.Checksum, env wasmvmtypes.Env, packet wasmvmtypes.IBCPacket, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
func (c *sendEmulatedIBCTransferContract) IBCPacketTimeout(codeID wasmvm.Checksum, env wasmvmtypes.Env, packet wasmvmtypes.IBCPacket, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
var data ibctransfertypes.FungibleTokenPacketData
if err := ibctransfertypes.ModuleCdc.UnmarshalJSON(packet.Data, &data); err != nil {
return nil, 0, err
@ -380,7 +381,7 @@ func (c *sendEmulatedIBCTransferContract) IBCPacketTimeout(codeID wasmvm.Checksu
Amount: wasmvmtypes.Coins{wasmvmtypes.NewCoin(data.Amount, data.Denom)},
}}
return &wasmvmtypes.IBCBasicResponse{Messages: []wasmvmtypes.CosmosMsg{{Bank: returnTokens}}}, 0, nil
return &wasmvmtypes.IBCBasicResponse{Messages: []wasmvmtypes.SubMsg{{ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{Bank: returnTokens}}}}, 0, nil
}
// custom contract execute payload
@ -410,7 +411,7 @@ type receiverContract struct {
chain *ibctesting.TestChain
}
func (c *receiverContract) IBCPacketReceive(codeID wasmvm.Checksum, env wasmvmtypes.Env, packet wasmvmtypes.IBCPacket, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.IBCReceiveResponse, uint64, error) {
func (c *receiverContract) IBCPacketReceive(codeID wasmvm.Checksum, env wasmvmtypes.Env, packet wasmvmtypes.IBCPacket, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCReceiveResponse, uint64, error) {
var src ibctransfertypes.FungibleTokenPacketData
if err := ibctransfertypes.ModuleCdc.UnmarshalJSON(packet.Data, &src); err != nil {
return nil, 0, err
@ -428,7 +429,7 @@ func (c *receiverContract) IBCPacketReceive(codeID wasmvm.Checksum, env wasmvmty
return &wasmvmtypes.IBCReceiveResponse{Acknowledgement: ack, Attributes: log}, 0, nil
}
func (c *receiverContract) IBCPacketAck(codeID wasmvm.Checksum, env wasmvmtypes.Env, packetAck wasmvmtypes.IBCAcknowledgement, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
func (c *receiverContract) IBCPacketAck(codeID wasmvm.Checksum, env wasmvmtypes.Env, packetAck wasmvmtypes.IBCAcknowledgementWithPacket, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
var data ibctransfertypes.FungibleTokenPacketData
if err := ibctransfertypes.ModuleCdc.UnmarshalJSON(packetAck.OriginalPacket.Data, &data); err != nil {
return nil, 0, err
@ -436,7 +437,7 @@ func (c *receiverContract) IBCPacketAck(codeID wasmvm.Checksum, env wasmvmtypes.
// call original ibctransfer keeper to not copy all code into this
var ack channeltypes.Acknowledgement
if err := ibctransfertypes.ModuleCdc.UnmarshalJSON(packetAck.Acknowledgement, &ack); err != nil {
if err := ibctransfertypes.ModuleCdc.UnmarshalJSON(packetAck.Acknowledgement.Data, &ack); err != nil {
return nil, 0, err
}
@ -454,27 +455,27 @@ func (c *receiverContract) IBCPacketAck(codeID wasmvm.Checksum, env wasmvmtypes.
// simple helper struct that implements connection setup methods.
type contractStub struct{}
func (s *contractStub) IBCChannelOpen(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannel, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (uint64, error) {
func (s *contractStub) IBCChannelOpen(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannel, 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) IBCChannelConnect(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannel, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
func (s *contractStub) IBCChannelConnect(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannel, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
return &wasmvmtypes.IBCBasicResponse{}, 0, nil
}
func (s *contractStub) IBCChannelClose(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannel, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
func (s *contractStub) IBCChannelClose(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannel, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
panic("implement me")
}
func (s *contractStub) IBCPacketReceive(codeID wasmvm.Checksum, env wasmvmtypes.Env, packet wasmvmtypes.IBCPacket, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.IBCReceiveResponse, uint64, error) {
func (s *contractStub) IBCPacketReceive(codeID wasmvm.Checksum, env wasmvmtypes.Env, packet wasmvmtypes.IBCPacket, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCReceiveResponse, uint64, error) {
panic("implement me")
}
func (s *contractStub) IBCPacketAck(codeID wasmvm.Checksum, env wasmvmtypes.Env, ack wasmvmtypes.IBCAcknowledgement, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
func (s *contractStub) IBCPacketAck(codeID wasmvm.Checksum, env wasmvmtypes.Env, ack wasmvmtypes.IBCAcknowledgementWithPacket, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
return &wasmvmtypes.IBCBasicResponse{}, 0, nil
}
func (s *contractStub) IBCPacketTimeout(codeID wasmvm.Checksum, env wasmvmtypes.Env, packet wasmvmtypes.IBCPacket, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
func (s *contractStub) IBCPacketTimeout(codeID wasmvm.Checksum, env wasmvmtypes.Env, packet wasmvmtypes.IBCPacket, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) {
panic("implement me")
}

View File

@ -1,9 +1,12 @@
package types
const (
CustomEventType = "wasm"
EventTypePinCode = "pin_code"
EventTypeUnpinCode = "unpin_code"
// WasmModuleEventType is stored with any contract TX
WasmModuleEventType = "wasm"
// CustomContractEventPrefix contracts can create custom events. To not mix them with other system events they got the `wasm-` prefix.
CustomContractEventPrefix = "wasm-"
EventTypePinCode = "pin_code"
EventTypeUnpinCode = "unpin_code"
)
const ( // event attributes
AttributeKeyContractAddr = "contract_address"

View File

@ -1,7 +1,7 @@
package types
import (
types2 "github.com/CosmWasm/wasmvm/types"
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
"github.com/cosmos/cosmos-sdk/types"
sdk "github.com/cosmos/cosmos-sdk/types"
capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
@ -58,32 +58,32 @@ type IBCContractKeeper interface {
OnOpenChannel(
ctx sdk.Context,
contractAddr sdk.AccAddress,
channel types2.IBCChannel,
channel wasmvmtypes.IBCChannel,
) error
OnConnectChannel(
ctx sdk.Context,
contractAddr sdk.AccAddress,
channel types2.IBCChannel,
channel wasmvmtypes.IBCChannel,
) error
OnCloseChannel(
ctx sdk.Context,
contractAddr sdk.AccAddress,
channel types2.IBCChannel,
channel wasmvmtypes.IBCChannel,
) error
OnRecvPacket(
ctx sdk.Context,
contractAddr sdk.AccAddress,
packet types2.IBCPacket,
packet wasmvmtypes.IBCPacket,
) ([]byte, error)
OnAckPacket(
ctx sdk.Context,
contractAddr sdk.AccAddress,
acknowledgement types2.IBCAcknowledgement,
acknowledgement wasmvmtypes.IBCAcknowledgementWithPacket,
) error
OnTimeoutPacket(
ctx sdk.Context,
contractAddr sdk.AccAddress,
packet types2.IBCPacket,
packet wasmvmtypes.IBCPacket,
) error
// ClaimCapability allows the transfer module to claim a capability
//that IBC module passes to it

View File

@ -297,23 +297,6 @@ func NewWasmCoins(cosmosCoins sdk.Coins) (wasmCoins []wasmvmtypes.Coin) {
return wasmCoins
}
// ParseEvents converts wasm LogAttributes into an sdk.Events. Returns events and number of bytes for custom attributes
func ParseEvents(wasmOutputAttrs []wasmvmtypes.EventAttribute, contractAddr sdk.AccAddress) sdk.Events {
// we always tag with the contract address issuing this event
attrs := []sdk.Attribute{sdk.NewAttribute(AttributeKeyContractAddr, contractAddr.String())}
// append attributes from wasm to the sdk.Event
for _, l := range wasmOutputAttrs {
// and reserve the contract_address key for our use (not contract)
if l.Key != AttributeKeyContractAddr {
attr := sdk.NewAttribute(l.Key, l.Value)
attrs = append(attrs, attr)
}
}
// each wasm invokation always returns one sdk.Event
return sdk.Events{sdk.NewEvent(CustomEventType, attrs...)}
}
// WasmConfig is the extra config required for wasm
type WasmConfig struct {
SmartQueryGasLimit uint64

View File

@ -31,7 +31,7 @@ type WasmerEngine interface {
// Under the hood, we may recompile the wasm, use a cached native compile, or even use a cached instance
// for performance.
Instantiate(
code wasmvm.Checksum,
checksum wasmvm.Checksum,
env wasmvmtypes.Env,
info wasmvmtypes.MessageInfo,
initMsg []byte,
@ -40,6 +40,7 @@ type WasmerEngine interface {
querier wasmvm.Querier,
gasMeter wasmvm.GasMeter,
gasLimit uint64,
deserCost wasmvmtypes.UFraction,
) (*wasmvmtypes.Response, uint64, error)
// Execute calls a given contract. Since the only difference between contracts with the same CodeID is the
@ -58,6 +59,7 @@ type WasmerEngine interface {
querier wasmvm.Querier,
gasMeter wasmvm.GasMeter,
gasLimit uint64,
deserCost wasmvmtypes.UFraction,
) (*wasmvmtypes.Response, uint64, error)
// Query allows a client to execute a contract-specific query. If the result is not empty, it should be
@ -72,6 +74,7 @@ type WasmerEngine interface {
querier wasmvm.Querier,
gasMeter wasmvm.GasMeter,
gasLimit uint64,
deserCost wasmvmtypes.UFraction,
) ([]byte, uint64, error)
// Migrate will migrate an existing contract to a new code binary.
@ -81,7 +84,7 @@ type WasmerEngine interface {
//
// MigrateMsg has some data on how to perform the migration.
Migrate(
codeID wasmvm.Checksum,
checksum wasmvm.Checksum,
env wasmvmtypes.Env,
migrateMsg []byte,
store wasmvm.KVStore,
@ -89,6 +92,7 @@ type WasmerEngine interface {
querier wasmvm.Querier,
gasMeter wasmvm.GasMeter,
gasLimit uint64,
deserCost wasmvmtypes.UFraction,
) (*wasmvmtypes.Response, uint64, error)
// Sudo runs an existing contract in read/write mode (like Execute), but is never exposed to external callers
@ -97,7 +101,7 @@ type WasmerEngine interface {
// This allows a contract to expose custom "super user" functions or priviledged operations that can be
// deeply integrated with native modules.
Sudo(
codeID wasmvm.Checksum,
checksum wasmvm.Checksum,
env wasmvmtypes.Env,
sudoMsg []byte,
store wasmvm.KVStore,
@ -105,11 +109,12 @@ type WasmerEngine interface {
querier wasmvm.Querier,
gasMeter wasmvm.GasMeter,
gasLimit uint64,
deserCost wasmvmtypes.UFraction,
) (*wasmvmtypes.Response, uint64, error)
// Reply is called on the original dispatching contract after running a submessage
Reply(
codeID wasmvm.Checksum,
checksum wasmvm.Checksum,
env wasmvmtypes.Env,
reply wasmvmtypes.Reply,
store wasmvm.KVStore,
@ -117,6 +122,7 @@ type WasmerEngine interface {
querier wasmvm.Querier,
gasMeter wasmvm.GasMeter,
gasLimit uint64,
deserCost wasmvmtypes.UFraction,
) (*wasmvmtypes.Response, uint64, error)
// GetCode will load the original wasm code for the given code id.
@ -134,7 +140,7 @@ type WasmerEngine interface {
// IBCChannelOpen is available on IBC-enabled contracts and is a hook to call into
// during the handshake pahse
IBCChannelOpen(
codeID wasmvm.Checksum,
checksum wasmvm.Checksum,
env wasmvmtypes.Env,
channel wasmvmtypes.IBCChannel,
store wasmvm.KVStore,
@ -142,12 +148,13 @@ type WasmerEngine interface {
querier wasmvm.Querier,
gasMeter wasmvm.GasMeter,
gasLimit uint64,
deserCost wasmvmtypes.UFraction,
) (uint64, error)
// IBCChannelConnect is available on IBC-enabled contracts and is a hook to call into
// during the handshake pahse
IBCChannelConnect(
codeID wasmvm.Checksum,
checksum wasmvm.Checksum,
env wasmvmtypes.Env,
channel wasmvmtypes.IBCChannel,
store wasmvm.KVStore,
@ -155,12 +162,13 @@ type WasmerEngine interface {
querier wasmvm.Querier,
gasMeter wasmvm.GasMeter,
gasLimit uint64,
deserCost wasmvmtypes.UFraction,
) (*wasmvmtypes.IBCBasicResponse, uint64, error)
// IBCChannelClose is available on IBC-enabled contracts and is a hook to call into
// at the end of the channel lifetime
IBCChannelClose(
codeID wasmvm.Checksum,
checksum wasmvm.Checksum,
env wasmvmtypes.Env,
channel wasmvmtypes.IBCChannel,
store wasmvm.KVStore,
@ -168,12 +176,13 @@ type WasmerEngine interface {
querier wasmvm.Querier,
gasMeter wasmvm.GasMeter,
gasLimit uint64,
deserCost wasmvmtypes.UFraction,
) (*wasmvmtypes.IBCBasicResponse, uint64, error)
// IBCPacketReceive is available on IBC-enabled contracts and is called when an incoming
// packet is received on a channel belonging to this contract
IBCPacketReceive(
codeID wasmvm.Checksum,
checksum wasmvm.Checksum,
env wasmvmtypes.Env,
packet wasmvmtypes.IBCPacket,
store wasmvm.KVStore,
@ -181,26 +190,29 @@ type WasmerEngine interface {
querier wasmvm.Querier,
gasMeter wasmvm.GasMeter,
gasLimit uint64,
deserCost wasmvmtypes.UFraction,
) (*wasmvmtypes.IBCReceiveResponse, uint64, error)
// IBCPacketAck is available on IBC-enabled contracts and is called when an
// the response for an outgoing packet (previously sent by this contract)
// is received
IBCPacketAck(
codeID wasmvm.Checksum,
checksum wasmvm.Checksum,
env wasmvmtypes.Env,
ack wasmvmtypes.IBCAcknowledgement,
ack wasmvmtypes.IBCAcknowledgementWithPacket,
store wasmvm.KVStore,
goapi wasmvm.GoAPI,
querier wasmvm.Querier,
gasMeter wasmvm.GasMeter,
gasLimit uint64,
deserCost wasmvmtypes.UFraction,
) (*wasmvmtypes.IBCBasicResponse, uint64, error)
// IBCPacketTimeout is available on IBC-enabled contracts and is called when an
// outgoing packet (previously sent by this contract) will provably never be executed.
// Usually handled like ack returning an error
IBCPacketTimeout(
codeID wasmvm.Checksum,
checksum wasmvm.Checksum,
env wasmvmtypes.Env,
packet wasmvmtypes.IBCPacket,
store wasmvm.KVStore,
@ -208,6 +220,7 @@ type WasmerEngine interface {
querier wasmvm.Querier,
gasMeter wasmvm.GasMeter,
gasLimit uint64,
deserCost wasmvmtypes.UFraction,
) (*wasmvmtypes.IBCBasicResponse, uint64, error)
// Pin pins a code to an in-memory cache, such that is