refactor(abci): add msg index to event (#15845)
Co-authored-by: Facundo Medica <14063057+facundomedica@users.noreply.github.com> Co-authored-by: Facundo Medica <facundomedica@gmail.com>
This commit is contained in:
parent
295c261b18
commit
8e896f4d31
@ -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
|
||||
|
||||
|
||||
@ -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`).
|
||||
|
||||
@ -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{})
|
||||
|
||||
@ -3,7 +3,7 @@ package baseapp
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
"strconv"
|
||||
|
||||
errorsmod "cosmossdk.io/errors"
|
||||
"cosmossdk.io/log"
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
@ -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)
|
||||
@ -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
|
||||
|
||||
@ -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{})
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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"
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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"
|
||||
@ -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 {
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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",
|
||||
@ -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
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -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",
|
||||
@ -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
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user