Skip to content

Commit 7fa2356

Browse files
authored
feat(server/v2/stf): delayed marshalling of typed event (#22684)
1 parent 330954e commit 7fa2356

File tree

8 files changed

+122
-69
lines changed

8 files changed

+122
-69
lines changed

server/v2/cometbft/abci.go

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ type consensus[T transaction.Tx] struct {
6262
streamingManager streaming.Manager
6363
mempool mempool.Mempool[T]
6464

65-
cfg Config
66-
chainID string
67-
indexedEvents map[string]struct{}
65+
cfg Config
66+
chainID string
67+
indexedABCIEvents map[string]struct{}
6868

6969
initialHeight uint64
7070
// this is only available after this node has committed a block (in FinalizeBlock),
@@ -105,9 +105,16 @@ func (c *consensus[T]) CheckTx(ctx context.Context, req *abciproto.CheckTxReques
105105
return nil, err
106106
}
107107

108-
events, err := intoABCIEvents(resp.Events, c.indexedEvents)
109-
if err != nil {
110-
return nil, err
108+
events := make([]abci.Event, 0)
109+
if !c.cfg.AppTomlConfig.DisableABCIEvents {
110+
events, err = intoABCIEvents(
111+
resp.Events,
112+
c.indexedABCIEvents,
113+
c.cfg.AppTomlConfig.DisableIndexABCIEvents,
114+
)
115+
if err != nil {
116+
return nil, err
117+
}
111118
}
112119

113120
cometResp := &abciproto.CheckTxResponse{
@@ -116,6 +123,7 @@ func (c *consensus[T]) CheckTx(ctx context.Context, req *abciproto.CheckTxReques
116123
GasUsed: uint64ToInt64(resp.GasUsed),
117124
Events: events,
118125
}
126+
119127
if resp.Error != nil {
120128
space, code, log := errorsmod.ABCIInfo(resp.Error, c.cfg.AppTomlConfig.Trace)
121129
cometResp.Code = code
@@ -557,7 +565,13 @@ func (c *consensus[T]) FinalizeBlock(
557565
return nil, err
558566
}
559567

560-
return finalizeBlockResponse(resp, cp, appHash, c.indexedEvents, c.cfg.AppTomlConfig.Trace)
568+
return finalizeBlockResponse(
569+
resp,
570+
cp,
571+
appHash,
572+
c.indexedABCIEvents,
573+
c.cfg.AppTomlConfig,
574+
)
561575
}
562576

563577
func (c *consensus[T]) internalFinalizeBlock(

server/v2/cometbft/config.go

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ type Config struct {
1616
func DefaultAppTomlConfig() *AppTomlConfig {
1717
return &AppTomlConfig{
1818
MinRetainBlocks: 0,
19-
IndexEvents: make([]string, 0),
2019
HaltHeight: 0,
2120
HaltTime: 0,
2221
Address: "tcp://127.0.0.1:26658",
@@ -28,22 +27,27 @@ func DefaultAppTomlConfig() *AppTomlConfig {
2827
Target: make(map[string]indexer.Config),
2928
ChannelBufferSize: 1024,
3029
},
30+
IndexABCIEvents: make([]string, 0),
31+
DisableIndexABCIEvents: false,
32+
DisableABCIEvents: false,
3133
}
3234
}
3335

3436
type AppTomlConfig struct {
35-
MinRetainBlocks uint64 `mapstructure:"min-retain-blocks" toml:"min-retain-blocks" comment:"min-retain-blocks defines the minimum block height offset from the current block being committed, such that all blocks past this offset are pruned from CometBFT. A value of 0 indicates that no blocks should be pruned."`
36-
IndexEvents []string `mapstructure:"index-events" toml:"index-events" comment:"index-events defines the set of events in the form {eventType}.{attributeKey}, which informs CometBFT what to index. If empty, all events will be indexed."`
37-
HaltHeight uint64 `mapstructure:"halt-height" toml:"halt-height" comment:"halt-height contains a non-zero block height at which a node will gracefully halt and shutdown that can be used to assist upgrades and testing."`
38-
HaltTime uint64 `mapstructure:"halt-time" toml:"halt-time" comment:"halt-time contains a non-zero minimum block time (in Unix seconds) at which a node will gracefully halt and shutdown that can be used to assist upgrades and testing."`
39-
Address string `mapstructure:"address" toml:"address" comment:"address defines the CometBFT RPC server address to bind to."`
40-
Transport string `mapstructure:"transport" toml:"transport" comment:"transport defines the CometBFT RPC server transport protocol: socket, grpc"`
41-
Trace bool `mapstructure:"trace" toml:"trace" comment:"trace enables the CometBFT RPC server to output trace information about its internal operations."`
42-
Standalone bool `mapstructure:"standalone" toml:"standalone" comment:"standalone starts the application without the CometBFT node. The node should be started separately."`
37+
MinRetainBlocks uint64 `mapstructure:"min-retain-blocks" toml:"min-retain-blocks" comment:"min-retain-blocks defines the minimum block height offset from the current block being committed, such that all blocks past this offset are pruned from CometBFT. A value of 0 indicates that no blocks should be pruned."`
38+
HaltHeight uint64 `mapstructure:"halt-height" toml:"halt-height" comment:"halt-height contains a non-zero block height at which a node will gracefully halt and shutdown that can be used to assist upgrades and testing."`
39+
HaltTime uint64 `mapstructure:"halt-time" toml:"halt-time" comment:"halt-time contains a non-zero minimum block time (in Unix seconds) at which a node will gracefully halt and shutdown that can be used to assist upgrades and testing."`
40+
Address string `mapstructure:"address" toml:"address" comment:"address defines the CometBFT RPC server address to bind to."`
41+
Transport string `mapstructure:"transport" toml:"transport" comment:"transport defines the CometBFT RPC server transport protocol: socket, grpc"`
42+
Trace bool `mapstructure:"trace" toml:"trace" comment:"trace enables the CometBFT RPC server to output trace information about its internal operations."`
43+
Standalone bool `mapstructure:"standalone" toml:"standalone" comment:"standalone starts the application without the CometBFT node. The node should be started separately."`
4344

4445
// Sub configs
45-
Mempool mempool.Config `mapstructure:"mempool" toml:"mempool" comment:"mempool defines the configuration for the SDK built-in app-side mempool implementations."`
46-
Indexer indexer.IndexingConfig `mapstructure:"indexer" toml:"indexer" comment:"indexer defines the configuration for the SDK built-in indexer implementation."`
46+
Mempool mempool.Config `mapstructure:"mempool" toml:"mempool" comment:"mempool defines the configuration for the SDK built-in app-side mempool implementations."`
47+
Indexer indexer.IndexingConfig `mapstructure:"indexer" toml:"indexer" comment:"indexer defines the configuration for the SDK built-in indexer implementation."`
48+
IndexABCIEvents []string `mapstructure:"index-abci-events" toml:"index-abci-events" comment:"index-abci-events defines the set of events in the form {eventType}.{attributeKey}, which informs CometBFT what to index. If empty, all events will be indexed."`
49+
DisableIndexABCIEvents bool `mapstructure:"disable-index-abci-events" toml:"disable-index-abci-events" comment:"disable-index-abci-events disables the ABCI event indexing done by CometBFT. Useful when relying on the SDK indexer for event indexing, but still want events to be included in FinalizeBlockResponse."`
50+
DisableABCIEvents bool `mapstructure:"disable-abci-events" toml:"disable-abci-events" comment:"disable-abci-events disables all ABCI events. Useful when relying on the SDK indexer for event indexing."`
4751
}
4852

4953
// CfgOption is a function that allows to overwrite the default server configuration.

server/v2/cometbft/query.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,11 @@ func (c *consensus[T]) handleQueryApp(ctx context.Context, path []string, req *a
6161
return nil, errorsmod.Wrap(err, "failed to simulate tx")
6262
}
6363

64-
bz, err := intoABCISimulationResponse(txResult, c.indexedEvents)
64+
bz, err := intoABCISimulationResponse(
65+
txResult,
66+
c.indexedABCIEvents,
67+
c.cfg.AppTomlConfig.DisableIndexABCIEvents,
68+
)
6569
if err != nil {
6670
return nil, errorsmod.Wrap(err, "failed to marshal txResult")
6771
}

server/v2/cometbft/server.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,9 @@ func New[T transaction.Tx](
122122
}
123123
}
124124

125-
indexEvents := make(map[string]struct{}, len(srv.config.AppTomlConfig.IndexEvents))
126-
for _, e := range srv.config.AppTomlConfig.IndexEvents {
127-
indexEvents[e] = struct{}{}
125+
indexedABCIEvents := make(map[string]struct{}, len(srv.config.AppTomlConfig.IndexABCIEvents))
126+
for _, e := range srv.config.AppTomlConfig.IndexABCIEvents {
127+
indexedABCIEvents[e] = struct{}{}
128128
}
129129

130130
sc := store.GetStateCommitment().(snapshots.CommitSnapshotter)
@@ -183,7 +183,7 @@ func New[T transaction.Tx](
183183
checkTxHandler: srv.serverOptions.CheckTxHandler,
184184
extendVote: srv.serverOptions.ExtendVoteHandler,
185185
chainID: chainID,
186-
indexedEvents: indexEvents,
186+
indexedABCIEvents: indexedABCIEvents,
187187
initialHeight: 0,
188188
queryHandlersMap: queryHandlers,
189189
getProtoRegistry: sync.OnceValues(gogoproto.MergedRegistry),

server/v2/cometbft/utils.go

Lines changed: 39 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -70,16 +70,23 @@ func finalizeBlockResponse(
7070
cp *cmtproto.ConsensusParams,
7171
appHash []byte,
7272
indexSet map[string]struct{},
73-
debug bool,
73+
cfg *AppTomlConfig,
7474
) (*abci.FinalizeBlockResponse, error) {
75-
allEvents := append(in.BeginBlockEvents, in.EndBlockEvents...)
76-
77-
events, err := intoABCIEvents(allEvents, indexSet)
78-
if err != nil {
79-
return nil, err
75+
events := make([]abci.Event, 0)
76+
77+
if !cfg.DisableABCIEvents {
78+
var err error
79+
events, err = intoABCIEvents(
80+
append(in.BeginBlockEvents, in.EndBlockEvents...),
81+
indexSet,
82+
cfg.DisableIndexABCIEvents,
83+
)
84+
if err != nil {
85+
return nil, err
86+
}
8087
}
8188

82-
txResults, err := intoABCITxResults(in.TxResults, indexSet, debug)
89+
txResults, err := intoABCITxResults(in.TxResults, indexSet, cfg)
8390
if err != nil {
8491
return nil, err
8592
}
@@ -91,6 +98,7 @@ func finalizeBlockResponse(
9198
AppHash: appHash,
9299
ConsensusParamUpdates: cp,
93100
}
101+
94102
return resp, nil
95103
}
96104

@@ -108,72 +116,65 @@ func intoABCIValidatorUpdates(updates []appmodulev2.ValidatorUpdate) []abci.Vali
108116
return valsetUpdates
109117
}
110118

111-
func intoABCITxResults(results []server.TxResult, indexSet map[string]struct{}, debug bool) ([]*abci.ExecTxResult, error) {
119+
func intoABCITxResults(
120+
results []server.TxResult,
121+
indexSet map[string]struct{},
122+
cfg *AppTomlConfig,
123+
) ([]*abci.ExecTxResult, error) {
112124
res := make([]*abci.ExecTxResult, len(results))
113125
for i := range results {
114-
events, err := intoABCIEvents(results[i].Events, indexSet)
115-
if err != nil {
116-
return nil, err
126+
var err error
127+
events := make([]abci.Event, 0)
128+
129+
if !cfg.DisableABCIEvents {
130+
events, err = intoABCIEvents(results[i].Events, indexSet, cfg.DisableIndexABCIEvents)
131+
if err != nil {
132+
return nil, err
133+
}
117134
}
118135

119136
res[i] = responseExecTxResultWithEvents(
120137
results[i].Error,
121138
results[i].GasWanted,
122139
results[i].GasUsed,
123140
events,
124-
debug,
141+
cfg.Trace,
125142
)
126143
}
127144

128145
return res, nil
129146
}
130147

131-
func intoABCIEvents(events []event.Event, indexSet map[string]struct{}) ([]abci.Event, error) {
148+
func intoABCIEvents(events []event.Event, indexSet map[string]struct{}, indexNone bool) ([]abci.Event, error) {
132149
indexAll := len(indexSet) == 0
133150
abciEvents := make([]abci.Event, len(events))
134151
for i, e := range events {
135-
attributes, err := e.Attributes()
152+
attrs, err := e.Attributes()
136153
if err != nil {
137154
return nil, err
138155
}
156+
139157
abciEvents[i] = abci.Event{
140158
Type: e.Type,
141-
Attributes: make([]abci.EventAttribute, len(attributes)),
159+
Attributes: make([]abci.EventAttribute, len(attrs)),
142160
}
143161

144-
for j, attr := range attributes {
162+
for j, attr := range attrs {
145163
_, index := indexSet[fmt.Sprintf("%s.%s", e.Type, attr.Key)]
146164
abciEvents[i].Attributes[j] = abci.EventAttribute{
147165
Key: attr.Key,
148166
Value: attr.Value,
149-
Index: index || indexAll,
167+
Index: !indexNone && (index || indexAll),
150168
}
151169
}
152170
}
153171
return abciEvents, nil
154172
}
155173

156-
func intoABCISimulationResponse(txRes server.TxResult, indexSet map[string]struct{}) ([]byte, error) {
157-
indexAll := len(indexSet) == 0
158-
abciEvents := make([]abci.Event, len(txRes.Events))
159-
for i, e := range txRes.Events {
160-
attributes, err := e.Attributes()
161-
if err != nil {
162-
return nil, err
163-
}
164-
abciEvents[i] = abci.Event{
165-
Type: e.Type,
166-
Attributes: make([]abci.EventAttribute, len(attributes)),
167-
}
168-
169-
for j, attr := range attributes {
170-
_, index := indexSet[fmt.Sprintf("%s.%s", e.Type, attr.Key)]
171-
abciEvents[i].Attributes[j] = abci.EventAttribute{
172-
Key: attr.Key,
173-
Value: attr.Value,
174-
Index: index || indexAll,
175-
}
176-
}
174+
func intoABCISimulationResponse(txRes server.TxResult, indexSet map[string]struct{}, indexNone bool) ([]byte, error) {
175+
abciEvents, err := intoABCIEvents(txRes.Events, indexSet, indexNone)
176+
if err != nil {
177+
return nil, err
177178
}
178179

179180
msgResponses := make([]*gogoany.Any, len(txRes.Resp))

server/v2/stf/core_event_service.go

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,44 @@ type eventManager struct {
3939
// Emit emits an typed event that is defined in the protobuf file.
4040
// In the future these events will be added to consensus.
4141
func (em *eventManager) Emit(tev transaction.Msg) error {
42-
res, err := TypedEventToEvent(tev)
43-
if err != nil {
44-
return err
42+
ev := event.Event{
43+
Type: gogoproto.MessageName(tev),
44+
Attributes: func() ([]event.Attribute, error) {
45+
outerEvent, err := TypedEventToEvent(tev)
46+
if err != nil {
47+
return nil, err
48+
}
49+
50+
return outerEvent.Attributes()
51+
},
52+
Data: func() (json.RawMessage, error) {
53+
buf := new(bytes.Buffer)
54+
jm := &jsonpb.Marshaler{OrigName: true, EmitDefaults: true, AnyResolver: nil}
55+
if err := jm.Marshal(buf, tev); err != nil {
56+
return nil, err
57+
}
58+
59+
return buf.Bytes(), nil
60+
},
4561
}
4662

47-
em.executionContext.events = append(em.executionContext.events, res)
63+
em.executionContext.events = append(em.executionContext.events, ev)
4864
return nil
4965
}
5066

5167
// EmitKV emits a key value pair event.
5268
func (em *eventManager) EmitKV(eventType string, attrs ...event.Attribute) error {
53-
em.executionContext.events = append(em.executionContext.events, event.NewEvent(eventType, attrs...))
69+
ev := event.Event{
70+
Type: eventType,
71+
Attributes: func() ([]event.Attribute, error) {
72+
return attrs, nil
73+
},
74+
Data: func() (json.RawMessage, error) {
75+
return json.Marshal(attrs)
76+
},
77+
}
78+
79+
em.executionContext.events = append(em.executionContext.events, ev)
5480
return nil
5581
}
5682

tools/confix/data/v2-app.toml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
[comet]
22
# min-retain-blocks defines the minimum block height offset from the current block being committed, such that all blocks past this offset are pruned from CometBFT. A value of 0 indicates that no blocks should be pruned.
33
min-retain-blocks = 0
4-
# index-events defines the set of events in the form {eventType}.{attributeKey}, which informs CometBFT what to index. If empty, all events will be indexed.
5-
index-events = []
64
# halt-height contains a non-zero block height at which a node will gracefully halt and shutdown that can be used to assist upgrades and testing.
75
halt-height = 0
86
# halt-time contains a non-zero minimum block time (in Unix seconds) at which a node will gracefully halt and shutdown that can be used to assist upgrades and testing.
@@ -15,6 +13,12 @@ transport = 'socket'
1513
trace = false
1614
# standalone starts the application without the CometBFT node. The node should be started separately.
1715
standalone = false
16+
# index-abci-events defines the set of events in the form {eventType}.{attributeKey}, which informs CometBFT what to index. If empty, all events will be indexed.
17+
index-abci-events = []
18+
# disable-index-abci-events disables the ABCI event indexing done by CometBFT. Useful when relying on the SDK indexer for event indexing, but still want events to be included in FinalizeBlockResponse.
19+
disable-index-abci-events = false
20+
# disable-abci-events disables all ABCI events. Useful when relying on the SDK indexer for event indexing.
21+
disable-abci-events = false
1822

1923
# mempool defines the configuration for the SDK built-in app-side mempool implementations.
2024
[comet.mempool]

tools/confix/migrations.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ type v2KeyChangesMap map[string][]string
4141
var v2KeyChanges = v2KeyChangesMap{
4242
"minimum-gas-prices": []string{"server.minimum-gas-prices"},
4343
"min-retain-blocks": []string{"comet.min-retain-blocks"},
44-
"index-events": []string{"comet.index-events"},
44+
"index-events": []string{"comet.index-abci-events"},
4545
"halt-height": []string{"comet.halt-height"},
4646
"halt-time": []string{"comet.halt-time"},
4747
"app-db-backend": []string{"store.app-db-backend"},

0 commit comments

Comments
 (0)