Skip to content

Commit

Permalink
Update events (#98)
Browse files Browse the repository at this point in the history
* Update events

(cherry picked from commit f00c336b46fcb4058fc6485fbfdb94d870cedd58)

* Capture context events

* Add event description

* Increase system test timeout to 45s
  • Loading branch information
alpe authored Aug 16, 2021
1 parent 5e24861 commit 3f75489
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 20 deletions.
62 changes: 62 additions & 0 deletions EVENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Event System

Events are an essential part of the Cosmos SDK. They are similar to "logs" in Ethereum and allow a blockchain
app to attach key-value pairs to a transaction that can later be used to search for it or extract some information
in human readable form. Events are not written to the application state, nor do they form part of the AppHash,
but mainly intended for client use (and become an essential API for any reactive app or app that searches for txs).

See https://github.com/CosmWasm/wasmd/blob/master/EVENTS.md for more details


### Standard Events in x/poe
```go
// create new validator
sdk.NewEvent(
"create_validator",
sdk.NewAttribute("operator", msg.DelegatorAddress),
sdk.NewAttribute("moniker", msg.Description.Moniker),
sdk.NewAttribute("pubkey", hex.EncodeToString(pk.Bytes())),
sdk.NewAttribute("amount", msg.Value.Amount.String()),
)

// update any validator data
sdk.NewEvent(
"update_validator",
sdk.NewAttribute("operator", msg.DelegatorAddress),
sdk.NewAttribute("moniker", msg.Description.Moniker),
),

```

### Standard Events in x/twasm
In twasm we have the concept of (privileged](https://github.com/confio/tgrade/tree/main/x/twasm#privileged) contracts that
add a number of new events to the system:

```go
// when a contract was set as privileged
sdk.NewEvent(
"set_privileged_contract",
sdk.NewAttribute("_contract_address", contractAddr.String()),
)

// when a contract had the privileged flag removed
sdk.NewEvent(
"unset_privileged_contract",
sdk.NewAttribute("_contract_address", contractAddr.String()),
)

// when a new privilege was given to a contract
sdk.NewEvent(
"register_privilege",
sdk.NewAttribute("_contract_address", contractAddr.String()),
sdk.NewAttribute("privilege_type", privilegeType.String()),
)

// when a privilege was removed for a contract
event := sdk.NewEvent(
"release_privilege",
sdk.NewAttribute(wasmtypes.AttributeKeyContractAddr, contractAddr.String()),
sdk.NewAttribute("privilege_type", privilegeType.String()),
)
```
We also emit the standard events from [wasmd/x/wasm](https://github.com/CosmWasm/wasmd/blob/master/EVENTS.md#standard-events-in-xwasm)
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ test-unit:
@VERSION=$(VERSION) go test -mod=readonly -tags='ledger test_ledger_mock' ./...

test-system: install
@VERSION=$(VERSION) go test -mod=readonly -tags='ledger test_ledger_mock system_test' ./testing --wait-time=30s --verbose
@VERSION=$(VERSION) go test -mod=readonly -tags='ledger test_ledger_mock system_test' ./testing --wait-time=45s --verbose

test-race:
@VERSION=$(VERSION) go test -mod=readonly -race -tags='ledger test_ledger_mock' ./...
Expand Down
19 changes: 11 additions & 8 deletions x/twasm/keeper/handler_plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,29 +41,32 @@ func NewTgradeHandler(cdc codec.Marshaler, keeper tgradeKeeper, bankKeeper minte
}

// DispatchMsg handles wasmVM message for privileged contracts
func (h TgradeHandler) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddress, _ string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) {
func (h TgradeHandler) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddress, _ string, msg wasmvmtypes.CosmosMsg) ([]sdk.Event, [][]byte, error) {
if msg.Custom == nil {
return nil, nil, wasmtypes.ErrUnknownMsg
}
if !h.keeper.IsPrivileged(ctx, contractAddr) {
return nil, nil, wasmtypes.ErrUnknownMsg
}
em := sdk.NewEventManager()
ctx = ctx.WithEventManager(em)
var tMsg contract.TgradeMsg
if err := tMsg.UnmarshalWithAny(msg.Custom, h.cdc); err != nil {
return nil, nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
}
switch {
case tMsg.Privilege != nil:
return nil, nil, h.handlePrivilege(ctx, contractAddr, tMsg.Privilege)
err := h.handlePrivilege(ctx, contractAddr, tMsg.Privilege)
return em.Events(), nil, err
case tMsg.ExecuteGovProposal != nil:
return nil, nil, h.handleGovProposalExecution(ctx, contractAddr, tMsg.ExecuteGovProposal)
err := h.handleGovProposalExecution(ctx, contractAddr, tMsg.ExecuteGovProposal)
return em.Events(), nil, err
case tMsg.MintTokens != nil:
evts, err := h.handleMintToken(ctx, contractAddr, tMsg.MintTokens)
return evts, nil, err
return append(evts, em.Events()...), nil, err
}

ModuleLogger(ctx).Info("unhandled message", "msg", msg)

return nil, nil, wasmtypes.ErrUnknownMsg
}

Expand Down Expand Up @@ -160,10 +163,10 @@ func (h TgradeHandler) handleMintToken(ctx sdk.Context, contractAddr sdk.AccAddr
}

return sdk.Events{sdk.NewEvent(
types.EventTypeRewards,
sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
types.EventTypeMintTokens,
sdk.NewAttribute(wasmtypes.AttributeKeyContractAddr, contractAddr.String()),
sdk.NewAttribute(sdk.AttributeKeyAmount, token.String()),
sdk.NewAttribute(types.AttributeKeyRewardRecipient, mint.RecipientAddr),
sdk.NewAttribute(types.AttributeKeyRecipient, mint.RecipientAddr),
)}, nil
}

Expand Down
32 changes: 28 additions & 4 deletions x/twasm/keeper/handler_plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,17 @@ func TestTgradeHandlesDispatchMsg(t *testing.T) {
src wasmvmtypes.CosmosMsg
expErr *sdkerrors.Error
expCapturedGovContent []govtypes.Content
expEvents []sdk.Event
}{
"handle privilege msg": {
src: wasmvmtypes.CosmosMsg{
Custom: []byte(`{"privilege":{"request":"begin_blocker"}}`),
},
setup: func(m *handlerTgradeKeeperMock) {
noopRegisterHook(m)
m.GetContractInfoFn = emitCtxEventWithGetContractInfoFn(m.GetContractInfoFn, sdk.NewEvent("testing"))
},
expEvents: sdk.Events{sdk.NewEvent("testing")},
},
"handle execute gov proposal msg": {
src: wasmvmtypes.CosmosMsg{
Expand All @@ -45,8 +48,10 @@ func TestTgradeHandlesDispatchMsg(t *testing.T) {
details.AddRegisteredPrivilege(types.PrivilegeTypeGovProposalExecutor, 1)
require.NoError(t, info.SetExtension(&details))
})
m.GetContractInfoFn = emitCtxEventWithGetContractInfoFn(m.GetContractInfoFn, sdk.NewEvent("testing"))
},
expCapturedGovContent: []govtypes.Content{&govtypes.TextProposal{Title: "foo", Description: "bar"}},
expEvents: sdk.Events{sdk.NewEvent("testing")},
},
"handle minter msg": {
src: wasmvmtypes.CosmosMsg{
Expand All @@ -60,6 +65,12 @@ func TestTgradeHandlesDispatchMsg(t *testing.T) {
require.NoError(t, info.SetExtension(&details))
})
},
expEvents: sdk.Events{sdk.NewEvent(
types.EventTypeMintTokens,
sdk.NewAttribute(wasmtypes.AttributeKeyContractAddr, contractAddr.String()),
sdk.NewAttribute(sdk.AttributeKeyAmount, "1utgd"),
sdk.NewAttribute(types.AttributeKeyRecipient, otherAddr.String()),
)},
},
"non custom msg rejected": {
src: wasmvmtypes.CosmosMsg{},
Expand Down Expand Up @@ -93,14 +104,27 @@ func TestTgradeHandlesDispatchMsg(t *testing.T) {
mock := handlerTgradeKeeperMock{}
spec.setup(&mock)
h := NewTgradeHandler(cdc, mock, minterMock, govRouter)
var ctx sdk.Context
_, _, gotErr := h.DispatchMsg(ctx, contractAddr, "", spec.src)
em := sdk.NewEventManager()
ctx := sdk.Context{}.WithEventManager(em)

// when
gotEvents, _, gotErr := h.DispatchMsg(ctx, contractAddr, "", spec.src)
// then
require.True(t, spec.expErr.Is(gotErr), "expected %v but got %#+v", spec.expErr, gotErr)
assert.Equal(t, spec.expCapturedGovContent, govRouter.captured)
assert.Equal(t, spec.expEvents, gotEvents)
assert.Empty(t, em.Events())
})
}
}

