Skip to content

Commit

Permalink
refactor(abci): add msg index to event (#15845)
Browse files Browse the repository at this point in the history
Co-authored-by: Facundo Medica <14063057+facundomedica@users.noreply.github.com>
Co-authored-by: Facundo Medica <facundomedica@gmail.com>
  • Loading branch information
3 people authored Apr 24, 2023
1 parent 295c261 commit 8e896f4
Show file tree
Hide file tree
Showing 10 changed files with 45 additions and 22 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@ Ref: https://keepachangelog.com/en/1.0.0/

* (x/staking) [#15701](https://github.com/cosmos/cosmos-sdk/pull/15701) `HistoricalInfoKey` now has a binary format.
* (grpc-web) [#14652](https://github.com/cosmos/cosmos-sdk/pull/14652) Use same port for gRPC-Web and the API server.
* (abci) [#15845](https://github.com/cosmos/cosmos-sdk/pull/15845) Add `msg_index` to all event attributes to associate events and messages
* (abci) [#15845](https://github.com/cosmos/cosmos-sdk/pull/15845) Remove duplicating events in `logs`

### CLI Breaking Changes

Expand Down
4 changes: 4 additions & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ simd config migrate v0.48

More information about [confix](https://docs.cosmos.network/main/tooling/confix).

#### Events

The log section of abci.TxResult is not populated in the case of successful msg(s) execution. Instead a new attribute is added to all messages indicating the `msg_index` which identifies which events and attributes relate the same transaction

#### gRPC-Web

gRPC-Web is now listening to the same address as the gRPC Gateway API server (default: `localhost:1317`).
Expand Down
2 changes: 1 addition & 1 deletion baseapp/abci_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,7 @@ func TestABCI_DeliverTx(t *testing.T) {
events := res.GetEvents()
require.Len(t, events, 3, "should contain ante handler, message type and counter events respectively")
require.Equal(t, sdk.MarkEventsToIndex(counterEvent("ante_handler", counter).ToABCIEvents(), map[string]struct{}{})[0], events[0], "ante handler event")
require.Equal(t, sdk.MarkEventsToIndex(counterEvent(sdk.EventTypeMessage, counter).ToABCIEvents(), map[string]struct{}{})[0], events[2], "msg handler update counter event")
require.Equal(t, sdk.MarkEventsToIndex(counterEvent(sdk.EventTypeMessage, counter).ToABCIEvents(), map[string]struct{}{})[0].Attributes[0], events[2].Attributes[0], "msg handler update counter event")
}

suite.baseApp.EndBlock(abci.RequestEndBlock{})
Expand Down
12 changes: 7 additions & 5 deletions baseapp/baseapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package baseapp
import (
"fmt"
"sort"
"strings"
"strconv"

errorsmod "cosmossdk.io/errors"
"cosmossdk.io/log"
Expand Down Expand Up @@ -775,7 +775,6 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte) (gInfo sdk.GasInfo, re
// Handler does not exist for a given message route. Otherwise, a reference to a
// Result is returned. The caller must not commit state if an error is returned.
func (app *BaseApp) runMsgs(ctx sdk.Context, msgs []sdk.Msg, mode runTxMode) (*sdk.Result, error) {
msgLogs := make(sdk.ABCIMessageLogs, 0, len(msgs))
events := sdk.EmptyEvents()
var msgResponses []*codectypes.Any

Expand All @@ -799,10 +798,15 @@ func (app *BaseApp) runMsgs(ctx sdk.Context, msgs []sdk.Msg, mode runTxMode) (*s
// create message events
msgEvents := createEvents(msgResult.GetEvents(), msg)

// append message events, data and logs
// append message events and data
//
// Note: Each message result's data must be length-prefixed in order to
// separate each result.
for j, event := range msgEvents {
// append message index to all events
msgEvents[j] = event.AppendAttributes(sdk.NewAttribute("msg_index", strconv.Itoa(i)))
}

events = events.AppendEvents(msgEvents)

// Each individual sdk.Result that went through the MsgServiceRouter
Expand All @@ -818,7 +822,6 @@ func (app *BaseApp) runMsgs(ctx sdk.Context, msgs []sdk.Msg, mode runTxMode) (*s
msgResponses = append(msgResponses, msgResponse)
}

msgLogs = append(msgLogs, sdk.NewABCIMessageLog(uint32(i), msgResult.Log, msgEvents))
}

data, err := makeABCIData(msgResponses)
Expand All @@ -828,7 +831,6 @@ func (app *BaseApp) runMsgs(ctx sdk.Context, msgs []sdk.Msg, mode runTxMode) (*s

return &sdk.Result{
Data: data,
Log: strings.TrimSpace(msgLogs.String()),
Events: events.ToABCIEvents(),
MsgResponses: msgResponses,
}, nil
Expand Down
2 changes: 1 addition & 1 deletion baseapp/streaming_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func TestABCI_MultiListener_StateChanges(t *testing.T) {
events := res.GetEvents()
require.Len(t, events, 3, "should contain ante handler, message type and counter events respectively")
require.Equal(t, sdk.MarkEventsToIndex(counterEvent("ante_handler", counter).ToABCIEvents(), map[string]struct{}{})[0], events[0], "ante handler event")
require.Equal(t, sdk.MarkEventsToIndex(counterEvent(sdk.EventTypeMessage, counter).ToABCIEvents(), map[string]struct{}{})[0], events[2], "msg handler update counter event")
require.Equal(t, sdk.MarkEventsToIndex(counterEvent(sdk.EventTypeMessage, counter).ToABCIEvents(), map[string]struct{}{})[0].Attributes[0], events[2].Attributes[0], "msg handler update counter event")
}

suite.baseApp.EndBlock(abci.RequestEndBlock{})
Expand Down
1 change: 1 addition & 0 deletions docs/docs/core/08-events.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ An Event contains:

* A `type` to categorize the Event at a high-level; for example, the Cosmos SDK uses the `"message"` type to filter Events by `Msg`s.
* A list of `attributes` are key-value pairs that give more information about the categorized Event. For example, for the `"message"` type, we can filter Events by key-value pairs using `message.action={some_action}`, `message.module={some_module}` or `message.sender={some_sender}`.
* A `msg_index` to identify which messages relate to the same transaction

:::tip
To parse the attribute values as strings, make sure to add `'` (single quotes) around each attribute value.
Expand Down
21 changes: 17 additions & 4 deletions tests/e2e/auth/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import (
"strings"
"testing"

"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"

"cosmossdk.io/depinject"
"cosmossdk.io/math"
abci "github.com/cometbft/cometbft/abci/types"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
Expand Down Expand Up @@ -440,7 +440,9 @@ func (s *E2ETestSuite) TestCLIQueryTxCmdByHash() {
var result sdk.TxResponse
s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &result))
s.Require().NotNil(result.Height)
s.Require().Contains(result.RawLog, tc.rawLogContains)
if ok := s.deepContains(result.Events, tc.rawLogContains); !ok {
s.Require().Fail("raw log does not contain the expected value, expected value: %s", tc.rawLogContains)
}
}
})
}
Expand Down Expand Up @@ -1961,3 +1963,14 @@ func (s *E2ETestSuite) getBalances(clientCtx client.Context, addr sdk.AccAddress
startTokens := balRes.Balances.AmountOf(denom)
return startTokens
}

func (s *E2ETestSuite) deepContains(events []abci.Event, value string) bool {
for _, e := range events {
for _, attr := range e.Attributes {
if strings.Contains(attr.Value, value) {
return true
}
}
}
return false
}
7 changes: 4 additions & 3 deletions tests/e2e/group/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

// without this import amino json encoding will fail when resolving any types
_ "cosmossdk.io/api/cosmos/group/v1"

"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
Expand Down Expand Up @@ -202,9 +203,9 @@ func (s *E2ETestSuite) TearDownSuite() {
}

func (s *E2ETestSuite) getProposalIDFromTxResponse(txResp sdk.TxResponse) string {
s.Require().Greater(len(txResp.Logs), 0)
s.Require().NotNil(txResp.Logs[0].Events)
events := txResp.Logs[0].Events
s.Require().Greater(len(txResp.Events), 0)
s.Require().NotNil(txResp.Events[0])
events := txResp.Events
createProposalEvent, _ := sdk.TypedEventToEvent(&group.EventSubmitProposal{})

for _, e := range events {
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/staking/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ func (s *E2ETestSuite) TestNewCreateValidatorCmd() {
s.Require().Equal(tc.expectedCode, txResp.Code, out.String())

var hadEvent bool
events := txResp.Logs[0].GetEvents()
events := txResp.Events
for i := 0; i < len(events); i++ {
if events[i].GetType() == "create_validator" {
attributes := events[i].GetAttributes()
Expand Down
14 changes: 7 additions & 7 deletions tests/e2e/tx/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,12 +289,12 @@ func (s *E2ETestSuite) TestGetTxEvents_GRPC() {
"with pagination",
&tx.GetTxsEventRequest{
Query: bankMsgSendEventAction,
Page: 2,
Page: 1,
Limit: 2,
},
false,
"",
1,
2,
},
{
"with multi events",
Expand All @@ -317,13 +317,13 @@ func (s *E2ETestSuite) TestGetTxEvents_GRPC() {
s.Require().NoError(err)
s.Require().GreaterOrEqual(len(grpcRes.Txs), 1)
s.Require().Equal("foobar", grpcRes.Txs[0].Body.Memo)
s.Require().Equal(len(grpcRes.Txs), tc.expLen)
s.Require().Equal(tc.expLen, len(grpcRes.Txs))

// Make sure fields are populated.
// ref: https://github.com/cosmos/cosmos-sdk/issues/8680
// ref: https://github.com/cosmos/cosmos-sdk/issues/8681
s.Require().NotEmpty(grpcRes.TxResponses[0].Timestamp)
s.Require().NotEmpty(grpcRes.TxResponses[0].RawLog)
s.Require().Empty(grpcRes.TxResponses[0].RawLog) // logs are empty if the transactions are successful
}
})
}
Expand Down Expand Up @@ -352,9 +352,9 @@ func (s *E2ETestSuite) TestGetTxEvents_GRPCGateway() {
},
{
"with pagination",
fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?query=%s&page=%d&limit=%d", val.APIAddress, bankMsgSendEventAction, 2, 2),
fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?query=%s&page=%d&limit=%d", val.APIAddress, bankMsgSendEventAction, 1, 2),
false,
"", 1,
"", 2,
},
{
"valid request: order by asc",
Expand Down Expand Up @@ -474,7 +474,7 @@ func (s *E2ETestSuite) TestGetTx_GRPCGateway() {
// ref: https://github.com/cosmos/cosmos-sdk/issues/8680
// ref: https://github.com/cosmos/cosmos-sdk/issues/8681
s.Require().NotEmpty(result.TxResponse.Timestamp)
s.Require().NotEmpty(result.TxResponse.RawLog)
s.Require().Empty(result.TxResponse.RawLog) // logs are empty on successful transactions
}
})
}
Expand Down

0 comments on commit 8e896f4

Please sign in to comment.