wasmd/x/wasm/internal/keeper/relay_test.go

659 lines
22 KiB
Go

package keeper
import (
"encoding/json"
"errors"
"github.com/CosmWasm/wasmd/x/wasm/internal/keeper/wasmtesting"
wasmvm "github.com/CosmWasm/wasmvm"
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"testing"
)
func TestOnOpenChannel(t *testing.T) {
var m wasmtesting.MockWasmer
wasmtesting.MakeIBCInstantiable(&m)
parentCtx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil)
example := SeedNewContractInstance(t, parentCtx, keepers, &m)
specs := map[string]struct {
contractAddr sdk.AccAddress
contractGas sdk.Gas
contractErr error
expErr bool
}{
"consume contract gas": {
contractAddr: example.Contract,
contractGas: 10,
},
"consume max gas": {
contractAddr: example.Contract,
contractGas: MaxGas,
},
"consume gas on error": {
contractAddr: example.Contract,
contractGas: 20,
contractErr: errors.New("test, ignore"),
expErr: true,
},
"unknown contract address": {
contractAddr: RandomAccountAddress(t),
expErr: true,
},
}
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) {
assert.Equal(t, myChannel, channel)
return spec.contractGas * GasMultiplier, spec.contractErr
}
ctx, cancel := parentCtx.CacheContext()
defer cancel()
before := ctx.GasMeter().GasConsumed()
// when
err := keepers.WasmKeeper.OnOpenChannel(ctx, spec.contractAddr, myChannel)
// then
if spec.expErr {
require.Error(t, err)
return
}
require.NoError(t, err)
// verify gas consumed
const storageCosts = sdk.Gas(0xa9d)
assert.Equal(t, spec.contractGas, ctx.GasMeter().GasConsumed()-before-storageCosts)
})
}
}
func TestOnConnectChannel(t *testing.T) {
var m wasmtesting.MockWasmer
wasmtesting.MakeIBCInstantiable(&m)
parentCtx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil)
example := SeedNewContractInstance(t, parentCtx, keepers, &m)
specs := map[string]struct {
contractAddr sdk.AccAddress
contractGas sdk.Gas
contractResp *wasmvmtypes.IBCBasicResponse
contractErr error
overwriteMessenger messenger
expErr bool
expContractEventAttrs int
expNoEvents bool
}{
"consume contract gas": {
contractAddr: example.Contract,
contractGas: 10,
contractResp: &wasmvmtypes.IBCBasicResponse{},
},
"consume gas on error, ignore events + messages": {
contractAddr: example.Contract,
contractGas: 20,
contractResp: &wasmvmtypes.IBCBasicResponse{
Messages: []wasmvmtypes.CosmosMsg{{Bank: &wasmvmtypes.BankMsg{}}},
Attributes: []wasmvmtypes.EventAttribute{{Key: "Foo", Value: "Bar"}},
},
contractErr: errors.New("test, ignore"),
expErr: true,
expNoEvents: true,
},
"dispatch contract messages on success": {
contractAddr: example.Contract,
contractGas: 30,
contractResp: &wasmvmtypes.IBCBasicResponse{
Messages: []wasmvmtypes.CosmosMsg{{Bank: &wasmvmtypes.BankMsg{}}, {Custom: json.RawMessage(`{"foo":"bar"}`)}},
},
},
"emit contract events on success": {
contractAddr: example.Contract,
contractGas: 40,
contractResp: &wasmvmtypes.IBCBasicResponse{
Attributes: []wasmvmtypes.EventAttribute{{Key: "Foo", Value: "Bar"}},
},
expContractEventAttrs: 1,
},
"messenger errors returned, events stored": {
contractAddr: example.Contract,
contractGas: 50,
contractResp: &wasmvmtypes.IBCBasicResponse{
Messages: []wasmvmtypes.CosmosMsg{{Bank: &wasmvmtypes.BankMsg{}}, {Custom: json.RawMessage(`{"foo":"bar"}`)}},
Attributes: []wasmvmtypes.EventAttribute{{Key: "Foo", Value: "Bar"}},
},
overwriteMessenger: &wasmtesting.MockMessageHandler{
DispatchFn: func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msgs ...wasmvmtypes.CosmosMsg) error {
return errors.New("test, ignore")
},
},
expErr: true,
expContractEventAttrs: 1,
},
"unknown contract address": {
contractAddr: RandomAccountAddress(t),
expErr: true,
expNoEvents: true,
},
}
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) {
assert.Equal(t, channel, myChannel)
return spec.contractResp, spec.contractGas * GasMultiplier, spec.contractErr
}
ctx, cancel := parentCtx.CacheContext()
ctx = ctx.WithEventManager(sdk.NewEventManager())
defer cancel()
before := ctx.GasMeter().GasConsumed()
msger, capturedMsgs := wasmtesting.NewCapturingMessageHandler()
keepers.WasmKeeper.messenger = msger
if spec.overwriteMessenger != nil {
keepers.WasmKeeper.messenger = spec.overwriteMessenger
}
// when
err := keepers.WasmKeeper.OnConnectChannel(ctx, spec.contractAddr, myChannel)
// then
events := ctx.EventManager().Events()
if spec.expErr {
require.Error(t, err)
assert.Empty(t, capturedMsgs) // no messages captured on error
if spec.expNoEvents {
require.Len(t, events, 0)
} else {
require.Len(t, events, 1)
assert.Len(t, events[0].Attributes, 1+spec.expContractEventAttrs)
}
return
}
require.NoError(t, err)
// verify gas consumed
const storageCosts = sdk.Gas(0xa9d)
assert.Equal(t, spec.contractGas, ctx.GasMeter().GasConsumed()-before-storageCosts)
// verify msgs dispatched
assert.Equal(t, spec.contractResp.Messages, *capturedMsgs)
assert.Len(t, events[0].Attributes, 1+spec.expContractEventAttrs)
})
}
}
func TestOnCloseChannel(t *testing.T) {
var m wasmtesting.MockWasmer
wasmtesting.MakeIBCInstantiable(&m)
parentCtx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil)
example := SeedNewContractInstance(t, parentCtx, keepers, &m)
specs := map[string]struct {
contractAddr sdk.AccAddress
contractGas sdk.Gas
contractResp *wasmvmtypes.IBCBasicResponse
contractErr error
overwriteMessenger messenger
expErr bool
expContractEventAttrs int
expNoEvents bool
}{
"consume contract gas": {
contractAddr: example.Contract,
contractGas: 10,
contractResp: &wasmvmtypes.IBCBasicResponse{},
},
"consume gas on error, ignore events + messages": {
contractAddr: example.Contract,
contractGas: 20,
contractResp: &wasmvmtypes.IBCBasicResponse{
Messages: []wasmvmtypes.CosmosMsg{{Bank: &wasmvmtypes.BankMsg{}}},
Attributes: []wasmvmtypes.EventAttribute{{Key: "Foo", Value: "Bar"}},
},
contractErr: errors.New("test, ignore"),
expErr: true,
expNoEvents: true,
},
"dispatch contract messages on success": {
contractAddr: example.Contract,
contractGas: 30,
contractResp: &wasmvmtypes.IBCBasicResponse{
Messages: []wasmvmtypes.CosmosMsg{{Bank: &wasmvmtypes.BankMsg{}}, {Custom: json.RawMessage(`{"foo":"bar"}`)}},
},
},
"emit contract events on success": {
contractAddr: example.Contract,
contractGas: 40,
contractResp: &wasmvmtypes.IBCBasicResponse{
Attributes: []wasmvmtypes.EventAttribute{{Key: "Foo", Value: "Bar"}},
},
expContractEventAttrs: 1,
},
"messenger errors returned, events stored": {
contractAddr: example.Contract,
contractGas: 50,
contractResp: &wasmvmtypes.IBCBasicResponse{
Messages: []wasmvmtypes.CosmosMsg{{Bank: &wasmvmtypes.BankMsg{}}, {Custom: json.RawMessage(`{"foo":"bar"}`)}},
Attributes: []wasmvmtypes.EventAttribute{{Key: "Foo", Value: "Bar"}},
},
overwriteMessenger: &wasmtesting.MockMessageHandler{
DispatchFn: func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msgs ...wasmvmtypes.CosmosMsg) error {
return errors.New("test, ignore")
},
},
expErr: true,
expContractEventAttrs: 1,
},
"unknown contract address": {
contractAddr: RandomAccountAddress(t),
expErr: true,
expNoEvents: true,
},
}
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) {
assert.Equal(t, channel, myChannel)
return spec.contractResp, spec.contractGas * GasMultiplier, spec.contractErr
}
ctx, cancel := parentCtx.CacheContext()
defer cancel()
before := ctx.GasMeter().GasConsumed()
msger, capturedMsgs := wasmtesting.NewCapturingMessageHandler()
keepers.WasmKeeper.messenger = msger
if spec.overwriteMessenger != nil {
keepers.WasmKeeper.messenger = spec.overwriteMessenger
}
// when
err := keepers.WasmKeeper.OnCloseChannel(ctx, spec.contractAddr, myChannel)
// then
events := ctx.EventManager().Events()
if spec.expErr {
require.Error(t, err)
assert.Empty(t, capturedMsgs) // no messages captured on error
if spec.expNoEvents {
require.Len(t, events, 0)
} else {
require.Len(t, events, 1)
assert.Len(t, events[0].Attributes, 1+spec.expContractEventAttrs)
}
return
}
require.NoError(t, err)
// verify gas consumed
const storageCosts = sdk.Gas(0xa9d)
assert.Equal(t, spec.contractGas, ctx.GasMeter().GasConsumed()-before-storageCosts)
// verify msgs dispatched
assert.Equal(t, spec.contractResp.Messages, *capturedMsgs)
require.Len(t, events, 1)
assert.Len(t, events[0].Attributes, 1+spec.expContractEventAttrs)
})
}
}
func TestOnRecvPacket(t *testing.T) {
var m wasmtesting.MockWasmer
wasmtesting.MakeIBCInstantiable(&m)
parentCtx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil)
example := SeedNewContractInstance(t, parentCtx, keepers, &m)
specs := map[string]struct {
contractAddr sdk.AccAddress
contractGas sdk.Gas
contractResp *wasmvmtypes.IBCReceiveResponse
contractErr error
overwriteMessenger messenger
expErr bool
expContractEventAttrs int
expNoEvents bool
}{
"consume contract gas": {
contractAddr: example.Contract,
contractGas: 10,
contractResp: &wasmvmtypes.IBCReceiveResponse{
Acknowledgement: []byte("myAck"),
},
},
"can return empty ack": {
contractAddr: example.Contract,
contractGas: 10,
contractResp: &wasmvmtypes.IBCReceiveResponse{},
},
"consume gas on error, ignore events + messages": {
contractAddr: example.Contract,
contractGas: 20,
contractResp: &wasmvmtypes.IBCReceiveResponse{
Acknowledgement: []byte("myAck"),
Messages: []wasmvmtypes.CosmosMsg{{Bank: &wasmvmtypes.BankMsg{}}},
Attributes: []wasmvmtypes.EventAttribute{{Key: "Foo", Value: "Bar"}},
},
contractErr: errors.New("test, ignore"),
expErr: true,
expNoEvents: true,
},
"dispatch contract messages on success": {
contractAddr: example.Contract,
contractGas: 30,
contractResp: &wasmvmtypes.IBCReceiveResponse{
Acknowledgement: []byte("myAck"),
Messages: []wasmvmtypes.CosmosMsg{{Bank: &wasmvmtypes.BankMsg{}}, {Custom: json.RawMessage(`{"foo":"bar"}`)}},
},
},
"emit contract events on success": {
contractAddr: example.Contract,
contractGas: 40,
contractResp: &wasmvmtypes.IBCReceiveResponse{
Acknowledgement: []byte("myAck"),
Attributes: []wasmvmtypes.EventAttribute{{Key: "Foo", Value: "Bar"}},
},
expContractEventAttrs: 1,
},
"messenger errors returned, events stored": {
contractAddr: example.Contract,
contractGas: 50,
contractResp: &wasmvmtypes.IBCReceiveResponse{
Acknowledgement: []byte("myAck"),
Messages: []wasmvmtypes.CosmosMsg{{Bank: &wasmvmtypes.BankMsg{}}, {Custom: json.RawMessage(`{"foo":"bar"}`)}},
Attributes: []wasmvmtypes.EventAttribute{{Key: "Foo", Value: "Bar"}},
},
overwriteMessenger: &wasmtesting.MockMessageHandler{
DispatchFn: func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msgs ...wasmvmtypes.CosmosMsg) error {
return errors.New("test, ignore")
},
},
expErr: true,
expContractEventAttrs: 1,
},
"unknown contract address": {
contractAddr: RandomAccountAddress(t),
expErr: true,
expNoEvents: true,
},
}
for name, spec := range specs {
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) {
assert.Equal(t, myPacket, packet)
return spec.contractResp, spec.contractGas * GasMultiplier, spec.contractErr
}
ctx, cancel := parentCtx.CacheContext()
defer cancel()
before := ctx.GasMeter().GasConsumed()
msger, capturedMsgs := wasmtesting.NewCapturingMessageHandler()
keepers.WasmKeeper.messenger = msger
if spec.overwriteMessenger != nil {
keepers.WasmKeeper.messenger = spec.overwriteMessenger
}
// when
gotAck, err := keepers.WasmKeeper.OnRecvPacket(ctx, spec.contractAddr, myPacket)
// then
events := ctx.EventManager().Events()
if spec.expErr {
require.Error(t, err)
assert.Empty(t, capturedMsgs) // no messages captured on error
if spec.expNoEvents {
require.Len(t, events, 0)
} else {
require.Len(t, events, 1)
assert.Len(t, events[0].Attributes, 1+spec.expContractEventAttrs)
}
return
}
require.NoError(t, err)
require.Equal(t, spec.contractResp.Acknowledgement, gotAck)
// verify gas consumed
const storageCosts = sdk.Gas(0xa9d)
assert.Equal(t, spec.contractGas, ctx.GasMeter().GasConsumed()-before-storageCosts)
// verify msgs dispatched
assert.Equal(t, spec.contractResp.Messages, *capturedMsgs)
require.Len(t, events, 1)
assert.Len(t, events[0].Attributes, 1+spec.expContractEventAttrs)
})
}
}
func TestOnAckPacket(t *testing.T) {
var m wasmtesting.MockWasmer
wasmtesting.MakeIBCInstantiable(&m)
parentCtx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil)
example := SeedNewContractInstance(t, parentCtx, keepers, &m)
specs := map[string]struct {
contractAddr sdk.AccAddress
contractGas sdk.Gas
contractResp *wasmvmtypes.IBCBasicResponse
contractErr error
overwriteMessenger messenger
expErr bool
expContractEventAttrs int
expNoEvents bool
}{
"consume contract gas": {
contractAddr: example.Contract,
contractGas: 10,
contractResp: &wasmvmtypes.IBCBasicResponse{},
},
"consume gas on error, ignore events + messages": {
contractAddr: example.Contract,
contractGas: 20,
contractResp: &wasmvmtypes.IBCBasicResponse{
Messages: []wasmvmtypes.CosmosMsg{{Bank: &wasmvmtypes.BankMsg{}}},
Attributes: []wasmvmtypes.EventAttribute{{Key: "Foo", Value: "Bar"}},
},
contractErr: errors.New("test, ignore"),
expErr: true,
expNoEvents: true,
},
"dispatch contract messages on success": {
contractAddr: example.Contract,
contractGas: 30,
contractResp: &wasmvmtypes.IBCBasicResponse{
Messages: []wasmvmtypes.CosmosMsg{{Bank: &wasmvmtypes.BankMsg{}}, {Custom: json.RawMessage(`{"foo":"bar"}`)}},
},
},
"emit contract events on success": {
contractAddr: example.Contract,
contractGas: 40,
contractResp: &wasmvmtypes.IBCBasicResponse{
Attributes: []wasmvmtypes.EventAttribute{{Key: "Foo", Value: "Bar"}},
},
expContractEventAttrs: 1,
},
"messenger errors returned, events stored": {
contractAddr: example.Contract,
contractGas: 50,
contractResp: &wasmvmtypes.IBCBasicResponse{
Messages: []wasmvmtypes.CosmosMsg{{Bank: &wasmvmtypes.BankMsg{}}, {Custom: json.RawMessage(`{"foo":"bar"}`)}},
Attributes: []wasmvmtypes.EventAttribute{{Key: "Foo", Value: "Bar"}},
},
overwriteMessenger: &wasmtesting.MockMessageHandler{
DispatchFn: func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msgs ...wasmvmtypes.CosmosMsg) error {
return errors.New("test, ignore")
},
},
expErr: true,
expContractEventAttrs: 1,
},
"unknown contract address": {
contractAddr: RandomAccountAddress(t),
expErr: true,
expNoEvents: true,
},
}
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) {
assert.Equal(t, myAck, ack)
return spec.contractResp, spec.contractGas * GasMultiplier, spec.contractErr
}
ctx, cancel := parentCtx.CacheContext()
defer cancel()
before := ctx.GasMeter().GasConsumed()
msger, capturedMsgs := wasmtesting.NewCapturingMessageHandler()
keepers.WasmKeeper.messenger = msger
if spec.overwriteMessenger != nil {
keepers.WasmKeeper.messenger = spec.overwriteMessenger
}
// when
err := keepers.WasmKeeper.OnAckPacket(ctx, spec.contractAddr, myAck)
// then
events := ctx.EventManager().Events()
if spec.expErr {
require.Error(t, err)
assert.Empty(t, capturedMsgs) // no messages captured on error
if spec.expNoEvents {
require.Len(t, events, 0)
} else {
require.Len(t, events, 1)
assert.Len(t, events[0].Attributes, 1+spec.expContractEventAttrs)
}
return
}
require.NoError(t, err)
// verify gas consumed
const storageCosts = sdk.Gas(0xa9d)
assert.Equal(t, spec.contractGas, ctx.GasMeter().GasConsumed()-before-storageCosts)
// verify msgs dispatched
assert.Equal(t, spec.contractResp.Messages, *capturedMsgs)
require.Len(t, events, 1)
assert.Len(t, events[0].Attributes, 1+spec.expContractEventAttrs)
})
}
}
func TestOnTimeoutPacket(t *testing.T) {
var m wasmtesting.MockWasmer
wasmtesting.MakeIBCInstantiable(&m)
parentCtx, keepers := CreateTestInput(t, false, SupportedFeatures, nil, nil)
example := SeedNewContractInstance(t, parentCtx, keepers, &m)
specs := map[string]struct {
contractAddr sdk.AccAddress
contractGas sdk.Gas
contractResp *wasmvmtypes.IBCBasicResponse
contractErr error
overwriteMessenger messenger
expErr bool
expContractEventAttrs int
expNoEvents bool
}{
"consume contract gas": {
contractAddr: example.Contract,
contractGas: 10,
contractResp: &wasmvmtypes.IBCBasicResponse{},
},
"consume gas on error, ignore events + messages": {
contractAddr: example.Contract,
contractGas: 20,
contractResp: &wasmvmtypes.IBCBasicResponse{
Messages: []wasmvmtypes.CosmosMsg{{Bank: &wasmvmtypes.BankMsg{}}},
Attributes: []wasmvmtypes.EventAttribute{{Key: "Foo", Value: "Bar"}},
},
contractErr: errors.New("test, ignore"),
expErr: true,
expNoEvents: true,
},
"dispatch contract messages on success": {
contractAddr: example.Contract,
contractGas: 30,
contractResp: &wasmvmtypes.IBCBasicResponse{
Messages: []wasmvmtypes.CosmosMsg{{Bank: &wasmvmtypes.BankMsg{}}, {Custom: json.RawMessage(`{"foo":"bar"}`)}},
},
},
"emit contract events on success": {
contractAddr: example.Contract,
contractGas: 40,
contractResp: &wasmvmtypes.IBCBasicResponse{
Attributes: []wasmvmtypes.EventAttribute{{Key: "Foo", Value: "Bar"}},
},
expContractEventAttrs: 1,
},
"messenger errors returned, events stored": {
contractAddr: example.Contract,
contractGas: 50,
contractResp: &wasmvmtypes.IBCBasicResponse{
Messages: []wasmvmtypes.CosmosMsg{{Bank: &wasmvmtypes.BankMsg{}}, {Custom: json.RawMessage(`{"foo":"bar"}`)}},
Attributes: []wasmvmtypes.EventAttribute{{Key: "Foo", Value: "Bar"}},
},
overwriteMessenger: &wasmtesting.MockMessageHandler{
DispatchFn: func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msgs ...wasmvmtypes.CosmosMsg) error {
return errors.New("test, ignore")
},
},
expErr: true,
expContractEventAttrs: 1,
},
"unknown contract address": {
contractAddr: RandomAccountAddress(t),
expErr: true,
expNoEvents: true,
},
}
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) {
assert.Equal(t, myPacket, packet)
return spec.contractResp, spec.contractGas * GasMultiplier, spec.contractErr
}
ctx, cancel := parentCtx.CacheContext()
defer cancel()
before := ctx.GasMeter().GasConsumed()
msger, capturedMsgs := wasmtesting.NewCapturingMessageHandler()
keepers.WasmKeeper.messenger = msger
if spec.overwriteMessenger != nil {
keepers.WasmKeeper.messenger = spec.overwriteMessenger
}
// when
err := keepers.WasmKeeper.OnTimeoutPacket(ctx, spec.contractAddr, myPacket)
// then
events := ctx.EventManager().Events()
if spec.expErr {
require.Error(t, err)
assert.Empty(t, capturedMsgs) // no messages captured on error
if spec.expNoEvents {
require.Len(t, events, 0)
} else {
require.Len(t, events, 1)
assert.Len(t, events[0].Attributes, 1+spec.expContractEventAttrs)
}
return
}
require.NoError(t, err)
// verify gas consumed
const storageCosts = sdk.Gas(0xa9d)
assert.Equal(t, spec.contractGas, ctx.GasMeter().GasConsumed()-before-storageCosts)
// verify msgs dispatched
assert.Equal(t, spec.contractResp.Messages, *capturedMsgs)
require.Len(t, events, 1)
assert.Len(t, events[0].Attributes, 1+spec.expContractEventAttrs)
})
}
}