diff --git a/CHANGELOG.md b/CHANGELOG.md index d1a5ea78a1..f2b42f87e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Bug Fixes * (x/foundation) [\#1061](https://github.com/Finschia/finschia-sdk/pull/1061) Make x/foundation MsgExec propagate events (backport #1053) +* (baseapp) [\#1075](https://github.com/cosmos/cosmos-sdk/pull/1075) Add `events.GetAttributes` and `event.GetAttribute` methods to simplify the retrieval of an attribute from event(s) (backport cosmos/cosmos-sdk#14356) ### Removed diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 299ba77670..98479a400a 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -814,7 +814,7 @@ func (app *BaseApp) runMsgs(ctx sdk.Context, msgs []sdk.Msg) (*sdk.Result, error } // create message events - msgEvents := createEvents(msg).AppendEvents(msgResult.GetEvents()) + msgEvents := createEvents(msgResult.GetEvents(), msg) // append message events, data and logs // @@ -838,7 +838,7 @@ func (app *BaseApp) runMsgs(ctx sdk.Context, msgs []sdk.Msg) (*sdk.Result, error }, nil } -func createEvents(msg sdk.Msg) sdk.Events { +func createEvents(events sdk.Events, msg sdk.Msg) sdk.Events { eventMsgName := sdk.MsgTypeURL(msg) msgEvent := sdk.NewEvent(sdk.EventTypeMessage, sdk.NewAttribute(sdk.AttributeKeyAction, eventMsgName)) @@ -847,12 +847,15 @@ func createEvents(msg sdk.Msg) sdk.Events { msgEvent = msgEvent.AppendAttributes(sdk.NewAttribute(sdk.AttributeKeySender, msg.GetSigners()[0].String())) } - // here we assume that routes module name is the second element of the route - // e.g. "cosmos.bank.v1beta1.MsgSend" => "bank" - moduleName := strings.Split(eventMsgName, ".") - if len(moduleName) > 1 { - msgEvent = msgEvent.AppendAttributes(sdk.NewAttribute(sdk.AttributeKeyModule, moduleName[1])) + // verify that events have no module attribute set + if _, found := events.GetAttributes(sdk.AttributeKeyModule); !found { + // here we assume that routes module name is the second element of the route + // e.g. "cosmos.bank.v1beta1.MsgSend" => "bank" + moduleName := strings.Split(eventMsgName, ".") + if len(moduleName) > 1 { + msgEvent = msgEvent.AppendAttributes(sdk.NewAttribute(sdk.AttributeKeyModule, moduleName[1])) + } } - return sdk.Events{msgEvent} + return sdk.Events{msgEvent}.AppendEvents(events) } diff --git a/types/events.go b/types/events.go index 9e6c879624..9228600207 100644 --- a/types/events.go +++ b/types/events.go @@ -197,6 +197,17 @@ func (e Event) AppendAttributes(attrs ...Attribute) Event { return e } +// GetAttribute returns an attribute for a given key present in an event. +// If the key is not found, the boolean value will be false. +func (e Event) GetAttribute(key string) (Attribute, bool) { + for _, attr := range e.Attributes { + if string(attr.Key) == key { + return Attribute{Key: string(attr.Key), Value: string(attr.Value)}, true + } + } + return Attribute{}, false +} + // AppendEvent adds an Event to a slice of events. func (e Events) AppendEvent(event Event) Events { return append(e, event) @@ -229,6 +240,19 @@ func toBytes(i interface{}) []byte { } } +// GetAttributes returns all attributes matching a given key present in events. +// If the key is not found, the boolean value will be false. +func (e Events) GetAttributes(key string) ([]Attribute, bool) { + attrs := make([]Attribute, 0) + for _, event := range e { + if attr, found := event.GetAttribute(key); found { + attrs = append(attrs, attr) + } + } + + return attrs, len(attrs) > 0 +} + // Common event types and attribute keys var ( EventTypeTx = "tx" diff --git a/types/events_test.go b/types/events_test.go index e461376294..45513e6fd9 100644 --- a/types/events_test.go +++ b/types/events_test.go @@ -43,6 +43,25 @@ func (s *eventsTestSuite) TestAppendAttributes() { s.Require().Equal(e, sdk.NewEvent("transfer", sdk.NewAttribute("sender", "foo"), sdk.NewAttribute("recipient", "bar"))) } +func (s *eventsTestSuite) TestGetAttributes() { + e := sdk.NewEvent("transfer", sdk.NewAttribute("sender", "foo")) + e = e.AppendAttributes(sdk.NewAttribute("recipient", "bar")) + attr, found := e.GetAttribute("recipient") + s.Require().True(found) + s.Require().Equal(attr, sdk.NewAttribute("recipient", "bar")) + _, found = e.GetAttribute("foo") + s.Require().False(found) + + events := sdk.Events{e}.AppendEvent(sdk.NewEvent("message", sdk.NewAttribute("sender", "bar"))) + attrs, found := events.GetAttributes("sender") + s.Require().True(found) + s.Require().Len(attrs, 2) + s.Require().Equal(attrs[0], sdk.NewAttribute("sender", "foo")) + s.Require().Equal(attrs[1], sdk.NewAttribute("sender", "bar")) + _, found = events.GetAttributes("foo") + s.Require().False(found) +} + func (s *eventsTestSuite) TestEmptyEvents() { s.Require().Equal(sdk.EmptyEvents(), sdk.Events{}) }