func emitCtxEventWithGetContractInfoFn(fn func(ctx sdk.Context, contractAddress sdk.AccAddress) *wasmtypes.ContractInfo, event sdk.Event) func(ctx sdk.Context, contractAddress sdk.AccAddress) *wasmtypes.ContractInfo {
return func(ctx sdk.Context, contractAddress sdk.AccAddress) *wasmtypes.ContractInfo {
ctx.EventManager().EmitEvent(event)
return fn(ctx, contractAddress)
}
}

type registration struct {
cb types.PrivilegeType
addr sdk.AccAddress
Expand Down Expand Up @@ -551,12 +575,12 @@ func TestHandleMintToken(t *testing.T) {
assert.Equal(t, (*capturedSentCoins)[0].coins, spec.expMintedCoins)
assert.Equal(t, (*capturedSentCoins)[0].recipientAddr, spec.expRecipient)
require.Len(t, gotEvts, 1)
assert.Equal(t, types.EventTypeRewards, gotEvts[0].Type)
assert.Equal(t, types.EventTypeMintTokens, gotEvts[0].Type)
})
}
}

// noopRegisterHook does nothing and but all methods for registration
// noopRegisterHook provided method stubs for all methods for registration
func noopRegisterHook(m *handlerTgradeKeeperMock, mutators ...func(*wasmtypes.ContractInfo)) {
m.IsPrivilegedFn = func(ctx sdk.Context, contract sdk.AccAddress) bool {
return true
Expand Down
4 changes: 0 additions & 4 deletions x/twasm/keeper/privileged.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ func (k Keeper) SetPrivileged(ctx sdk.Context, contractAddr sdk.AccAddress) erro
k.Logger(ctx).Info("Set privileged", "contractAddr", contractAddr.String())
event := sdk.NewEvent(
types.EventTypeSetPrivileged,
sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
sdk.NewAttribute(wasmtypes.AttributeKeyContractAddr, contractAddr.String()),
)
ctx.EventManager().EmitEvent(event)
Expand Down Expand Up @@ -98,7 +97,6 @@ func (k Keeper) UnsetPrivileged(ctx sdk.Context, contractAddr sdk.AccAddress) er
k.Logger(ctx).Info("Unset privileged", "contractAddr", contractAddr.String())
event := sdk.NewEvent(
types.EventTypeUnsetPrivileged,
sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
sdk.NewAttribute(wasmtypes.AttributeKeyContractAddr, contractAddr.String()),
)
ctx.EventManager().EmitEvent(event)
Expand Down Expand Up @@ -187,7 +185,6 @@ func (k Keeper) appendToPrivilegedContracts(ctx sdk.Context, privilegeType types
k.Logger(ctx).Info("Add privilege", "contractAddr", contractAddr.String(), "type", privilegeType.String())
event := sdk.NewEvent(
types.EventTypeRegisterPrivilege,
sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
sdk.NewAttribute(wasmtypes.AttributeKeyContractAddr, contractAddr.String()),
sdk.NewAttribute(types.AttributeKeyCallbackType, privilegeType.String()),
)
Expand All @@ -212,7 +209,6 @@ func (k Keeper) removePrivilegeRegistration(ctx sdk.Context, privilegeType types
k.Logger(ctx).Info("Remove privilege", "contractAddr", contractAddr.String(), "type", privilegeType.String())
event := sdk.NewEvent(
types.EventTypeReleasePrivilege,
sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
sdk.NewAttribute(wasmtypes.AttributeKeyContractAddr, contractAddr.String()),
sdk.NewAttribute(types.AttributeKeyCallbackType, privilegeType.String()),
)
Expand Down
6 changes: 3 additions & 3 deletions x/twasm/types/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ const (
EventTypeUnsetPrivileged = "unset_privileged_contract"
EventTypeRegisterPrivilege = "register_privilege"
EventTypeReleasePrivilege = "release_privilege"
EventTypeRewards = "rewards"
EventTypeMintTokens = "mint"
)

const ( // event attributes
AttributeKeyCallbackType = "privilege_type"
AttributeKeyRewardRecipient = "recipient"
AttributeKeyCallbackType = "privilege_type"
AttributeKeyRecipient = "recipient"
)

0 comments on commit 3f75489

Please sign in to comment.