feat(solana-indexer) PR 8: wire the decoder to the persistence seam - #4676
feat(solana-indexer) PR 8: wire the decoder to the persistence seam#4676squadgazzz wants to merge 5 commits into
Conversation
|
Claude finished @squadgazzz's task in 4m 21s —— View job PR Review: wire the decoder to the persistence seam
This is a clean, well-reasoned PR. The I left one inline comment: the revert guard treats a missing Everything else — the reverted-tx skip, the empty-vs-non-empty watermark branch, the Note: |
| // state-changing event may be emitted for it. Failed transactions are | ||
| // delivered on purpose (the revert is an attribution signal), and a | ||
| // dedicated revert-attribution event is a later PR. | ||
| if tx.meta.as_ref().is_some_and(|meta| meta.err.is_some()) { |
There was a problem hiding this comment.
The revert guard treats a missing meta as "not reverted" and falls through to decoding, whereas a few lines down (post_token_balances, L138–142) a missing meta is handled defensively via unwrap_or_default(). That's an inconsistency in how the two paths reason about meta being absent.
If meta can ever be None on a transaction update, we'd emit state-changing events for a transaction whose success we can't actually confirm — the opposite of the safety property this guard is establishing (spec §4). In practice Yellowstone always populates meta for tx updates, so this is likely defensive-only, but if that invariant holds it would be cleaner to expect/error on the absent case; if it doesn't hold, a missing meta arguably should skip (or dead-letter) rather than decode. Worth a one-line comment stating which it is.
Description
The decoder produced settlement events and dropped them. This wires them into the
Persistenceseam: events and the slot watermark flow throughpersist_events, decode failures land in a dead-letter seam, and reverted transactions stop emitting events. ThePersistencebodies stay documented no-ops until the Postgres adapter PR.Changes
Decoder::runhands each transaction's events topersist_eventsand advances the watermark, or callswrite_watermarkwhen a transaction yields no events.slot - 1: stream resume is slot-granular (from_slot = watermark + 1), so marking a slot done while it may still have transactions in flight would skip its remainder after a crash. Redelivery after restart is absorbed by idempotent writes (spec §7, §10).meta.errset decode to nothing: a failed Solana transaction rolls back every account write, so the decoder must not emit state-changing events (spec §4). A revert-attribution event is a later PR.write_dead_letter(signature, slot, "decoder_error")entry, while the events that did decode still persist and the watermark still advances (spec §12).write_dead_letteradded toPersistence, andTransactionErrorre-exported from the wire types.How to test
New and updated unit tests.
Related issues
Stacked on #4666. The SQL bodies land with the Postgres adapter PR later.