Skip to content

Commit

Permalink
Merge pull request #586 from CosmWasm/event_types_440
Browse files Browse the repository at this point in the history
Refactor events
  • Loading branch information
ethanfrey authored Aug 11, 2021
2 parents 0d2b291 + 0e49169 commit 7b2e84c
Show file tree
Hide file tree
Showing 16 changed files with 464 additions and 331 deletions.
11 changes: 11 additions & 0 deletions EVENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
14 changes: 0 additions & 14 deletions x/wasm/keeper/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
14 changes: 14 additions & 0 deletions x/wasm/keeper/events_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
79 changes: 71 additions & 8 deletions x/wasm/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
"github.com/tendermint/tendermint/libs/log"
"math"
"path/filepath"
"strconv"
"strings"
"time"
)

Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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")
Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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
}

Expand All @@ -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
}

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
}
Expand All @@ -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
}

Expand All @@ -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
}
Loading

0 comments on commit 7b2e84c

Please sign in to comment.