11
EVENTS.md
11
EVENTS.md
@@ -402,6 +402,17 @@ If the original contract execution example above was actually the result of a me
|
||||
and it registered a ReplyOn clause, the `reply` function on that contract would receive the entire 11 events in the example
|
||||
above, and would need to use the `message` markers to locate the segment of interest.
|
||||
|
||||
## Governance Events
|
||||
The governance process is handled by the cosmos-sdk `gov` module. We do not emit any events of type "message" anymore in v0.18+.
|
||||
Context-specific events are emitted as described above. `Execution` and `Migration` return some contract result though that are
|
||||
emitted as:
|
||||
```go
|
||||
sdk.NewEvent(
|
||||
"gov_contract_result",
|
||||
sdk.NewAttribute("result", hex.EncodeToString(data)),
|
||||
)
|
||||
```
|
||||
|
||||
## IBC Events
|
||||
|
||||
TODO: define what the default SDK messages are here and what we add to our custom keeper events.
|
||||
@@ -21,20 +21,6 @@ func newWasmModuleEvent(customAttributes []wasmvmtypes.EventAttribute, contractA
|
||||
return sdk.Events{sdk.NewEvent(types.WasmModuleEventType, attrs...)}, nil
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
@@ -251,3 +251,17 @@ func TestNewWasmModuleEvent(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ import (
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
"math"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -178,6 +180,16 @@ func (k Keeper) create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte,
|
||||
}
|
||||
codeInfo := types.NewCodeInfo(checksum, creator, *instantiateAccess)
|
||||
k.storeCodeInfo(ctx, codeID, codeInfo)
|
||||
|
||||
evt := sdk.NewEvent(
|
||||
types.EventTypeStoreCode,
|
||||
sdk.NewAttribute(types.AttributeKeyCodeID, strconv.FormatUint(codeID, 10)),
|
||||
)
|
||||
for _, f := range strings.Split(report.RequiredFeatures, ",") {
|
||||
evt.AppendAttributes(sdk.NewAttribute(types.AttributeKeyFeature, strings.TrimSpace(f)))
|
||||
}
|
||||
ctx.EventManager().EmitEvent(evt)
|
||||
|
||||
return codeID, nil
|
||||
}
|
||||
|
||||
@@ -293,7 +305,12 @@ func (k Keeper) instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.A
|
||||
k.appendToContractHistory(ctx, contractAddress, historyEntry)
|
||||
k.storeContractInfo(ctx, contractAddress, &contractInfo)
|
||||
|
||||
// dispatch submessages then messages
|
||||
ctx.EventManager().EmitEvent(sdk.NewEvent(
|
||||
types.EventTypeInstantiate,
|
||||
sdk.NewAttribute(types.AttributeKeyContractAddr, contractAddress.String()),
|
||||
sdk.NewAttribute(types.AttributeKeyCodeID, strconv.FormatUint(codeID, 10)),
|
||||
))
|
||||
|
||||
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")
|
||||
@@ -332,11 +349,16 @@ func (k Keeper) execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller
|
||||
return nil, sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error())
|
||||
}
|
||||
|
||||
// dispatch submessages then messages
|
||||
ctx.EventManager().EmitEvent(sdk.NewEvent(
|
||||
types.EventTypeExecute,
|
||||
sdk.NewAttribute(types.AttributeKeyContractAddr, contractAddress.String()),
|
||||
))
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
@@ -396,11 +418,17 @@ func (k Keeper) migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller
|
||||
k.addToContractCodeSecondaryIndex(ctx, contractAddress, historyEntry)
|
||||
k.storeContractInfo(ctx, contractAddress, contractInfo)
|
||||
|
||||
// dispatch submessages then messages
|
||||
ctx.EventManager().EmitEvent(sdk.NewEvent(
|
||||
types.EventTypeMigrate,
|
||||
sdk.NewAttribute(types.AttributeKeyCodeID, strconv.FormatUint(newCodeID, 10)),
|
||||
sdk.NewAttribute(types.AttributeKeyContractAddr, contractAddress.String()),
|
||||
))
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
@@ -428,11 +456,16 @@ func (k Keeper) Sudo(ctx sdk.Context, contractAddress sdk.AccAddress, msg []byte
|
||||
return nil, sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error())
|
||||
}
|
||||
|
||||
// dispatch submessages then messages
|
||||
ctx.EventManager().EmitEvent(sdk.NewEvent(
|
||||
types.EventTypeSudo,
|
||||
sdk.NewAttribute(types.AttributeKeyContractAddr, contractAddress.String()),
|
||||
))
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
@@ -461,11 +494,16 @@ func (k Keeper) reply(ctx sdk.Context, contractAddress sdk.AccAddress, reply was
|
||||
return nil, sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error())
|
||||
}
|
||||
|
||||
// dispatch submessages then messages
|
||||
ctx.EventManager().EmitEvent(sdk.NewEvent(
|
||||
types.EventTypeReply,
|
||||
sdk.NewAttribute(types.AttributeKeyContractAddr, contractAddress.String()),
|
||||
))
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
@@ -709,6 +747,11 @@ func (k Keeper) pinCode(ctx sdk.Context, codeID uint64) error {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
// store 1 byte to not run into `nil` debugging issues
|
||||
store.Set(types.GetPinnedCodeIndexPrefix(codeID), []byte{1})
|
||||
|
||||
ctx.EventManager().EmitEvent(sdk.NewEvent(
|
||||
types.EventTypePinCode,
|
||||
sdk.NewAttribute(types.AttributeKeyCodeID, strconv.FormatUint(codeID, 10)),
|
||||
))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -724,6 +767,11 @@ func (k Keeper) unpinCode(ctx sdk.Context, codeID uint64) error {
|
||||
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store.Delete(types.GetPinnedCodeIndexPrefix(codeID))
|
||||
|
||||
ctx.EventManager().EmitEvent(sdk.NewEvent(
|
||||
types.EventTypeUnpinCode,
|
||||
sdk.NewAttribute(types.AttributeKeyCodeID, strconv.FormatUint(codeID, 10)),
|
||||
))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -775,7 +823,7 @@ func (k *Keeper) handleContractResponse(
|
||||
attributeGasCost := k.gasRegister.EventCosts(attrs, evts)
|
||||
ctx.GasMeter().ConsumeGas(attributeGasCost, "Custom contract event attributes")
|
||||
// emit all events from this contract itself
|
||||
if len(attrs) != 0 || !hasWasmModuleEvent(ctx, contractAddr) {
|
||||
if len(attrs) != 0 {
|
||||
wasmEvents, err := newWasmModuleEvent(attrs, contractAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -985,7 +1033,9 @@ func NewBankCoinTransferrer(keeper types.BankKeeper) BankCoinTransferrer {
|
||||
|
||||
// TransferCoins transfers coins from source to destination account when coin send was enabled for them and the recipient
|
||||
// is not in the blocked address list.
|
||||
func (c BankCoinTransferrer) TransferCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error {
|
||||
func (c BankCoinTransferrer) TransferCoins(parentCtx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error {
|
||||
em := sdk.NewEventManager()
|
||||
ctx := parentCtx.WithEventManager(em)
|
||||
if err := c.keeper.SendEnabledCoins(ctx, amt...); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -996,6 +1046,12 @@ func (c BankCoinTransferrer) TransferCoins(ctx sdk.Context, fromAddr sdk.AccAddr
|
||||
if sdkerr != nil {
|
||||
return sdkerr
|
||||
}
|
||||
for _, e := range em.Events() {
|
||||
if e.Type == sdk.EventTypeMessage { // skip messages as we talk to the keeper directly
|
||||
continue
|
||||
}
|
||||
parentCtx.EventManager().EmitEvent(e)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1016,12 +1072,19 @@ 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, messages []wasmvmtypes.SubMsg, origRspData []byte) ([]byte, error) {
|
||||
em := sdk.NewEventManager()
|
||||
result := origRspData
|
||||
switch rsp, err := h.md.DispatchSubmessages(ctx, contractAddr, ibcPort, messages); {
|
||||
switch rsp, err := h.md.DispatchSubmessages(ctx.WithEventManager(em), contractAddr, ibcPort, messages); {
|
||||
case err != nil:
|
||||
return nil, sdkerrors.Wrap(err, "submessages")
|
||||
case rsp != nil:
|
||||
result = rsp
|
||||
}
|
||||
// emit non message type events only
|
||||
for _, e := range em.Events() {
|
||||
if e.Type != sdk.EventTypeMessage {
|
||||
ctx.EventManager().EmitEvent(e)
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
@@ -40,13 +40,17 @@ func TestCreate(t *testing.T) {
|
||||
wasmCode, err := ioutil.ReadFile("./testdata/hackatom.wasm")
|
||||
require.NoError(t, err)
|
||||
|
||||
contractID, err := keeper.Create(ctx, creator, wasmCode, nil)
|
||||
em := sdk.NewEventManager()
|
||||
codeID, err := keeper.Create(ctx.WithEventManager(em), creator, wasmCode, nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(1), contractID)
|
||||
require.Equal(t, uint64(1), codeID)
|
||||
// and verify content
|
||||
storedCode, err := keepers.WasmKeeper.GetByteCode(ctx, contractID)
|
||||
storedCode, err := keepers.WasmKeeper.GetByteCode(ctx, codeID)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, wasmCode, storedCode)
|
||||
// and events emitted
|
||||
exp := sdk.Events{sdk.NewEvent("store_code", sdk.NewAttribute("code_id", "1"))}
|
||||
assert.Equal(t, exp, em.Events())
|
||||
}
|
||||
|
||||
func TestCreateStoresInstantiatePermission(t *testing.T) {
|
||||
@@ -277,8 +281,9 @@ func TestInstantiate(t *testing.T) {
|
||||
|
||||
gasBefore := ctx.GasMeter().GasConsumed()
|
||||
|
||||
em := sdk.NewEventManager()
|
||||
// create with no balance is also legal
|
||||
gotContractAddr, _, err := keepers.ContractKeeper.Instantiate(ctx, codeID, creator, nil, initMsgBz, "demo contract 1", nil)
|
||||
gotContractAddr, _, err := keepers.ContractKeeper.Instantiate(ctx.WithEventManager(em), codeID, creator, nil, initMsgBz, "demo contract 1", nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "cosmos14hj2tavq8fpesdwxxcu44rty3hh90vhuc53mp6", gotContractAddr.String())
|
||||
|
||||
@@ -301,6 +306,15 @@ func TestInstantiate(t *testing.T) {
|
||||
Msg: json.RawMessage(initMsgBz),
|
||||
}}
|
||||
assert.Equal(t, exp, keepers.WasmKeeper.GetContractHistory(ctx, gotContractAddr))
|
||||
|
||||
// and events emitted
|
||||
expEvt := sdk.Events{
|
||||
sdk.NewEvent("instantiate",
|
||||
sdk.NewAttribute("_contract_address", gotContractAddr.String()), sdk.NewAttribute("code_id", "1")),
|
||||
sdk.NewEvent("wasm",
|
||||
sdk.NewAttribute("_contract_address", gotContractAddr.String()), sdk.NewAttribute("Let the", "hacking begin")),
|
||||
}
|
||||
assert.Equal(t, expEvt, em.Events())
|
||||
}
|
||||
|
||||
func TestInstantiateWithDeposit(t *testing.T) {
|
||||
@@ -508,8 +522,9 @@ func TestExecute(t *testing.T) {
|
||||
// verifier can execute, and get proper gas amount
|
||||
start := time.Now()
|
||||
gasBefore := ctx.GasMeter().GasConsumed()
|
||||
|
||||
res, err = keepers.ContractKeeper.Execute(ctx, addr, fred, []byte(`{"release":{}}`), topUp)
|
||||
em := sdk.NewEventManager()
|
||||
// when
|
||||
res, err = keepers.ContractKeeper.Execute(ctx.WithEventManager(em), addr, fred, []byte(`{"release":{}}`), topUp)
|
||||
diff := time.Now().Sub(start)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, res)
|
||||
@@ -530,6 +545,12 @@ func TestExecute(t *testing.T) {
|
||||
require.NotNil(t, contractAcct)
|
||||
assert.Equal(t, sdk.Coins(nil), bankKeeper.GetAllBalances(ctx, contractAcct.GetAddress()))
|
||||
|
||||
// and events emitted
|
||||
require.Len(t, em.Events(), 5)
|
||||
expEvt := sdk.NewEvent("execute",
|
||||
sdk.NewAttribute("_contract_address", addr.String()))
|
||||
assert.Equal(t, expEvt, em.Events()[1])
|
||||
|
||||
t.Logf("Duration: %v (%d gas)\n", diff, gasAfter-gasBefore)
|
||||
}
|
||||
|
||||
@@ -1014,6 +1035,13 @@ func TestMigrateWithDispatchedMessage(t *testing.T) {
|
||||
assert.Equal(t, "burnt 1 keys", string(data))
|
||||
type dict map[string]interface{}
|
||||
expEvents := []dict{
|
||||
{
|
||||
"Type": "migrate",
|
||||
"Attr": []dict{
|
||||
{"code_id": "2"},
|
||||
{"_contract_address": contractAddr},
|
||||
},
|
||||
},
|
||||
{
|
||||
"Type": "wasm",
|
||||
"Attr": []dict{
|
||||
@@ -1030,21 +1058,9 @@ func TestMigrateWithDispatchedMessage(t *testing.T) {
|
||||
{"amount": "100000denom"},
|
||||
},
|
||||
},
|
||||
{
|
||||
"Type": "message",
|
||||
"Attr": []dict{
|
||||
{"sender": contractAddr},
|
||||
},
|
||||
},
|
||||
{
|
||||
"Type": "message",
|
||||
"Attr": []dict{
|
||||
{"module": "bank"},
|
||||
},
|
||||
},
|
||||
}
|
||||
expJSONEvts := string(mustMarshal(t, expEvents))
|
||||
assert.JSONEq(t, expJSONEvts, prettyEvents(t, ctx.EventManager().Events()))
|
||||
assert.JSONEq(t, expJSONEvts, prettyEvents(t, ctx.EventManager().Events()), prettyEvents(t, ctx.EventManager().Events()))
|
||||
|
||||
// all persistent data cleared
|
||||
m := keepers.WasmKeeper.QueryRaw(ctx, contractAddr, []byte("config"))
|
||||
@@ -1160,7 +1176,6 @@ func TestSudo(t *testing.T) {
|
||||
}
|
||||
initMsgBz, err := json.Marshal(initMsg)
|
||||
require.NoError(t, err)
|
||||
|
||||
addr, _, err := keepers.ContractKeeper.Instantiate(ctx, contractID, creator, nil, initMsgBz, "demo contract 3", deposit)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "cosmos14hj2tavq8fpesdwxxcu44rty3hh90vhuc53mp6", addr.String())
|
||||
@@ -1183,7 +1198,10 @@ func TestSudo(t *testing.T) {
|
||||
sudoMsg, err := json.Marshal(msg)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = keepers.WasmKeeper.Sudo(ctx, addr, sudoMsg)
|
||||
em := sdk.NewEventManager()
|
||||
|
||||
// when
|
||||
_, err = keepers.WasmKeeper.Sudo(ctx.WithEventManager(em), addr, sudoMsg)
|
||||
require.NoError(t, err)
|
||||
|
||||
// ensure community now exists and got paid
|
||||
@@ -1191,6 +1209,12 @@ func TestSudo(t *testing.T) {
|
||||
require.NotNil(t, comAcct)
|
||||
balance := bankKeeper.GetBalance(ctx, comAcct.GetAddress(), "denom")
|
||||
assert.Equal(t, sdk.NewInt64Coin("denom", 76543), balance)
|
||||
// and events emitted
|
||||
require.Len(t, em.Events(), 2)
|
||||
expEvt := sdk.NewEvent("sudo",
|
||||
sdk.NewAttribute("_contract_address", addr.String()))
|
||||
assert.Equal(t, expEvt, em.Events()[0])
|
||||
|
||||
}
|
||||
|
||||
func prettyEvents(t *testing.T, events sdk.Events) string {
|
||||
@@ -1355,6 +1379,66 @@ func TestClearContractAdmin(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPinCode(t *testing.T) {
|
||||
ctx, keepers := CreateTestInput(t, false, SupportedFeatures)
|
||||
k := keepers.WasmKeeper
|
||||
|
||||
var capturedChecksums []wasmvm.Checksum
|
||||
mock := wasmtesting.MockWasmer{PinFn: func(checksum wasmvm.Checksum) error {
|
||||
capturedChecksums = append(capturedChecksums, checksum)
|
||||
return nil
|
||||
}}
|
||||
wasmtesting.MakeInstantiable(&mock)
|
||||
myCodeID := StoreRandomContract(t, ctx, keepers, &mock).CodeID
|
||||
require.Equal(t, uint64(1), myCodeID)
|
||||
em := sdk.NewEventManager()
|
||||
|
||||
// when
|
||||
gotErr := k.pinCode(ctx.WithEventManager(em), myCodeID)
|
||||
|
||||
// then
|
||||
require.NoError(t, gotErr)
|
||||
assert.NotEmpty(t, capturedChecksums)
|
||||
assert.True(t, k.IsPinnedCode(ctx, myCodeID))
|
||||
|
||||
// and events
|
||||
exp := sdk.Events{sdk.NewEvent("pin_code", sdk.NewAttribute("code_id", "1"))}
|
||||
assert.Equal(t, exp, em.Events())
|
||||
}
|
||||
|
||||
func TestUnpinCode(t *testing.T) {
|
||||
ctx, keepers := CreateTestInput(t, false, SupportedFeatures)
|
||||
k := keepers.WasmKeeper
|
||||
|
||||
var capturedChecksums []wasmvm.Checksum
|
||||
mock := wasmtesting.MockWasmer{
|
||||
PinFn: func(checksum wasmvm.Checksum) error {
|
||||
return nil
|
||||
},
|
||||
UnpinFn: func(checksum wasmvm.Checksum) error {
|
||||
capturedChecksums = append(capturedChecksums, checksum)
|
||||
return nil
|
||||
}}
|
||||
wasmtesting.MakeInstantiable(&mock)
|
||||
myCodeID := StoreRandomContract(t, ctx, keepers, &mock).CodeID
|
||||
require.Equal(t, uint64(1), myCodeID)
|
||||
err := k.pinCode(ctx, myCodeID)
|
||||
require.NoError(t, err)
|
||||
em := sdk.NewEventManager()
|
||||
|
||||
// when
|
||||
gotErr := k.unpinCode(ctx.WithEventManager(em), myCodeID)
|
||||
|
||||
// then
|
||||
require.NoError(t, gotErr)
|
||||
assert.NotEmpty(t, capturedChecksums)
|
||||
assert.False(t, k.IsPinnedCode(ctx, myCodeID))
|
||||
|
||||
// and events
|
||||
exp := sdk.Events{sdk.NewEvent("unpin_code", sdk.NewAttribute("code_id", "1"))}
|
||||
assert.Equal(t, exp, em.Events())
|
||||
}
|
||||
|
||||
func TestInitializePinnedCodes(t *testing.T) {
|
||||
ctx, keepers := CreateTestInput(t, false, SupportedFeatures)
|
||||
k := keepers.WasmKeeper
|
||||
@@ -1364,7 +1448,7 @@ func TestInitializePinnedCodes(t *testing.T) {
|
||||
capturedChecksums = append(capturedChecksums, checksum)
|
||||
return nil
|
||||
}}
|
||||
wasmtesting.MakeIBCInstantiable(&mock)
|
||||
wasmtesting.MakeInstantiable(&mock)
|
||||
|
||||
const testItems = 3
|
||||
myCodeIDs := make([]uint64, testItems)
|
||||
@@ -1436,6 +1520,7 @@ func TestNewDefaultWasmVMContractResponseHandler(t *testing.T) {
|
||||
setup func(m *wasmtesting.MockMsgDispatcher)
|
||||
expErr bool
|
||||
expData []byte
|
||||
expEvts sdk.Events
|
||||
}{
|
||||
"submessage overwrites result when set": {
|
||||
srcData: []byte("otherData"),
|
||||
@@ -1446,6 +1531,7 @@ func TestNewDefaultWasmVMContractResponseHandler(t *testing.T) {
|
||||
},
|
||||
expErr: false,
|
||||
expData: []byte("mySubMsgData"),
|
||||
expEvts: sdk.Events{},
|
||||
},
|
||||
"submessage overwrites result when empty": {
|
||||
srcData: []byte("otherData"),
|
||||
@@ -1456,6 +1542,7 @@ func TestNewDefaultWasmVMContractResponseHandler(t *testing.T) {
|
||||
},
|
||||
expErr: false,
|
||||
expData: []byte(""),
|
||||
expEvts: sdk.Events{},
|
||||
},
|
||||
"submessage do not overwrite result when nil": {
|
||||
srcData: []byte("otherData"),
|
||||
@@ -1466,6 +1553,7 @@ func TestNewDefaultWasmVMContractResponseHandler(t *testing.T) {
|
||||
},
|
||||
expErr: false,
|
||||
expData: []byte("otherData"),
|
||||
expEvts: sdk.Events{},
|
||||
},
|
||||
"submessage error aborts process": {
|
||||
setup: func(m *wasmtesting.MockMsgDispatcher) {
|
||||
@@ -1475,6 +1563,24 @@ func TestNewDefaultWasmVMContractResponseHandler(t *testing.T) {
|
||||
},
|
||||
expErr: true,
|
||||
},
|
||||
"message events filtered out": {
|
||||
setup: func(m *wasmtesting.MockMsgDispatcher) {
|
||||
m.DispatchSubmessagesFn = func(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.SubMsg) ([]byte, error) {
|
||||
ctx.EventManager().EmitEvent(sdk.NewEvent(sdk.EventTypeMessage))
|
||||
return nil, nil
|
||||
}
|
||||
},
|
||||
expEvts: sdk.Events{},
|
||||
},
|
||||
"message emit non message events": {
|
||||
setup: func(m *wasmtesting.MockMsgDispatcher) {
|
||||
m.DispatchSubmessagesFn = func(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.SubMsg) ([]byte, error) {
|
||||
ctx.EventManager().EmitEvent(sdk.NewEvent("myEvent"))
|
||||
return nil, nil
|
||||
}
|
||||
},
|
||||
expEvts: sdk.Events{sdk.NewEvent("myEvent")},
|
||||
},
|
||||
}
|
||||
for name, spec := range specs {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
@@ -1484,15 +1590,60 @@ func TestNewDefaultWasmVMContractResponseHandler(t *testing.T) {
|
||||
var mock wasmtesting.MockMsgDispatcher
|
||||
spec.setup(&mock)
|
||||
d := NewDefaultWasmVMContractResponseHandler(&mock)
|
||||
// when
|
||||
em := sdk.NewEventManager()
|
||||
|
||||
gotData, gotErr := d.Handle(sdk.Context{}, RandomAccountAddress(t), "ibc-port", msgs, spec.srcData)
|
||||
// when
|
||||
gotData, gotErr := d.Handle(sdk.Context{}.WithEventManager(em), RandomAccountAddress(t), "ibc-port", msgs, spec.srcData)
|
||||
if spec.expErr {
|
||||
require.Error(t, gotErr)
|
||||
return
|
||||
}
|
||||
require.NoError(t, gotErr)
|
||||
assert.Equal(t, spec.expData, gotData)
|
||||
assert.Equal(t, spec.expEvts, em.Events())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestReply(t *testing.T) {
|
||||
ctx, keepers := CreateTestInput(t, false, SupportedFeatures)
|
||||
k := keepers.WasmKeeper
|
||||
var mock wasmtesting.MockWasmer
|
||||
wasmtesting.MakeInstantiable(&mock)
|
||||
example := SeedNewContractInstance(t, ctx, keepers, &mock)
|
||||
|
||||
specs := map[string]struct {
|
||||
rsp wasmvmtypes.Response
|
||||
expData []byte
|
||||
expErr bool
|
||||
expEvt sdk.Events
|
||||
}{
|
||||
"all good": {
|
||||
rsp: wasmvmtypes.Response{Data: []byte("foo")},
|
||||
expData: []byte("foo"),
|
||||
expEvt: sdk.Events{sdk.NewEvent("reply", sdk.NewAttribute("_contract_address", example.Contract.String()))},
|
||||
},
|
||||
"error": {
|
||||
expErr: true,
|
||||
},
|
||||
}
|
||||
for name, spec := range specs {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
mock.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) {
|
||||
if spec.expErr {
|
||||
return nil, 1, errors.New("testing")
|
||||
}
|
||||
return &spec.rsp, 1, nil
|
||||
}
|
||||
em := sdk.NewEventManager()
|
||||
gotData, gotErr := k.reply(ctx.WithEventManager(em), example.Contract, wasmvmtypes.Reply{})
|
||||
if spec.expErr {
|
||||
require.Error(t, gotErr)
|
||||
return
|
||||
}
|
||||
require.NoError(t, gotErr)
|
||||
assert.Equal(t, spec.expData, gotData)
|
||||
assert.Equal(t, spec.expEvt, em.Events())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,6 @@ package keeper
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"github.com/CosmWasm/wasmd/x/wasm/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
@@ -25,18 +23,18 @@ func (m msgServer) StoreCode(goCtx context.Context, msg *types.MsgStoreCode) (*t
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(err, "sender")
|
||||
}
|
||||
codeID, err := m.keeper.Create(ctx, senderAddr, msg.WASMByteCode, msg.InstantiatePermission)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvent(sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Sender),
|
||||
sdk.NewAttribute(types.AttributeKeyCodeID, fmt.Sprintf("%d", codeID)),
|
||||
sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender),
|
||||
))
|
||||
|
||||
codeID, err := m.keeper.Create(ctx, senderAddr, msg.WASMByteCode, msg.InstantiatePermission)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.MsgStoreCodeResponse{
|
||||
CodeID: codeID,
|
||||
}, nil
|
||||
@@ -56,20 +54,17 @@ func (m msgServer) InstantiateContract(goCtx context.Context, msg *types.MsgInst
|
||||
}
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvent(sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
|
||||
sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender),
|
||||
))
|
||||
|
||||
contractAddr, data, err := m.keeper.Instantiate(ctx, msg.CodeID, senderAddr, adminAddr, msg.Msg, msg.Label, msg.Funds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvent(sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Sender),
|
||||
sdk.NewAttribute(types.AttributeKeyCodeID, fmt.Sprintf("%d", msg.CodeID)),
|
||||
sdk.NewAttribute(types.AttributeKeyContractAddr, contractAddr.String()),
|
||||
sdk.NewAttribute(types.AttributeResultDataHex, hex.EncodeToString(data)),
|
||||
))
|
||||
|
||||
return &types.MsgInstantiateContractResponse{
|
||||
Address: contractAddr.String(),
|
||||
Data: data,
|
||||
@@ -87,19 +82,17 @@ func (m msgServer) ExecuteContract(goCtx context.Context, msg *types.MsgExecuteC
|
||||
return nil, sdkerrors.Wrap(err, "contract")
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvent(sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
|
||||
sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender),
|
||||
))
|
||||
|
||||
data, err := m.keeper.Execute(ctx, contractAddr, senderAddr, msg.Msg, msg.Funds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvent(sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Sender),
|
||||
sdk.NewAttribute(types.AttributeKeyContractAddr, msg.Contract),
|
||||
sdk.NewAttribute(types.AttributeResultDataHex, hex.EncodeToString(data)),
|
||||
))
|
||||
|
||||
return &types.MsgExecuteContractResponse{
|
||||
Data: data,
|
||||
}, nil
|
||||
@@ -116,20 +109,17 @@ func (m msgServer) MigrateContract(goCtx context.Context, msg *types.MsgMigrateC
|
||||
return nil, sdkerrors.Wrap(err, "contract")
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvent(sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
|
||||
sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender),
|
||||
))
|
||||
|
||||
data, err := m.keeper.Migrate(ctx, contractAddr, senderAddr, msg.CodeID, msg.Msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvent(sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Sender),
|
||||
sdk.NewAttribute(types.AttributeKeyCodeID, fmt.Sprintf("%d", msg.CodeID)),
|
||||
sdk.NewAttribute(types.AttributeKeyContractAddr, msg.Contract),
|
||||
sdk.NewAttribute(types.AttributeResultDataHex, hex.EncodeToString(data)),
|
||||
))
|
||||
|
||||
return &types.MsgMigrateContractResponse{
|
||||
Data: data,
|
||||
}, nil
|
||||
@@ -150,17 +140,16 @@ func (m msgServer) UpdateAdmin(goCtx context.Context, msg *types.MsgUpdateAdmin)
|
||||
return nil, sdkerrors.Wrap(err, "new admin")
|
||||
}
|
||||
|
||||
if err := m.keeper.UpdateContractAdmin(ctx, contractAddr, senderAddr, newAdminAddr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvent(sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Sender),
|
||||
sdk.NewAttribute(types.AttributeKeyContractAddr, msg.Contract),
|
||||
sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender),
|
||||
))
|
||||
|
||||
if err := m.keeper.UpdateContractAdmin(ctx, contractAddr, senderAddr, newAdminAddr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.MsgUpdateAdminResponse{}, nil
|
||||
}
|
||||
|
||||
@@ -175,16 +164,15 @@ func (m msgServer) ClearAdmin(goCtx context.Context, msg *types.MsgClearAdmin) (
|
||||
return nil, sdkerrors.Wrap(err, "contract")
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvent(sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
|
||||
sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender),
|
||||
))
|
||||
|
||||
if err := m.keeper.ClearContractAdmin(ctx, contractAddr, senderAddr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvent(sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Sender),
|
||||
sdk.NewAttribute(types.AttributeKeyContractAddr, msg.Contract),
|
||||
))
|
||||
|
||||
return &types.MsgClearAdminResponse{}, nil
|
||||
}
|
||||
|
||||
@@ -2,12 +2,10 @@ package keeper
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"github.com/CosmWasm/wasmd/x/wasm/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// NewWasmProposalHandler creates a new governance Handler for wasm proposals
|
||||
@@ -58,18 +56,8 @@ func handleStoreCodeProposal(ctx sdk.Context, k types.ContractOpsKeeper, p types
|
||||
if err != nil {
|
||||
return sdkerrors.Wrap(err, "run as address")
|
||||
}
|
||||
codeID, err := k.Create(ctx, runAsAddr, p.WASMByteCode, p.InstantiatePermission)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ourEvent := sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
|
||||
sdk.NewAttribute(types.AttributeKeyCodeID, fmt.Sprintf("%d", codeID)),
|
||||
)
|
||||
ctx.EventManager().EmitEvent(ourEvent)
|
||||
return nil
|
||||
_, err = k.Create(ctx, runAsAddr, p.WASMByteCode, p.InstantiatePermission)
|
||||
return err
|
||||
}
|
||||
|
||||
func handleInstantiateProposal(ctx sdk.Context, k types.ContractOpsKeeper, p types.InstantiateContractProposal) error {
|
||||
@@ -85,19 +73,15 @@ func handleInstantiateProposal(ctx sdk.Context, k types.ContractOpsKeeper, p typ
|
||||
return sdkerrors.Wrap(err, "admin")
|
||||
}
|
||||
|
||||
contractAddr, data, err := k.Instantiate(ctx, p.CodeID, runAsAddr, adminAddr, p.Msg, p.Label, p.Funds)
|
||||
_, data, err := k.Instantiate(ctx, p.CodeID, runAsAddr, adminAddr, p.Msg, p.Label, p.Funds)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ourEvent := sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
|
||||
sdk.NewAttribute(types.AttributeKeyCodeID, fmt.Sprintf("%d", p.CodeID)),
|
||||
sdk.NewAttribute(types.AttributeKeyContractAddr, contractAddr.String()),
|
||||
sdk.NewAttribute(types.AttributeResultDataHex, hex.EncodeToString(data)),
|
||||
)
|
||||
ctx.EventManager().EmitEvent(ourEvent)
|
||||
ctx.EventManager().EmitEvent(sdk.NewEvent(
|
||||
types.EventTypeGovContractResult,
|
||||
sdk.NewAttribute(types.AttributeKeyResultDataHex, hex.EncodeToString(data)),
|
||||
))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -119,14 +103,10 @@ func handleMigrateProposal(ctx sdk.Context, k types.ContractOpsKeeper, p types.M
|
||||
return err
|
||||
}
|
||||
|
||||
ourEvent := sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
|
||||
sdk.NewAttribute(types.AttributeKeyCodeID, fmt.Sprintf("%d", p.CodeID)),
|
||||
sdk.NewAttribute(types.AttributeKeyContractAddr, p.Contract),
|
||||
sdk.NewAttribute(types.AttributeResultDataHex, hex.EncodeToString(data)),
|
||||
)
|
||||
ctx.EventManager().EmitEvent(ourEvent)
|
||||
ctx.EventManager().EmitEvent(sdk.NewEvent(
|
||||
types.EventTypeGovContractResult,
|
||||
sdk.NewAttribute(types.AttributeKeyResultDataHex, hex.EncodeToString(data)),
|
||||
))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -143,17 +123,7 @@ func handleUpdateAdminProposal(ctx sdk.Context, k types.ContractOpsKeeper, p typ
|
||||
return sdkerrors.Wrap(err, "run as address")
|
||||
}
|
||||
|
||||
if err := k.UpdateContractAdmin(ctx, contractAddr, nil, newAdminAddr); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ourEvent := sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
|
||||
sdk.NewAttribute(types.AttributeKeyContractAddr, p.Contract),
|
||||
)
|
||||
ctx.EventManager().EmitEvent(ourEvent)
|
||||
return nil
|
||||
return k.UpdateContractAdmin(ctx, contractAddr, nil, newAdminAddr)
|
||||
}
|
||||
|
||||
func handleClearAdminProposal(ctx sdk.Context, k types.ContractOpsKeeper, p types.ClearAdminProposal) error {
|
||||
@@ -168,12 +138,6 @@ func handleClearAdminProposal(ctx sdk.Context, k types.ContractOpsKeeper, p type
|
||||
if err := k.ClearContractAdmin(ctx, contractAddr, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
ourEvent := sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
|
||||
sdk.NewAttribute(types.AttributeKeyContractAddr, p.Contract),
|
||||
)
|
||||
ctx.EventManager().EmitEvent(ourEvent)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -186,14 +150,6 @@ func handlePinCodesProposal(ctx sdk.Context, k types.ContractOpsKeeper, p types.
|
||||
return sdkerrors.Wrapf(err, "code id: %d", v)
|
||||
}
|
||||
}
|
||||
for _, v := range p.CodeIDs {
|
||||
ourEvent := sdk.NewEvent(
|
||||
types.EventTypePinCode,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
|
||||
sdk.NewAttribute(types.AttributeKeyCodeID, strconv.FormatUint(v, 10)),
|
||||
)
|
||||
ctx.EventManager().EmitEvent(ourEvent)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -206,13 +162,5 @@ func handleUnpinCodesProposal(ctx sdk.Context, k types.ContractOpsKeeper, p type
|
||||
return sdkerrors.Wrapf(err, "code id: %d", v)
|
||||
}
|
||||
}
|
||||
for _, v := range p.CodeIDs {
|
||||
ourEvent := sdk.NewEvent(
|
||||
types.EventTypeUnpinCode,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
|
||||
sdk.NewAttribute(types.AttributeKeyCodeID, strconv.FormatUint(v, 10)),
|
||||
)
|
||||
ctx.EventManager().EmitEvent(ourEvent)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -111,8 +111,12 @@ func TestInstantiateProposal(t *testing.T) {
|
||||
}}
|
||||
assert.Equal(t, expHistory, wasmKeeper.GetContractHistory(ctx, contractAddr))
|
||||
// and event
|
||||
require.Len(t, em.Events(), 2, "%#v", em.Events())
|
||||
require.Len(t, em.Events()[1].Attributes, 4)
|
||||
require.Len(t, em.Events(), 3, "%#v", em.Events())
|
||||
require.Equal(t, types.EventTypeInstantiate, em.Events()[0].Type)
|
||||
require.Equal(t, types.WasmModuleEventType, em.Events()[1].Type)
|
||||
require.Equal(t, types.EventTypeGovContractResult, em.Events()[2].Type)
|
||||
require.Len(t, em.Events()[2].Attributes, 1)
|
||||
require.NotEmpty(t, em.Events()[2].Attributes[0])
|
||||
}
|
||||
|
||||
func TestMigrateProposal(t *testing.T) {
|
||||
@@ -192,7 +196,10 @@ func TestMigrateProposal(t *testing.T) {
|
||||
assert.Equal(t, expHistory, wasmKeeper.GetContractHistory(ctx, contractAddr))
|
||||
// and events emitted
|
||||
require.Len(t, em.Events(), 2)
|
||||
require.Len(t, em.Events()[1].Attributes, 4)
|
||||
assert.Equal(t, types.EventTypeMigrate, em.Events()[0].Type)
|
||||
require.Equal(t, types.EventTypeGovContractResult, em.Events()[1].Type)
|
||||
require.Len(t, em.Events()[1].Attributes, 1)
|
||||
assert.Equal(t, types.AttributeKeyResultDataHex, string(em.Events()[1].Attributes[0].Key))
|
||||
}
|
||||
|
||||
func TestAdminProposals(t *testing.T) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/CosmWasm/wasmd/x/wasm/keeper/wasmtesting"
|
||||
"github.com/CosmWasm/wasmd/x/wasm/types"
|
||||
wasmvm "github.com/CosmWasm/wasmvm"
|
||||
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
@@ -92,14 +93,13 @@ func TestOnConnectChannel(t *testing.T) {
|
||||
const myContractGas = 40
|
||||
|
||||
specs := map[string]struct {
|
||||
contractAddr sdk.AccAddress
|
||||
contractResp *wasmvmtypes.IBCBasicResponse
|
||||
contractErr error
|
||||
overwriteMessenger *wasmtesting.MockMessageHandler
|
||||
expContractGas sdk.Gas
|
||||
expErr bool
|
||||
expContractEventAttrs int
|
||||
expNoEvents bool
|
||||
contractAddr sdk.AccAddress
|
||||
contractResp *wasmvmtypes.IBCBasicResponse
|
||||
contractErr error
|
||||
overwriteMessenger *wasmtesting.MockMessageHandler
|
||||
expContractGas sdk.Gas
|
||||
expErr bool
|
||||
expEventTypes []string
|
||||
}{
|
||||
"consume contract gas": {
|
||||
contractAddr: example.Contract,
|
||||
@@ -115,7 +115,6 @@ func TestOnConnectChannel(t *testing.T) {
|
||||
},
|
||||
contractErr: errors.New("test, ignore"),
|
||||
expErr: true,
|
||||
expNoEvents: true,
|
||||
},
|
||||
"dispatch contract messages on success": {
|
||||
contractAddr: example.Contract,
|
||||
@@ -130,7 +129,7 @@ func TestOnConnectChannel(t *testing.T) {
|
||||
contractResp: &wasmvmtypes.IBCBasicResponse{
|
||||
Attributes: []wasmvmtypes.EventAttribute{{Key: "Foo", Value: "Bar"}},
|
||||
},
|
||||
expContractEventAttrs: 1,
|
||||
expEventTypes: []string{types.WasmModuleEventType},
|
||||
},
|
||||
"messenger errors returned, events stored": {
|
||||
contractAddr: example.Contract,
|
||||
@@ -139,14 +138,13 @@ func TestOnConnectChannel(t *testing.T) {
|
||||
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,
|
||||
overwriteMessenger: wasmtesting.NewErroringMessageHandler(),
|
||||
expErr: true,
|
||||
expEventTypes: []string{types.WasmModuleEventType},
|
||||
},
|
||||
"unknown contract address": {
|
||||
contractAddr: RandomAccountAddress(t),
|
||||
expErr: true,
|
||||
expNoEvents: true,
|
||||
},
|
||||
}
|
||||
for name, spec := range specs {
|
||||
@@ -177,16 +175,10 @@ func TestOnConnectChannel(t *testing.T) {
|
||||
err := keepers.WasmKeeper.OnConnectChannel(ctx, spec.contractAddr, msg)
|
||||
|
||||
// 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)
|
||||
}
|
||||
assert.Equal(t, spec.expEventTypes, stripTypes(ctx.EventManager().Events()))
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
@@ -198,9 +190,7 @@ func TestOnConnectChannel(t *testing.T) {
|
||||
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)
|
||||
assert.Equal(t, spec.expEventTypes, stripTypes(ctx.EventManager().Events()))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -214,14 +204,13 @@ func TestOnCloseChannel(t *testing.T) {
|
||||
const myContractGas = 40
|
||||
|
||||
specs := map[string]struct {
|
||||
contractAddr sdk.AccAddress
|
||||
contractResp *wasmvmtypes.IBCBasicResponse
|
||||
contractErr error
|
||||
overwriteMessenger *wasmtesting.MockMessageHandler
|
||||
expContractGas sdk.Gas
|
||||
expErr bool
|
||||
expContractEventAttrs int
|
||||
expNoEvents bool
|
||||
contractAddr sdk.AccAddress
|
||||
contractResp *wasmvmtypes.IBCBasicResponse
|
||||
contractErr error
|
||||
overwriteMessenger *wasmtesting.MockMessageHandler
|
||||
expContractGas sdk.Gas
|
||||
expErr bool
|
||||
expEventTypes []string
|
||||
}{
|
||||
"consume contract gas": {
|
||||
contractAddr: example.Contract,
|
||||
@@ -237,7 +226,6 @@ func TestOnCloseChannel(t *testing.T) {
|
||||
},
|
||||
contractErr: errors.New("test, ignore"),
|
||||
expErr: true,
|
||||
expNoEvents: true,
|
||||
},
|
||||
"dispatch contract messages on success": {
|
||||
contractAddr: example.Contract,
|
||||
@@ -252,7 +240,7 @@ func TestOnCloseChannel(t *testing.T) {
|
||||
contractResp: &wasmvmtypes.IBCBasicResponse{
|
||||
Attributes: []wasmvmtypes.EventAttribute{{Key: "Foo", Value: "Bar"}},
|
||||
},
|
||||
expContractEventAttrs: 1,
|
||||
expEventTypes: []string{types.WasmModuleEventType},
|
||||
},
|
||||
"messenger errors returned, events stored": {
|
||||
contractAddr: example.Contract,
|
||||
@@ -261,14 +249,13 @@ func TestOnCloseChannel(t *testing.T) {
|
||||
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,
|
||||
overwriteMessenger: wasmtesting.NewErroringMessageHandler(),
|
||||
expErr: true,
|
||||
expEventTypes: []string{types.WasmModuleEventType},
|
||||
},
|
||||
"unknown contract address": {
|
||||
contractAddr: RandomAccountAddress(t),
|
||||
expErr: true,
|
||||
expNoEvents: true,
|
||||
},
|
||||
}
|
||||
for name, spec := range specs {
|
||||
@@ -298,16 +285,10 @@ func TestOnCloseChannel(t *testing.T) {
|
||||
err := keepers.WasmKeeper.OnCloseChannel(ctx, spec.contractAddr, msg)
|
||||
|
||||
// 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)
|
||||
}
|
||||
assert.Equal(t, spec.expEventTypes, stripTypes(ctx.EventManager().Events()))
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
@@ -319,8 +300,7 @@ func TestOnCloseChannel(t *testing.T) {
|
||||
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)
|
||||
assert.Equal(t, spec.expEventTypes, stripTypes(ctx.EventManager().Events()))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -342,10 +322,7 @@ func TestOnRecvPacket(t *testing.T) {
|
||||
expContractGas sdk.Gas
|
||||
expAck []byte
|
||||
expErr bool
|
||||
// normally 0 on error, 1 on success, if we return custom events, this may be > 1
|
||||
expContractEvents int
|
||||
// how many custom attributes are on the "wasm" event (not counting _contract_address)
|
||||
expContractEventAttrs int
|
||||
expEventTypes []string
|
||||
}{
|
||||
"consume contract gas": {
|
||||
contractAddr: example.Contract,
|
||||
@@ -353,14 +330,12 @@ func TestOnRecvPacket(t *testing.T) {
|
||||
contractResp: &wasmvmtypes.IBCReceiveResponse{
|
||||
Acknowledgement: []byte("myAck"),
|
||||
},
|
||||
expAck: []byte("myAck"),
|
||||
expContractEvents: 1,
|
||||
expAck: []byte("myAck"),
|
||||
},
|
||||
"can return empty ack": {
|
||||
contractAddr: example.Contract,
|
||||
expContractGas: myContractGas,
|
||||
contractResp: &wasmvmtypes.IBCReceiveResponse{},
|
||||
expContractEvents: 1,
|
||||
contractAddr: example.Contract,
|
||||
expContractGas: myContractGas,
|
||||
contractResp: &wasmvmtypes.IBCReceiveResponse{},
|
||||
},
|
||||
"consume gas on error, ignore events + messages": {
|
||||
contractAddr: example.Contract,
|
||||
@@ -380,8 +355,7 @@ func TestOnRecvPacket(t *testing.T) {
|
||||
Acknowledgement: []byte("myAck"),
|
||||
Messages: []wasmvmtypes.SubMsg{{ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{Bank: &wasmvmtypes.BankMsg{}}}, {ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{Custom: json.RawMessage(`{"foo":"bar"}`)}}},
|
||||
},
|
||||
expContractEvents: 1,
|
||||
expAck: []byte("myAck"),
|
||||
expAck: []byte("myAck"),
|
||||
},
|
||||
"emit contract attributes on success": {
|
||||
contractAddr: example.Contract,
|
||||
@@ -390,9 +364,8 @@ func TestOnRecvPacket(t *testing.T) {
|
||||
Acknowledgement: []byte("myAck"),
|
||||
Attributes: []wasmvmtypes.EventAttribute{{Key: "Foo", Value: "Bar"}},
|
||||
},
|
||||
expContractEvents: 1,
|
||||
expContractEventAttrs: 1,
|
||||
expAck: []byte("myAck"),
|
||||
expEventTypes: []string{types.WasmModuleEventType},
|
||||
expAck: []byte("myAck"),
|
||||
},
|
||||
"emit contract events on success": {
|
||||
contractAddr: example.Contract,
|
||||
@@ -408,9 +381,8 @@ func TestOnRecvPacket(t *testing.T) {
|
||||
}},
|
||||
}},
|
||||
},
|
||||
expContractEvents: 2,
|
||||
expContractEventAttrs: 1,
|
||||
expAck: []byte("myAck"),
|
||||
expEventTypes: []string{types.WasmModuleEventType, "wasm-custom"},
|
||||
expAck: []byte("myAck"),
|
||||
},
|
||||
"messenger errors returned, events stored": {
|
||||
contractAddr: example.Contract,
|
||||
@@ -420,10 +392,9 @@ func TestOnRecvPacket(t *testing.T) {
|
||||
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,
|
||||
expContractEvents: 1,
|
||||
expContractEventAttrs: 1,
|
||||
overwriteMessenger: wasmtesting.NewErroringMessageHandler(),
|
||||
expErr: true,
|
||||
expEventTypes: []string{types.WasmModuleEventType},
|
||||
},
|
||||
"submessage reply can overwrite ack data": {
|
||||
contractAddr: example.Contract,
|
||||
@@ -435,8 +406,8 @@ func TestOnRecvPacket(t *testing.T) {
|
||||
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"),
|
||||
expContractEvents: 1,
|
||||
expAck: []byte("myBetterAck"),
|
||||
expEventTypes: []string{types.EventTypeReply},
|
||||
},
|
||||
"unknown contract address": {
|
||||
contractAddr: RandomAccountAddress(t),
|
||||
@@ -473,14 +444,10 @@ func TestOnRecvPacket(t *testing.T) {
|
||||
gotAck, err := keepers.WasmKeeper.OnRecvPacket(ctx, spec.contractAddr, msg)
|
||||
|
||||
// then
|
||||
events := ctx.EventManager().Events()
|
||||
if spec.expErr {
|
||||
require.Error(t, err)
|
||||
assert.Empty(t, capturedMsgs) // no messages captured on error
|
||||
require.Len(t, events, spec.expContractEvents)
|
||||
if spec.expContractEvents > 0 {
|
||||
assert.Len(t, events[0].Attributes, 1+spec.expContractEventAttrs)
|
||||
}
|
||||
assert.Equal(t, spec.expEventTypes, stripTypes(ctx.EventManager().Events()))
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
@@ -494,8 +461,7 @@ func TestOnRecvPacket(t *testing.T) {
|
||||
for i, m := range spec.contractResp.Messages {
|
||||
assert.Equal(t, (*capturedMsgs)[i], m.Msg)
|
||||
}
|
||||
require.Len(t, events, spec.expContractEvents)
|
||||
assert.Len(t, events[0].Attributes, 1+spec.expContractEventAttrs)
|
||||
assert.Equal(t, spec.expEventTypes, stripTypes(ctx.EventManager().Events()))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -509,14 +475,13 @@ func TestOnAckPacket(t *testing.T) {
|
||||
const myContractGas = 40
|
||||
|
||||
specs := map[string]struct {
|
||||
contractAddr sdk.AccAddress
|
||||
contractResp *wasmvmtypes.IBCBasicResponse
|
||||
contractErr error
|
||||
overwriteMessenger *wasmtesting.MockMessageHandler
|
||||
expContractGas sdk.Gas
|
||||
expErr bool
|
||||
expContractEventAttrs int
|
||||
expNoEvents bool
|
||||
contractAddr sdk.AccAddress
|
||||
contractResp *wasmvmtypes.IBCBasicResponse
|
||||
contractErr error
|
||||
overwriteMessenger *wasmtesting.MockMessageHandler
|
||||
expContractGas sdk.Gas
|
||||
expErr bool
|
||||
expEventTypes []string
|
||||
}{
|
||||
"consume contract gas": {
|
||||
contractAddr: example.Contract,
|
||||
@@ -532,7 +497,6 @@ func TestOnAckPacket(t *testing.T) {
|
||||
},
|
||||
contractErr: errors.New("test, ignore"),
|
||||
expErr: true,
|
||||
expNoEvents: true,
|
||||
},
|
||||
"dispatch contract messages on success": {
|
||||
contractAddr: example.Contract,
|
||||
@@ -547,7 +511,7 @@ func TestOnAckPacket(t *testing.T) {
|
||||
contractResp: &wasmvmtypes.IBCBasicResponse{
|
||||
Attributes: []wasmvmtypes.EventAttribute{{Key: "Foo", Value: "Bar"}},
|
||||
},
|
||||
expContractEventAttrs: 1,
|
||||
expEventTypes: []string{types.WasmModuleEventType},
|
||||
},
|
||||
"messenger errors returned, events stored": {
|
||||
contractAddr: example.Contract,
|
||||
@@ -556,14 +520,13 @@ func TestOnAckPacket(t *testing.T) {
|
||||
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,
|
||||
overwriteMessenger: wasmtesting.NewErroringMessageHandler(),
|
||||
expErr: true,
|
||||
expEventTypes: []string{types.WasmModuleEventType},
|
||||
},
|
||||
"unknown contract address": {
|
||||
contractAddr: RandomAccountAddress(t),
|
||||
expErr: true,
|
||||
expNoEvents: true,
|
||||
},
|
||||
}
|
||||
for name, spec := range specs {
|
||||
@@ -588,16 +551,11 @@ func TestOnAckPacket(t *testing.T) {
|
||||
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)
|
||||
}
|
||||
assert.Equal(t, spec.expEventTypes, stripTypes(ctx.EventManager().Events()))
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
@@ -609,9 +567,7 @@ func TestOnAckPacket(t *testing.T) {
|
||||
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)
|
||||
assert.Equal(t, spec.expEventTypes, stripTypes(ctx.EventManager().Events()))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -631,16 +587,12 @@ func TestOnTimeoutPacket(t *testing.T) {
|
||||
overwriteMessenger *wasmtesting.MockMessageHandler
|
||||
expContractGas sdk.Gas
|
||||
expErr bool
|
||||
// normally 0 on error, 1 on success, if we return custom events, this may be > 1
|
||||
expContractEvents int
|
||||
// how many custom attributes are on the "wasm" event (not counting _contract_address)
|
||||
expContractEventAttrs int
|
||||
expEventTypes []string
|
||||
}{
|
||||
"consume contract gas": {
|
||||
contractAddr: example.Contract,
|
||||
expContractGas: myContractGas,
|
||||
contractResp: &wasmvmtypes.IBCBasicResponse{},
|
||||
expContractEvents: 1,
|
||||
contractAddr: example.Contract,
|
||||
expContractGas: myContractGas,
|
||||
contractResp: &wasmvmtypes.IBCBasicResponse{},
|
||||
},
|
||||
"consume gas on error, ignore events + messages": {
|
||||
contractAddr: example.Contract,
|
||||
@@ -658,7 +610,6 @@ func TestOnTimeoutPacket(t *testing.T) {
|
||||
contractResp: &wasmvmtypes.IBCBasicResponse{
|
||||
Messages: []wasmvmtypes.SubMsg{{ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{Bank: &wasmvmtypes.BankMsg{}}}, {ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{Custom: json.RawMessage(`{"foo":"bar"}`)}}},
|
||||
},
|
||||
expContractEvents: 1,
|
||||
},
|
||||
"emit contract attributes on success": {
|
||||
contractAddr: example.Contract,
|
||||
@@ -666,8 +617,7 @@ func TestOnTimeoutPacket(t *testing.T) {
|
||||
contractResp: &wasmvmtypes.IBCBasicResponse{
|
||||
Attributes: []wasmvmtypes.EventAttribute{{Key: "Foo", Value: "Bar"}},
|
||||
},
|
||||
expContractEvents: 1,
|
||||
expContractEventAttrs: 1,
|
||||
expEventTypes: []string{types.WasmModuleEventType},
|
||||
},
|
||||
"emit contract events on success": {
|
||||
contractAddr: example.Contract,
|
||||
@@ -682,21 +632,18 @@ func TestOnTimeoutPacket(t *testing.T) {
|
||||
}},
|
||||
}},
|
||||
},
|
||||
expContractEvents: 2,
|
||||
expContractEventAttrs: 1,
|
||||
expEventTypes: []string{types.WasmModuleEventType, "wasm-custom"},
|
||||
},
|
||||
// TODO: I am a bit confued this does return events on error...
|
||||
"messenger errors returned, events stored": {
|
||||
"messenger errors returned, events stored before": {
|
||||
contractAddr: example.Contract,
|
||||
expContractGas: myContractGas + 10,
|
||||
contractResp: &wasmvmtypes.IBCBasicResponse{
|
||||
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,
|
||||
expContractEvents: 1,
|
||||
expContractEventAttrs: 1,
|
||||
overwriteMessenger: wasmtesting.NewErroringMessageHandler(),
|
||||
expErr: true,
|
||||
expEventTypes: []string{types.WasmModuleEventType},
|
||||
},
|
||||
"unknown contract address": {
|
||||
contractAddr: RandomAccountAddress(t),
|
||||
@@ -725,14 +672,10 @@ func TestOnTimeoutPacket(t *testing.T) {
|
||||
err := keepers.WasmKeeper.OnTimeoutPacket(ctx, spec.contractAddr, msg)
|
||||
|
||||
// then
|
||||
events := ctx.EventManager().Events()
|
||||
if spec.expErr {
|
||||
require.Error(t, err)
|
||||
assert.Empty(t, capturedMsgs) // no messages captured on error
|
||||
require.Len(t, events, spec.expContractEvents)
|
||||
if spec.expContractEvents > 0 {
|
||||
assert.Len(t, events[0].Attributes, 1+spec.expContractEventAttrs)
|
||||
}
|
||||
assert.Equal(t, spec.expEventTypes, stripTypes(ctx.EventManager().Events()))
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
@@ -744,8 +687,15 @@ func TestOnTimeoutPacket(t *testing.T) {
|
||||
for i, m := range spec.contractResp.Messages {
|
||||
assert.Equal(t, (*capturedMsgs)[i], m.Msg)
|
||||
}
|
||||
require.Len(t, events, spec.expContractEvents)
|
||||
assert.Len(t, events[0].Attributes, 1+spec.expContractEventAttrs)
|
||||
assert.Equal(t, spec.expEventTypes, stripTypes(ctx.EventManager().Events()))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func stripTypes(events sdk.Events) []string {
|
||||
var r []string
|
||||
for _, e := range events {
|
||||
r = append(r, e.Type)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
@@ -210,7 +210,7 @@ func TestDispatchSubMsgErrorHandling(t *testing.T) {
|
||||
|
||||
assertReturnedEvents := func(expectedEvents int) assertion {
|
||||
return func(t *testing.T, ctx sdk.Context, contract, emptyAccount string, response wasmvmtypes.SubcallResult) {
|
||||
assert.Len(t, response.Ok.Events, expectedEvents)
|
||||
require.Len(t, response.Ok.Events, expectedEvents)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,14 +231,14 @@ func TestDispatchSubMsgErrorHandling(t *testing.T) {
|
||||
assertGotContractAddr := func(t *testing.T, ctx sdk.Context, contract, emptyAccount string, response wasmvmtypes.SubcallResult) {
|
||||
// should get the events emitted on new contract
|
||||
event := response.Ok.Events[0]
|
||||
assert.Equal(t, event.Type, "wasm")
|
||||
require.Equal(t, event.Type, "instantiate")
|
||||
assert.Equal(t, event.Attributes[0].Key, "_contract_address")
|
||||
eventAddr := event.Attributes[0].Value
|
||||
assert.NotEqual(t, contract, eventAddr)
|
||||
|
||||
// data field is the raw canonical address
|
||||
// QUESTION: why not types.MsgInstantiateContractResponse? difference between calling Router and Service?
|
||||
assert.Len(t, response.Ok.Data, 20)
|
||||
require.Len(t, response.Ok.Data, 20)
|
||||
resAddr := sdk.AccAddress(response.Ok.Data)
|
||||
assert.Equal(t, eventAddr, resAddr.String())
|
||||
}
|
||||
|
||||
5
x/wasm/keeper/testdata/download_releases.sh
vendored
5
x/wasm/keeper/testdata/download_releases.sh
vendored
@@ -17,4 +17,7 @@ done
|
||||
|
||||
# create the zip variant
|
||||
gzip -k hackatom.wasm
|
||||
mv hackatom.wasm.gz hackatom.wasm.gzip
|
||||
mv hackatom.wasm.gz hackatom.wasm.gzip
|
||||
|
||||
rm -f version.txt
|
||||
echo "$tag" >version.txt
|
||||
BIN
x/wasm/keeper/testdata/hackatom.wasm.gzip
vendored
BIN
x/wasm/keeper/testdata/hackatom.wasm.gzip
vendored
Binary file not shown.
BIN
x/wasm/keeper/testdata/ibc_reflect.wasm
vendored
BIN
x/wasm/keeper/testdata/ibc_reflect.wasm
vendored
Binary file not shown.
1
x/wasm/keeper/testdata/version.txt
vendored
Normal file
1
x/wasm/keeper/testdata/version.txt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
v0.16.0+contracts
|
||||
@@ -179,11 +179,12 @@ func TestHandleInstantiate(t *testing.T) {
|
||||
|
||||
require.Equal(t, "cosmos14hj2tavq8fpesdwxxcu44rty3hh90vhuc53mp6", contractBech32Addr)
|
||||
// this should be standard x/wasm init event, nothing from contract
|
||||
require.Equal(t, 2, len(res.Events), prettyEvents(res.Events))
|
||||
assert.Equal(t, "wasm", res.Events[0].Type)
|
||||
assertAttribute(t, "_contract_address", contractBech32Addr, res.Events[0].Attributes[0])
|
||||
assert.Equal(t, "message", res.Events[1].Type)
|
||||
assertAttribute(t, "module", "wasm", res.Events[1].Attributes[0])
|
||||
require.Equal(t, 3, len(res.Events), prettyEvents(res.Events))
|
||||
require.Equal(t, "message", res.Events[0].Type)
|
||||
assertAttribute(t, "module", "wasm", res.Events[0].Attributes[0])
|
||||
require.Equal(t, "instantiate", res.Events[1].Type)
|
||||
require.Equal(t, "wasm", res.Events[2].Type)
|
||||
assertAttribute(t, "_contract_address", contractBech32Addr, res.Events[2].Attributes[0])
|
||||
|
||||
assertCodeList(t, q, data.ctx, 1)
|
||||
assertCodeBytes(t, q, data.ctx, 1, testContract)
|
||||
@@ -235,13 +236,14 @@ func TestHandleExecute(t *testing.T) {
|
||||
contractBech32Addr := parseInitResponse(t, res.Data)
|
||||
|
||||
require.Equal(t, "cosmos14hj2tavq8fpesdwxxcu44rty3hh90vhuc53mp6", contractBech32Addr)
|
||||
// this should be standard x/wasm init event, plus a bank send event (2), with no custom contract events
|
||||
require.Equal(t, 3, len(res.Events), prettyEvents(res.Events))
|
||||
assert.Equal(t, "transfer", res.Events[0].Type)
|
||||
assert.Equal(t, "wasm", res.Events[1].Type)
|
||||
assertAttribute(t, "_contract_address", contractBech32Addr, res.Events[1].Attributes[0])
|
||||
assert.Equal(t, "message", res.Events[2].Type)
|
||||
assertAttribute(t, "module", "wasm", res.Events[2].Attributes[0])
|
||||
// this should be standard x/wasm message event, init event, plus a bank send event (2), with no custom contract events
|
||||
require.Equal(t, 4, len(res.Events), prettyEvents(res.Events))
|
||||
require.Equal(t, "message", res.Events[0].Type)
|
||||
assertAttribute(t, "module", "wasm", res.Events[0].Attributes[0])
|
||||
require.Equal(t, "transfer", res.Events[1].Type)
|
||||
require.Equal(t, "instantiate", res.Events[2].Type)
|
||||
require.Equal(t, "wasm", res.Events[3].Type)
|
||||
assertAttribute(t, "_contract_address", contractBech32Addr, res.Events[3].Attributes[0])
|
||||
|
||||
// ensure bob doesn't exist
|
||||
bobAcct := data.acctKeeper.GetAccount(data.ctx, bob)
|
||||
@@ -271,29 +273,33 @@ func TestHandleExecute(t *testing.T) {
|
||||
assertExecuteResponse(t, res.Data, []byte{0xf0, 0x0b, 0xaa})
|
||||
|
||||
// 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, 6, len(res.Events), prettyEvents(res.Events))
|
||||
|
||||
assert.Equal(t, "message", res.Events[0].Type)
|
||||
assertAttribute(t, "module", "wasm", res.Events[0].Attributes[0])
|
||||
|
||||
require.Equal(t, "transfer", res.Events[1].Type)
|
||||
require.Len(t, res.Events[1].Attributes, 3)
|
||||
assertAttribute(t, "recipient", contractBech32Addr, res.Events[1].Attributes[0])
|
||||
assertAttribute(t, "sender", fred.String(), res.Events[1].Attributes[1])
|
||||
assertAttribute(t, "amount", "5000denom", res.Events[1].Attributes[2])
|
||||
|
||||
assert.Equal(t, "execute", res.Events[2].Type)
|
||||
|
||||
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 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])
|
||||
assert.Equal(t, "wasm", res.Events[3].Type)
|
||||
assertAttribute(t, "_contract_address", contractBech32Addr, res.Events[3].Attributes[0])
|
||||
assertAttribute(t, "action", "release", res.Events[3].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])
|
||||
assert.Equal(t, "wasm-hackatom", res.Events[4].Type)
|
||||
assertAttribute(t, "_contract_address", contractBech32Addr, res.Events[4].Attributes[0])
|
||||
assertAttribute(t, "action", "release", res.Events[4].Attributes[1])
|
||||
// second transfer (this without conflicting message)
|
||||
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])
|
||||
assert.Equal(t, "transfer", res.Events[5].Type)
|
||||
assertAttribute(t, "recipient", bob.String(), res.Events[5].Attributes[0])
|
||||
assertAttribute(t, "sender", contractBech32Addr, res.Events[5].Attributes[1])
|
||||
assertAttribute(t, "amount", "105000denom", res.Events[5].Attributes[2])
|
||||
// finally, standard x/wasm tag
|
||||
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)
|
||||
|
||||
@@ -1,23 +1,28 @@
|
||||
package types
|
||||
|
||||
const (
|
||||
// WasmModuleEventType is stored with any contract TX
|
||||
// WasmModuleEventType is stored with any contract TX that returns non empty EventAttributes
|
||||
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"
|
||||
|
||||
EventTypeStoreCode = "store_code"
|
||||
EventTypeInstantiate = "instantiate"
|
||||
EventTypeExecute = "execute"
|
||||
EventTypeMigrate = "migrate"
|
||||
EventTypePinCode = "pin_code"
|
||||
EventTypeUnpinCode = "unpin_code"
|
||||
EventTypeSudo = "sudo"
|
||||
EventTypeReply = "reply"
|
||||
EventTypeGovContractResult = "gov_contract_result"
|
||||
)
|
||||
|
||||
// event attributes returned from contract execution
|
||||
const (
|
||||
AttributeReservedPrefix = "_"
|
||||
AttributeKeyContractAddr = "_contract_address"
|
||||
)
|
||||
AttributeReservedPrefix = "_"
|
||||
|
||||
// event attributes returned under "message" type - no prefix needed there
|
||||
const (
|
||||
AttributeKeyCodeID = "code_id"
|
||||
AttributeKeySigner = "signer"
|
||||
AttributeResultDataHex = "result"
|
||||
AttributeKeyContractAddr = "_contract_address"
|
||||
AttributeKeyCodeID = "code_id"
|
||||
AttributeKeyResultDataHex = "result"
|
||||
AttributeKeyFeature = "feature"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user