Skip to content

Commit

Permalink
Add additional trigger events (#1740)
Browse files Browse the repository at this point in the history
* Create new events and generate protos.

* Add events to emit.

* Update tests for processing to test new dispatched event.

* Add tests for EventTriggerDetection.

* Update specs for events.

* Update changelog.

* Change EventTriggerExecuted to contain a success flag rather than an error string. It's possible for the error to be non-deterministic.

* Update assert.

---------

Co-authored-by: Ira Miller <[email protected]>
  • Loading branch information
Taztingo and iramiller authored Nov 10, 2023
1 parent 1d3aea4 commit 7ece7b4
Show file tree
Hide file tree
Showing 9 changed files with 655 additions and 42 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
### Improvements

* When the exchange module settles orders, update the marker net-asset-values ([#1736](https://github.com/provenance-io/provenance/pull/1736).
* Add the EventTriggerDetected and EventTriggerExecuted events [#1717](https://github.com/provenance-io/provenance/issues/1717).

### Bug Fixes

Expand Down
38 changes: 36 additions & 2 deletions docs/proto-docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,8 @@
- [provenance/trigger/v1/event.proto](#provenance/trigger/v1/event.proto)
- [EventTriggerCreated](#provenance.trigger.v1.EventTriggerCreated)
- [EventTriggerDestroyed](#provenance.trigger.v1.EventTriggerDestroyed)
- [EventTriggerDetected](#provenance.trigger.v1.EventTriggerDetected)
- [EventTriggerExecuted](#provenance.trigger.v1.EventTriggerExecuted)

- [provenance/trigger/v1/trigger.proto](#provenance/trigger/v1/trigger.proto)
- [Attribute](#provenance.trigger.v1.Attribute)
Expand Down Expand Up @@ -9990,7 +9992,7 @@ EventTriggerCreated is an event for when a trigger is created

| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `trigger_id` | [string](#string) | | trigger_id is a unique identifier of the trigger |
| `trigger_id` | [string](#string) | | trigger_id is a unique identifier of the trigger. |



Expand All @@ -10005,7 +10007,39 @@ EventTriggerDestroyed is an event for when a trigger is destroyed

| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `trigger_id` | [string](#string) | | trigger_id is a unique identifier of the trigger |
| `trigger_id` | [string](#string) | | trigger_id is a unique identifier of the trigger. |






<a name="provenance.trigger.v1.EventTriggerDetected"></a>

### EventTriggerDetected
EventTriggerDetected is an event for when a trigger's event is detected


| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `trigger_id` | [string](#string) | | trigger_id is a unique identifier of the trigger. |






<a name="provenance.trigger.v1.EventTriggerExecuted"></a>

### EventTriggerExecuted
EventTriggerExecuted is an event for when a trigger is executed.


| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `trigger_id` | [string](#string) | | trigger_id is a unique identifier of the trigger. |
| `owner` | [string](#string) | | owner is the creator of the trigger. |
| `success` | [bool](#bool) | | success indicates if all executed actions were successful. |



Expand Down
20 changes: 18 additions & 2 deletions proto/provenance/trigger/v1/event.proto
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,28 @@ option java_multiple_files = true;

// EventTriggerCreated is an event for when a trigger is created
message EventTriggerCreated {
// trigger_id is a unique identifier of the trigger
// trigger_id is a unique identifier of the trigger.
string trigger_id = 1;
}

// EventTriggerDestroyed is an event for when a trigger is destroyed
message EventTriggerDestroyed {
// trigger_id is a unique identifier of the trigger
// trigger_id is a unique identifier of the trigger.
string trigger_id = 1;
}

// EventTriggerDetected is an event for when a trigger's event is detected
message EventTriggerDetected {
// trigger_id is a unique identifier of the trigger.
string trigger_id = 1;
}

// EventTriggerExecuted is an event for when a trigger is executed.
message EventTriggerExecuted {
// trigger_id is a unique identifier of the trigger.
string trigger_id = 1;
// owner is the creator of the trigger.
string owner = 2;
// success indicates if all executed actions were successful.
bool success = 3;
}
11 changes: 11 additions & 0 deletions x/trigger/keeper/event_detector.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ func (k Keeper) DetectBlockEvents(ctx sdk.Context) {

for _, trigger := range triggers {
k.Logger(ctx).Debug(fmt.Sprintf("Trigger %d added to queue", trigger.Id))
k.emitTriggerDetected(ctx, trigger)
k.UnregisterTrigger(ctx, trigger)
k.QueueTrigger(ctx, trigger)
}
Expand Down Expand Up @@ -88,3 +89,13 @@ func (k Keeper) getMatchingTriggersUntil(ctx sdk.Context, prefix string, match f
}
return
}

// emitTriggerDetected Emits an EventTriggerDetection for the provided trigger.
func (k Keeper) emitTriggerDetected(ctx sdk.Context, trigger types.Trigger) {
err := ctx.EventManager().EmitTypedEvent(&types.EventTriggerDetected{
TriggerId: fmt.Sprintf("%d", trigger.GetId()),
})
if err != nil {
ctx.Logger().Error("unable to emit EventTriggerDetected", "err", err)
}
}
51 changes: 51 additions & 0 deletions x/trigger/keeper/event_detector_test.go
Original file line number Diff line number Diff line change
@@ -1,24 +1,36 @@
package keeper_test

import (
"fmt"

codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdktx "github.com/cosmos/cosmos-sdk/types/tx"
"github.com/provenance-io/provenance/testutil/assertions"
"github.com/provenance-io/provenance/x/trigger/types"
)

func (s *KeeperTestSuite) TestDetectBlockEvents() {
detected := func(triggerID uint64) sdk.Event {
event, _ := sdk.TypedEventToEvent(&types.EventTriggerDetected{
TriggerId: fmt.Sprintf("%d", triggerID),
})
return event
}

tests := []struct {
name string
triggers []types.TriggerEventI
registered []types.Trigger
queued []types.QueuedTrigger
events sdk.Events
}{
{
name: "valid - no triggers",
triggers: []types.TriggerEventI{},
registered: []types.Trigger(nil),
queued: []types.QueuedTrigger(nil),
events: sdk.Events{},
},
{
name: "valid - triggers, but no events",
Expand All @@ -29,6 +41,7 @@ func (s *KeeperTestSuite) TestDetectBlockEvents() {
s.CreateTrigger(1, s.accountAddresses[0].String(), &types.BlockHeightEvent{BlockHeight: uint64(s.ctx.BlockHeight()) + 1}, &types.MsgDestroyTriggerRequest{Id: 1, Authority: s.accountAddresses[0].String()}),
},
queued: []types.QueuedTrigger(nil),
events: sdk.Events{},
},
{
name: "valid - 1 detected transaction event",
Expand All @@ -43,6 +56,9 @@ func (s *KeeperTestSuite) TestDetectBlockEvents() {
Trigger: s.CreateTrigger(2, s.accountAddresses[0].String(), &types.TransactionEvent{Name: "event2"}, &types.MsgDestroyTriggerRequest{Id: 1, Authority: s.accountAddresses[0].String()}),
},
},
events: []sdk.Event{
detected(2),
},
},
{
name: "valid - 1 detected transaction event for multiple of same event",
Expand All @@ -57,6 +73,9 @@ func (s *KeeperTestSuite) TestDetectBlockEvents() {
Trigger: s.CreateTrigger(3, s.accountAddresses[0].String(), &types.TransactionEvent{Name: "event1"}, &types.MsgDestroyTriggerRequest{Id: 1, Authority: s.accountAddresses[0].String()}),
},
},
events: []sdk.Event{
detected(3),
},
},
{
name: "valid - 1 detected block height event",
Expand All @@ -71,6 +90,9 @@ func (s *KeeperTestSuite) TestDetectBlockEvents() {
Trigger: s.CreateTrigger(4, s.accountAddresses[0].String(), &types.BlockHeightEvent{BlockHeight: uint64(s.ctx.BlockHeight())}, &types.MsgDestroyTriggerRequest{Id: 1, Authority: s.accountAddresses[0].String()}),
},
},
events: []sdk.Event{
detected(4),
},
},
{
name: "valid - 1 detected time event",
Expand All @@ -85,6 +107,9 @@ func (s *KeeperTestSuite) TestDetectBlockEvents() {
Trigger: s.CreateTrigger(5, s.accountAddresses[0].String(), &types.BlockTimeEvent{Time: s.ctx.BlockTime()}, &types.MsgDestroyTriggerRequest{Id: 1, Authority: s.accountAddresses[0].String()}),
},
},
events: []sdk.Event{
detected(5),
},
},
{
name: "valid - multiple detected transaction events",
Expand All @@ -111,6 +136,11 @@ func (s *KeeperTestSuite) TestDetectBlockEvents() {
Trigger: s.CreateTrigger(8, s.accountAddresses[0].String(), &types.TransactionEvent{Name: "event2"}, &types.MsgDestroyTriggerRequest{Id: 1, Authority: s.accountAddresses[0].String()}),
},
},
events: []sdk.Event{
detected(6),
detected(7),
detected(8),
},
},
{
name: "valid - multiple detected block height events",
Expand All @@ -131,6 +161,10 @@ func (s *KeeperTestSuite) TestDetectBlockEvents() {
Trigger: s.CreateTrigger(10, s.accountAddresses[0].String(), &types.BlockHeightEvent{BlockHeight: uint64(s.ctx.BlockHeight())}, &types.MsgDestroyTriggerRequest{Id: 1, Authority: s.accountAddresses[0].String()}),
},
},
events: []sdk.Event{
detected(9),
detected(10),
},
},
{
name: "valid - multiple detected block height events and reordered",
Expand All @@ -151,6 +185,10 @@ func (s *KeeperTestSuite) TestDetectBlockEvents() {
Trigger: s.CreateTrigger(11, s.accountAddresses[0].String(), &types.BlockHeightEvent{BlockHeight: uint64(s.ctx.BlockHeight())}, &types.MsgDestroyTriggerRequest{Id: 1, Authority: s.accountAddresses[0].String()}),
},
},
events: []sdk.Event{
detected(12),
detected(11),
},
},
{
name: "valid - multiple detected time events",
Expand All @@ -171,6 +209,10 @@ func (s *KeeperTestSuite) TestDetectBlockEvents() {
Trigger: s.CreateTrigger(14, s.accountAddresses[0].String(), &types.BlockTimeEvent{Time: s.ctx.BlockTime()}, &types.MsgDestroyTriggerRequest{Id: 1, Authority: s.accountAddresses[0].String()}),
},
},
events: []sdk.Event{
detected(13),
detected(14),
},
},
{
name: "valid - different types detected",
Expand Down Expand Up @@ -200,6 +242,11 @@ func (s *KeeperTestSuite) TestDetectBlockEvents() {
Trigger: s.CreateTrigger(18, s.accountAddresses[0].String(), &types.BlockTimeEvent{Time: s.ctx.BlockTime()}, &types.MsgDestroyTriggerRequest{Id: 1, Authority: s.accountAddresses[0].String()}),
},
},
events: []sdk.Event{
detected(15),
detected(17),
detected(18),
},
},
}

Expand All @@ -215,10 +262,14 @@ func (s *KeeperTestSuite) TestDetectBlockEvents() {
s.ctx.GasMeter().RefundGas(s.ctx.GasMeter().GasConsumed(), "testing")
registered = append(registered, trigger)
}
s.ctx = s.ctx.WithEventManager(sdk.NewEventManagerWithHistory(s.ctx.EventManager().GetABCIEventHistory()))

// Action
s.app.TriggerKeeper.DetectBlockEvents(s.ctx)

events := s.ctx.EventManager().Events()
assertions.AssertEqualEvents(s.T(), tc.events, events, "should have correct events from detected events in DetectBlockEvents")

// Verify
triggers, err := s.app.TriggerKeeper.GetAllTriggers(s.ctx)
s.NoError(err, "GetAllTriggers")
Expand Down
27 changes: 22 additions & 5 deletions x/trigger/keeper/trigger_dispatcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import (
"fmt"

"github.com/cosmos/cosmos-sdk/baseapp"
types "github.com/cosmos/cosmos-sdk/codec/types"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdktx "github.com/cosmos/cosmos-sdk/types/tx"

"github.com/provenance-io/provenance/x/trigger/types"
)

const (
Expand Down Expand Up @@ -37,12 +39,13 @@ func (k Keeper) ProcessTriggers(ctx sdk.Context) {
k.RemoveGasLimit(ctx, triggerID)

actions := item.GetTrigger().Actions
k.runActions(ctx, gasLimit, actions)
err := k.runActions(ctx, gasLimit, actions)
k.emitTriggerExecuted(ctx, item.GetTrigger(), err == nil)
}
}

// RunActions Runs all the actions and constrains them by gasLimit.
func (k Keeper) runActions(ctx sdk.Context, gasLimit uint64, actions []*types.Any) {
func (k Keeper) runActions(ctx sdk.Context, gasLimit uint64, actions []*codectypes.Any) error {
cacheCtx, flush := ctx.CacheContext()
gasMeter := sdk.NewGasMeter(gasLimit)
cacheCtx = cacheCtx.WithGasMeter(gasMeter)
Expand All @@ -55,21 +58,23 @@ func (k Keeper) runActions(ctx sdk.Context, gasLimit uint64, actions []*types.An
"actions", actions,
"error", err,
)
return
return err
}
results, err := k.handleMsgs(cacheCtx, msgs)
if err != nil {
k.Logger(ctx).Error(
"HandleMsgs",
"error", err,
)
return
return err
}

flush()
for _, res := range results {
ctx.EventManager().EmitEvents(res.GetEvents())
}

return nil
}

// handleMsgs Handles each message and verifies gas limit has not been exceeded.
Expand Down Expand Up @@ -120,3 +125,15 @@ func (k Keeper) safeHandle(ctx sdk.Context, msg sdk.Msg, handler baseapp.MsgServ
}()
return handler(ctx, msg)
}

// emitTriggerExecuted Emits an EventTriggerExecuted for the provided trigger.
func (k Keeper) emitTriggerExecuted(ctx sdk.Context, trigger types.Trigger, success bool) {
eventErr := ctx.EventManager().EmitTypedEvent(&types.EventTriggerExecuted{
TriggerId: fmt.Sprintf("%d", trigger.GetId()),
Owner: trigger.Owner,
Success: success,
})
if eventErr != nil {
ctx.Logger().Error("unable to emit EventTriggerExecuted", "err", eventErr)
}
}
Loading

0 comments on commit 7ece7b4

Please sign in to comment.