backport: implement the ADR 075 /events method (#7965) (#9497)

* rpc: implement the ADR 075 /events method (#7965)

This method implements the eventlog extension interface to expose ABCI metadata
to the log for query processing. Only the types that have ABCI events need to
implement this.

- Add an event log to the environment
- Add a sketch of the handler method
- Add an /events RPCFunc to the route map
- Implement query logic
- Subscribe to pubsub if confingured, handle termination

* add MatchesEvents test

* add TODO due to backport sequence

Co-authored-by: M. J. Fromberger <fromberger@interchain.io>
This commit is contained in:
mmsqe
2022-10-04 22:52:27 +02:00
committed by GitHub
co-authored by M. J. Fromberger
parent 069e402aa1
commit d47b675cda
10 changed files with 315 additions and 1 deletions
+33
View File
@@ -2,6 +2,7 @@ package types
import (
"fmt"
"strings"
abci "github.com/tendermint/tendermint/abci/types"
tmjson "github.com/tendermint/tendermint/libs/json"
@@ -68,6 +69,11 @@ type EventDataNewBlock struct {
ResultEndBlock abci.ResponseEndBlock `json:"result_end_block"`
}
// ABCIEvents implements the eventlog.ABCIEventer interface.
func (e EventDataNewBlock) ABCIEvents() []abci.Event {
return append(e.ResultBeginBlock.Events, e.ResultEndBlock.Events...)
}
type EventDataNewBlockHeader struct {
Header Header `json:"header"`
@@ -76,6 +82,11 @@ type EventDataNewBlockHeader struct {
ResultEndBlock abci.ResponseEndBlock `json:"result_end_block"`
}
// ABCIEvents implements the eventlog.ABCIEventer interface.
func (e EventDataNewBlockHeader) ABCIEvents() []abci.Event {
return append(e.ResultBeginBlock.Events, e.ResultEndBlock.Events...)
}
type EventDataNewEvidence struct {
Evidence Evidence `json:"evidence"`
@@ -87,6 +98,15 @@ type EventDataTx struct {
abci.TxResult
}
// ABCIEvents implements the eventlog.ABCIEventer interface.
func (e EventDataTx) ABCIEvents() []abci.Event {
base := []abci.Event{
eventWithAttr(TxHashKey, fmt.Sprintf("%X", Tx(e.Tx).Hash())),
eventWithAttr(TxHeightKey, fmt.Sprintf("%d", e.Height)),
}
return append(base, e.Result.Events...)
}
// NOTE: This goes into the replay WAL
type EventDataRoundState struct {
Height int64 `json:"height"`
@@ -181,3 +201,16 @@ type BlockEventPublisher interface {
type TxEventPublisher interface {
PublishEventTx(EventDataTx) error
}
// eventWithAttr constructs a single abci.Event with a single attribute.
// The type of the event and the name of the attribute are obtained by
// splitting the event type on period (e.g., "foo.bar").
func eventWithAttr(etype, value string) abci.Event {
parts := strings.SplitN(etype, ".", 2)
return abci.Event{
Type: parts[0],
Attributes: []abci.EventAttribute{{
Key: parts[1], Value: value,
}},
}
}
+16
View File
@@ -7,6 +7,22 @@ import (
"github.com/stretchr/testify/assert"
)
// Verify that the event data types satisfy their shared interface.
// TODO: add EventDataBlockSyncStatus and EventDataStateSyncStatus
// when backport #6700 and #6755.
var (
_ TMEventData = EventDataCompleteProposal{}
_ TMEventData = EventDataNewBlock{}
_ TMEventData = EventDataNewBlockHeader{}
_ TMEventData = EventDataNewEvidence{}
_ TMEventData = EventDataNewRound{}
_ TMEventData = EventDataRoundState{}
_ TMEventData = EventDataTx{}
_ TMEventData = EventDataValidatorSetUpdates{}
_ TMEventData = EventDataVote{}
_ TMEventData = EventDataString("")
)
func TestQueryTxFor(t *testing.T) {
tx := Tx("foo")
assert.Equal(t,