fix(sei-tendermint): publish Autobahn block events (CON-352) - #3998
fix(sei-tendermint): publish Autobahn block events (CON-352)#3998shemnon wants to merge 1 commit into
Conversation
Publish committed Autobahn blocks and transactions to the event bus so indexer-backed RPC methods can observe inclusion. - Wire the node event bus into validator and fullnode Giga routers - Publish block, header, and transaction events after application commit - Cover transaction indexing, empty blocks, result-count mismatches, and broadcast_tx_commit end to end
PR SummaryMedium Risk Overview After Node setup passes the shared Reviewed by Cursor Bugbot for commit 1c31e68. Bugbot is set up for automated code reviews on this repo. Configure here. |
|
The latest Buf updates on your PR. Results from workflow Buf / buf (pull_request).
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3998 +/- ##
==========================================
- Coverage 59.10% 58.02% -1.08%
==========================================
Files 2305 2206 -99
Lines 197039 185504 -11535
==========================================
- Hits 116452 107635 -8817
+ Misses 69817 68037 -1780
+ Partials 10770 9832 -938
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 1c31e68. Configure here.
| return nil, fmt.Errorf("app.Commit(): %w", err) | ||
| } | ||
| // Indexer-backed RPCs (broadcast_tx_commit, /tx) wait on these events. | ||
| r.publishExecutedBlockEvents(b, proposerAddress, resp) |
There was a problem hiding this comment.
Missing Autobahn event reindex path
Medium Severity
Autobahn now publishes indexer events only inside executeBlock after app.Commit, but restart recovery advances from the app tip without re-publishing the last committed height. A crash after commit and before those events are indexed permanently skips that block for /tx and broadcast_tx_commit. CometBFT covers this with handshake replayEvents; Autobahn skips the handshaker.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 1c31e68. Configure here.
There was a problem hiding this comment.
The wiring is sound: the event bus reaches both Giga roles through the single buildGigaRouter choke point, events are published after app.Commit in the same order (and with the same sanity-check panic) as the classic state.FireEvents path, and the added tests cover indexing, empty blocks, count mismatch, and broadcast_tx_commit end to end. Two non-blocking notes: the published block carries an empty Block.Hash(), and the publish sequence is a verbatim copy of state.FireEvents.
Findings: 0 blocking | 2 non-blocking | 1 posted inline
Blockers
- None at the file/PR level.
Non-blocking
- [suggestion]
publishExecutedBlockEventsis a near-verbatim copy of the exportedstate.FireEvents(sei-tendermint/internal/state/execution.go:643) — same three publish blocks, same panic message, same//nolint:goseccomment — minus the evidence and validator-update publishes. Nothing keeps the two in sync, so a future fix toFireEvents(a new event type, an index/height fix) silently misses the Autobahn path. Consider callingstate.FireEventsdirectly, or extracting the shared sequence into a small package both can depend on. Worth checking the import direction first:internal/state's non-test deps (eventbus, mempool, store, proxy, pubsub) do not reachinternal/p2ptoday, so the import appears cycle-free. - 1 suggestion(s)/nit(s) flagged inline on specific lines.
| } | ||
| eventBus := r.cfg.EventBus | ||
|
|
||
| if err := eventBus.PublishEventNewBlock(types.EventDataNewBlock{ |
There was a problem hiding this comment.
[suggestion] The translated block's header has no ValidatorsHash, so Block.Hash() returns nil for these events (types/block.go:511 short-circuits on len(h.ValidatorsHash) == 0). Only BlockID carries the real Autobahn hash. That was harmless while nothing consumed these events, but publishing them makes consumers that key off Block.Hash() start emitting zero hashes rather than nothing: the RPC event log subscribes to all bus events and is on by default (event-log-window-size = 30s), and evmrpc's block filters read exactly that field — getBlockHeadersAfter does common.BytesToHash(block.Block.Hash()) (evmrpc/filter.go:695), so eth_newBlockFilter + eth_getFilterChanges will now return 0x000…0 for every Autobahn block, which clients can mistake for a real hash. Same applies to websocket tm.event='NewBlock' subscribers. Either populate the header fields the hash derives from, or switch the affected consumers to BlockID (and note the limitation on translateGlobalBlock, whose doc currently lists only the evmrpc receipt path as a caller).


Publish committed Autobahn blocks and transactions to the event bus so indexer-backed RPC methods can observe inclusion.
Summary
Autobahn committed blocks were not publishing block and transaction events. As a result, the transaction indexer never observed Autobahn transactions, causing indexer-backed RPC methods such as broadcast_tx_commit and /tx
to wait until timeout.
Testing