Files
wasmd/x/wasm/keeper/msg_dispatcher_test.go
Alexander Peters 7e936c7fff Cosmos-SDK v0.47 integration brach (#1149)
* Start cosmos-sdk v0.47 integration (#1136)

* Upgrade to sdk v0.47 branch

* More integration work

* SDK version upgrade; fixes

* More fixes

* Fixes

* Deactivate failing tests

* SDK + ibc-go version upgrades

* limix gas fix

(cherry picked from commit f7f841768e5051d96d243b42ce4f231a33020326)

* with valset in bench

(cherry picked from commit 35b2a8fd2c23d6160fca540771fd348913f7f143)

* Revert staking query handler; fix tests

* Minor cleanup

* Rebased

* Address linter issues

* Set legacy router proper

* Deactivate failing test. Race condition needs to handled in SDK

* Address some code smells

* Bump sdk version

* Use gov v1 internally for votes

* Activate test after sdk fix

* Add group test

* Add config template for wasm fields

* Add Rust backtrace flag for more debug output on simulations

* Set unique node folder for tests

* Revert "Add Rust backtrace flag for more debug output on simulations"

This reverts commit 218c3c6ce137dc02f7bc38391408d3460fb27e6f.

* Simulations

* Run also im/export + deterministic sims

* Add package prefix to interfaces

* Add signer annotation (https://github.com/cosmos/cosmos-sdk/issues/10933), minor cleanup

* Bump sdk version

* Review comments

Co-authored-by: vuong <nguyenvuong1122000@gmail.com>

* Bump bufbuild/buf-setup-action from 1.11.0 to 1.12.0

Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.11.0 to 1.12.0.
- [Release notes](https://github.com/bufbuild/buf-setup-action/releases)
- [Commits](https://github.com/bufbuild/buf-setup-action/compare/v1.11.0...v1.12.0)

---
updated-dependencies:
- dependency-name: bufbuild/buf-setup-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
(cherry picked from commit f4905955b5)

* Remove intertx for vanilla ICA

* fix msg format in EVENTS.md

(cherry picked from commit 38d466adfd)

* Better to sdk coin convertion (#1164)

* Better to sdk coin convertion

* Review feedback

(cherry picked from commit a925a9ed61)

* Disallow only address permission (#1163)

* Remove AccessTypeOnlyAddress for store msg

* Remove AccessTypeOnlyAddress for update config msg

* Review feedback

Co-authored-by: Simon Warta <2603011+webmaster128@users.noreply.github.com>

Co-authored-by: Simon Warta <2603011+webmaster128@users.noreply.github.com>
(cherry picked from commit 8991633de2)

* Integrate wasmvm v1.2.0 (backport #1161) (#1175)

* Integrate wasmvm v1.2.0 (#1161)

* Bump wasmvm version

* Bump wasm test contracts

* Encode weighted votes

* Encode instantiate2

* Handle code info query; better wasmvm errors

* Fix readme

* Make linter happy

* add non cgo build

* Review comments

* Bump wasmvm to release version

Co-authored-by: jhernandezb <contact@jhernandez.me>
(cherry picked from commit 957b38e0a5)

# Conflicts:
#	x/wasm/keeper/handler_plugin_encoders.go
#	x/wasm/keeper/handler_plugin_encoders_test.go
#	x/wasm/keeper/keeper.go
#	x/wasm/keeper/keeper_test.go

* Adress merge conflicts

Co-authored-by: Alexander Peters <alpe@users.noreply.github.com>

* Bump bufbuild/buf-setup-action from 1.12.0 to 1.13.0

Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.12.0 to 1.13.0.
- [Release notes](https://github.com/bufbuild/buf-setup-action/releases)
- [Commits](https://github.com/bufbuild/buf-setup-action/compare/v1.12.0...v1.13.0)

---
updated-dependencies:
- dependency-name: bufbuild/buf-setup-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
(cherry picked from commit ffa0e5e5e1)

* Emit events for setContractAdmin + setAccessConfig (#1179)

(cherry picked from commit c9e7830ac1)

* Dependency upgrades (#1172)

* Bump sdk version to lastest

* Bump ibc-go  version to lastest

* Remove channel hack

* Update to ibc-go v7 + protoVer=0.11.5

* Bump bufbuild/buf-setup-action from 1.13.0 to 1.13.1

Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.13.0 to 1.13.1.
- [Release notes](https://github.com/bufbuild/buf-setup-action/releases)
- [Commits](https://github.com/bufbuild/buf-setup-action/compare/v1.13.0...v1.13.1)

---
updated-dependencies:
- dependency-name: bufbuild/buf-setup-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
(cherry picked from commit de27e7f82f)

* Fix typos (backport #1185) (#1194)

* Fix typos

(cherry picked from commit c88b8194cb)

# Conflicts:
#	proto/cosmwasm/wasm/v1/tx.proto

* Fix merge conflict

---------

Co-authored-by: Alex Peters <alpe@users.noreply.github.com>

* Bump bufbuild/buf-setup-action from 1.13.1 to 1.14.0 (#1200)

Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.13.1 to 1.14.0.
- [Release notes](https://github.com/bufbuild/buf-setup-action/releases)
- [Commits](https://github.com/bufbuild/buf-setup-action/compare/v1.13.1...v1.14.0)

---
updated-dependencies:
- dependency-name: bufbuild/buf-setup-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
(cherry picked from commit f3fc31c386)

* list-contract-by-code bugfix

(cherry picked from commit 2ccffed778)

* fix: stargate querier does not reset the state

(cherry picked from commit fd0323541d)

* test: add unit test

(cherry picked from commit 6d8018ac59)

* Add Windows client support (#1197)

* Add Windows client support

* Separate server and windows client

---------

Co-authored-by: Alex Peters <alpe@users.noreply.github.com>
(cherry picked from commit 8a20779518)

* Bump bufbuild/buf-setup-action from 1.14.0 to 1.15.0

Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.14.0 to 1.15.0.
- [Release notes](https://github.com/bufbuild/buf-setup-action/releases)
- [Commits](https://github.com/bufbuild/buf-setup-action/compare/v1.14.0...v1.15.0)

---
updated-dependencies:
- dependency-name: bufbuild/buf-setup-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
(cherry picked from commit e5fab3da5a)

* Rename windows client binary

(cherry picked from commit de09c7fe2b)

* Return IBC packet sequence number (backport #1225) (#1233)

* Return IBC packet sequence number (#1225)

* Return IBC packet sequence number

* Fix review feedbacks

* Remove names to return values in DispatchMsg method

* Fix comments

(cherry picked from commit 4f1c57fc12)

# Conflicts:
#	x/wasm/keeper/handler_plugin.go

* Fix merge conflict

---------

Co-authored-by: pinosu <95283998+pinosu@users.noreply.github.com>
Co-authored-by: Alex Peters <alpe@users.noreply.github.com>

* Test rust panic for regression

(cherry picked from commit a52e604966)

* Fix client checksum verification (#1234)

* Fix client checksum verification

* Review comments

(cherry picked from commit 1a8019b380)

# Conflicts:
#	x/wasm/client/cli/gov_tx.go

* Fix merge conflict

* Fix linters

* Configure sonarcloud analysis

(cherry picked from commit 85cf1614fb)

* Bump bufbuild/buf-setup-action from 1.15.0 to 1.15.1

Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.15.0 to 1.15.1.
- [Release notes](https://github.com/bufbuild/buf-setup-action/releases)
- [Commits](https://github.com/bufbuild/buf-setup-action/compare/v1.15.0...v1.15.1)

---
updated-dependencies:
- dependency-name: bufbuild/buf-setup-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
(cherry picked from commit 730ea5a1cf)

* Make `CaptureIbcEvents` in ibctesting public.

Before this change, it wasn't possible to implement the
`chain.SendMsgs` method without
[copying](https://github.com/public-awesome/ics721/blob/main/e2e/suite_helpers.go#L81-L98)
them over.

(cherry picked from commit b64fa078a3)

* Upgrade to wasmvm 1.2.1 (backport #1245) (#1254)

* Upgrade to wasmvm 1.2.1 (#1245)

* Use wasmvm store adapter

* Bump wasmvm to v1.2.1

(cherry picked from commit 850f901b2e)

# Conflicts:
#	go.mod
#	go.sum
#	x/wasm/keeper/keeper.go

* Resolve conflicts

---------

Co-authored-by: Alexander Peters <alpe@users.noreply.github.com>

* WIP All cometbft (#1244)

* Dep upgrade; use CometBft

* Remove duplicte message events

* Add changelog for v0.31.0 (#1188)

* Start changelog for v0.31.0

* Add ICA upgrade

* Add proto version link to buf.build

* Update changelog (#1239)

* Update changelog

* Update changelog with latest changes

* Set release date

---------

Co-authored-by: pinosu <95283998+pinosu@users.noreply.github.com>
(cherry picked from commit bc0e817912)

* Remove new message type event

* Support msg update params gov proposal (#1247)

* Add MsgUpdateParams support

* Implement UpdateParams msg

* Fix test UpdateParams

* Add migration test

* Fix

* Fix lint issues

* Revert changes according to review feedback

* Remove more x/params dependencies

* Remove x/params from genesis test

* Formatting

* Restore old changes

* fix lint

* Fix tests and restructure migrations

* Rename alias for convention

---------

Co-authored-by: Alex Peters <alpe@users.noreply.github.com>

* Fix test data generator (#1263)

* linting 47 pr (#1261)

* lint cosmwasm for sdk 47

* fix

* remove setGenesis

* remove additional unused functions

* pass tests

* use SDK's errors module

* unecessary conversions

* unnecessary conversions

* remove unneeded event manager

* complete linting of tests for 47

* add test for reimportation

* check errors

* Update x/wasm/keeper/proposal_integration_test.go

Co-authored-by: Alexander Peters <alpe@users.noreply.github.com>

* apply suggestion

* suggestions

* lints

* don't return error in when making new transactions

* no todo's in the code

* Fix test data generator

* Update x/wasm/types/genesis_test.go

Co-authored-by: Alexander Peters <alpe@users.noreply.github.com>

* use the full string invalid address (2 words) always

---------

Co-authored-by: Alexander Peters <alpe@users.noreply.github.com>

* Regenerate from proto; remove dead code; polish code

* Set SDK version to v0.47x.0 (#1262)

* Set SDK version to v0.47x.0

* Set chainID

* Minor updates

* Set chainID for simulations

* Buf mod update

* Use sdk tag instead of hash in buf

* Bump ibc-go to v7.0.0

* faddat/re merge main (#1274)

undefined

---------

Co-authored-by: vuong <nguyenvuong1122000@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: llllllluc <58892938+llllllluc@users.noreply.github.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Co-authored-by: Gjermund Garaba <gjermund@garaba.net>
Co-authored-by: Nikhil Suri <nikhilsuri@comcast.net>
Co-authored-by: Paul <p22626262@gmail.com>
Co-authored-by: pinosu <95283998+pinosu@users.noreply.github.com>
Co-authored-by: ekez <zekemedley@gmail.com>
Co-authored-by: Jacob Gadikian <jacobgadikian@gmail.com>
2023-03-20 10:32:22 +01:00

431 lines
17 KiB
Go

package keeper
import (
"errors"
"fmt"
"testing"
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
abci "github.com/cometbft/cometbft/abci/types"
"github.com/cometbft/cometbft/libs/log"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/CosmWasm/wasmd/x/wasm/keeper/wasmtesting"
)
func TestDispatchSubmessages(t *testing.T) {
noReplyCalled := &mockReplyer{}
var anyGasLimit uint64 = 1
specs := map[string]struct {
msgs []wasmvmtypes.SubMsg
replyer *mockReplyer
msgHandler *wasmtesting.MockMessageHandler
expErr bool
expData []byte
expCommits []bool
expEvents sdk.Events
}{
"no reply on error without error": {
msgs: []wasmvmtypes.SubMsg{{ReplyOn: wasmvmtypes.ReplyError}},
replyer: noReplyCalled,
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{[]byte("myData")}, nil
},
},
expCommits: []bool{true},
},
"no reply on success without success": {
msgs: []wasmvmtypes.SubMsg{{ReplyOn: wasmvmtypes.ReplySuccess}},
replyer: noReplyCalled,
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, nil, errors.New("test, ignore")
},
},
expCommits: []bool{false},
expErr: true,
},
"reply on success - received": {
msgs: []wasmvmtypes.SubMsg{{
ReplyOn: wasmvmtypes.ReplySuccess,
}},
replyer: &mockReplyer{
replyFn: func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) ([]byte, error) {
return []byte("myReplyData"), nil
},
},
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{[]byte("myData")}, nil
},
},
expData: []byte("myReplyData"),
expCommits: []bool{true},
},
"reply on error - handled": {
msgs: []wasmvmtypes.SubMsg{{
ReplyOn: wasmvmtypes.ReplyError,
}},
replyer: &mockReplyer{
replyFn: func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) ([]byte, error) {
return []byte("myReplyData"), nil
},
},
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, nil, errors.New("my error")
},
},
expData: []byte("myReplyData"),
expCommits: []bool{false},
},
"with reply events": {
msgs: []wasmvmtypes.SubMsg{{
ReplyOn: wasmvmtypes.ReplySuccess,
}},
replyer: &mockReplyer{
replyFn: func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) ([]byte, error) {
ctx.EventManager().EmitEvent(sdk.NewEvent("wasm-reply"))
return []byte("myReplyData"), nil
},
},
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: "foo", Value: "bar"}}}}
return myEvents, [][]byte{[]byte("myData")}, nil
},
},
expData: []byte("myReplyData"),
expCommits: []bool{true},
expEvents: []sdk.Event{
{
Type: "myEvent",
Attributes: []abci.EventAttribute{{Key: "foo", Value: "bar"}},
},
sdk.NewEvent("wasm-reply"),
},
},
"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: "foo", Value: "bar"}}}}
ctx.EventManager().EmitEvents(myEvents)
return nil, nil, nil
},
},
expCommits: []bool{true},
expEvents: []sdk.Event{{
Type: "myEvent",
Attributes: []abci.EventAttribute{{Key: "foo", Value: "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: "foo", Value: "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,
}},
replyer: &mockReplyer{
replyFn: func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) ([]byte, error) {
return nil, errors.New("reply failed")
},
},
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, nil, nil
},
},
expCommits: []bool{false},
expErr: true,
},
"with gas limit - out of gas": {
msgs: []wasmvmtypes.SubMsg{{
GasLimit: &anyGasLimit,
ReplyOn: wasmvmtypes.ReplyError,
}},
replyer: &mockReplyer{
replyFn: func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) ([]byte, error) {
return []byte("myReplyData"), nil
},
},
msgHandler: &wasmtesting.MockMessageHandler{
DispatchMsgFn: func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) {
ctx.GasMeter().ConsumeGas(sdk.Gas(101), "testing")
return nil, [][]byte{[]byte("someData")}, nil
},
},
expData: []byte("myReplyData"),
expCommits: []bool{false},
},
"with gas limit - within limit no error": {
msgs: []wasmvmtypes.SubMsg{{
GasLimit: &anyGasLimit,
ReplyOn: wasmvmtypes.ReplyError,
}},
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) {
ctx.GasMeter().ConsumeGas(sdk.Gas(1), "testing")
return nil, [][]byte{[]byte("someData")}, nil
},
},
expCommits: []bool{true},
},
"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) {
return []byte(fmt.Sprintf("myReplyData:%d", reply.ID)), nil
},
},
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, nil, errors.New("my error")
},
},
expData: []byte("myReplyData:2"),
expCommits: []bool{false, false},
},
"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) {
if reply.ID == 2 {
return nil, nil
}
return []byte("myReplyData:1"), nil
},
},
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, nil, errors.New("my error")
},
},
expData: []byte("myReplyData:1"),
expCommits: []bool{false, false},
},
"multiple msg - empty reply can overwrite result": {
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) {
if reply.ID == 2 {
return []byte{}, nil
}
return []byte("myReplyData:1"), nil
},
},
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, nil, errors.New("my error")
},
},
expData: []byte{},
expCommits: []bool{false, false},
},
"message event filtered without reply": {
msgs: []wasmvmtypes.SubMsg{{
ReplyOn: wasmvmtypes.ReplyNever,
}},
replyer: &mockReplyer{
replyFn: func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) ([]byte, error) {
return nil, errors.New("should never be called")
},
},
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{
sdk.NewEvent("message"),
sdk.NewEvent("execute", sdk.NewAttribute("foo", "bar")),
}
return myEvents, [][]byte{[]byte("myData")}, nil
},
},
expData: nil,
expCommits: []bool{true},
expEvents: []sdk.Event{sdk.NewEvent("execute", sdk.NewAttribute("foo", "bar"))},
},
"wasm reply gets proper events": {
// put fake wasmmsg in here to show where it comes from
msgs: []wasmvmtypes.SubMsg{{ID: 1, ReplyOn: wasmvmtypes.ReplyAlways, Msg: wasmvmtypes.CosmosMsg{Wasm: &wasmvmtypes.WasmMsg{}}}},
replyer: &mockReplyer{
replyFn: func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) ([]byte, error) {
if reply.Result.Err != "" {
return nil, errors.New(reply.Result.Err)
}
res := reply.Result.Ok
// ensure the input events are what we expect
// I didn't use require.Equal() to act more like a contract... but maybe that would be better
if len(res.Events) != 2 {
return nil, fmt.Errorf("event count: %#v", res.Events)
}
if res.Events[0].Type != "execute" {
return nil, fmt.Errorf("event0: %#v", res.Events[0])
}
if res.Events[1].Type != "wasm" {
return nil, fmt.Errorf("event1: %#v", res.Events[1])
}
// let's add a custom event here and see if it makes it out
ctx.EventManager().EmitEvent(sdk.NewEvent("wasm-reply"))
// update data from what we got in
return res.Data, nil
},
},
msgHandler: &wasmtesting.MockMessageHandler{
DispatchMsgFn: func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) {
events = []sdk.Event{
sdk.NewEvent("message", sdk.NewAttribute("_contract_address", contractAddr.String())),
// we don't know what the contarctAddr will be so we can't use it in the final tests
sdk.NewEvent("execute", sdk.NewAttribute("_contract_address", "placeholder-random-addr")),
sdk.NewEvent("wasm", sdk.NewAttribute("random", "data")),
}
return events, [][]byte{[]byte("subData")}, nil
},
},
expData: []byte("subData"),
expCommits: []bool{true},
expEvents: []sdk.Event{
sdk.NewEvent("execute", sdk.NewAttribute("_contract_address", "placeholder-random-addr")),
sdk.NewEvent("wasm", sdk.NewAttribute("random", "data")),
sdk.NewEvent("wasm-reply"),
},
},
"non-wasm reply events get filtered": {
// show events from a stargate message gets filtered out
msgs: []wasmvmtypes.SubMsg{{ID: 1, ReplyOn: wasmvmtypes.ReplyAlways, Msg: wasmvmtypes.CosmosMsg{Stargate: &wasmvmtypes.StargateMsg{}}}},
replyer: &mockReplyer{
replyFn: func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) ([]byte, error) {
if reply.Result.Err != "" {
return nil, errors.New(reply.Result.Err)
}
res := reply.Result.Ok
// ensure the input events are what we expect
// I didn't use require.Equal() to act more like a contract... but maybe that would be better
if len(res.Events) != 0 {
return nil, errors.New("events not filtered out")
}
// let's add a custom event here and see if it makes it out
ctx.EventManager().EmitEvent(sdk.NewEvent("stargate-reply"))
// update data from what we got in
return res.Data, nil
},
},
msgHandler: &wasmtesting.MockMessageHandler{
DispatchMsgFn: func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) {
events = []sdk.Event{
// this is filtered out
sdk.NewEvent("message", sdk.NewAttribute("stargate", "something-something")),
// we still emit this to the client, but not the contract
sdk.NewEvent("non-determinstic"),
}
return events, [][]byte{[]byte("subData")}, nil
},
},
expData: []byte("subData"),
expCommits: []bool{true},
expEvents: []sdk.Event{
sdk.NewEvent("non-determinstic"),
// the event from reply is also exposed
sdk.NewEvent("stargate-reply"),
},
},
}
for name, spec := range specs {
t.Run(name, func(t *testing.T) {
var mockStore wasmtesting.MockCommitMultiStore
em := sdk.NewEventManager()
ctx := sdk.Context{}.WithMultiStore(&mockStore).
WithGasMeter(sdk.NewGasMeter(100)).
WithEventManager(em).WithLogger(log.TestingLogger())
d := NewMessageDispatcher(spec.msgHandler, spec.replyer)
// run the test
gotData, gotErr := d.DispatchSubmessages(ctx, RandomAccountAddress(t), "any_port", spec.msgs)
if spec.expErr {
require.Error(t, gotErr)
assert.Empty(t, em.Events())
return
}
// if we don't expect an error, we should get no error
require.NoError(t, gotErr)
assert.Equal(t, spec.expData, gotData)
// ensure the commits are what we expect
assert.Equal(t, spec.expCommits, mockStore.Committed)
if len(spec.expEvents) == 0 {
assert.Empty(t, em.Events())
} else {
assert.Equal(t, spec.expEvents, em.Events())
}
})
}
}
type mockReplyer struct {
replyFn func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) ([]byte, error)
}
func (m mockReplyer) reply(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) ([]byte, error) {
if m.replyFn == nil {
panic("not expected to be called")
}
return m.replyFn(ctx, contractAddress, reply)
}