Re-validate pending sol_purchases when blocknumber catches up#818
Open
rickyrombo wants to merge 1 commit into
Open
Re-validate pending sol_purchases when blocknumber catches up#818rickyrombo wants to merge 1 commit into
rickyrombo wants to merge 1 commit into
Conversation
A sol_purchases row is inserted with is_valid = NULL ("pending") when its
valid_after_blocknumber hasn't been indexed yet at insert time. Until now
there was no mechanism to flip pending rows to a final verdict — they
stayed NULL indefinitely even after the indexer caught up.
This adds a trigger on tracks/playlists that emits NOTIFY
'pending_purchase_revalidation' when blocknumber advances past any
pending row's valid_after_blocknumber, plus a Go listener in the Solana
indexer that consumes the notification and re-runs the existing
validatePurchase. A 5-minute sweep + startup sweep covers cases where
NOTIFY drops (no connected listener) or rows that pre-date the trigger.
The trigger does no validation work itself — it only signals which
content_id changed, so the math stays in validatePurchase as the single
source of truth. No SQL port, no parity risk with config-driven values
like NetworkTakeRate.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
tracks/playliststhat emitsNOTIFY 'pending_purchase_revalidation'whenblocknumberadvances past any pendingsol_purchasesrow'svalid_after_blocknumber. Cheap EXISTS guard so the vast majority of track/playlist updates skip the notify entirely.PurchaseRevalidator) in the Solana indexer that consumes notifications and re-runs the existingvalidatePurchasefor affected pending rows. A 5-minute sweep + startup sweep covers cases where NOTIFY drops (no connected listener) or pending rows that predate the trigger.validatePurchaseas the single source of truth — the trigger only signals whichcontent_idchanged. No SQL port, no parity drift with config-driven values likeNetworkTakeRate.Why
A
sol_purchasesrow is inserted withis_valid = NULL("pending") when itsvalid_after_blocknumberhasn't been indexed by the local node yet (MAX(blocks.number) < valid_after_blocknumberat insert time). Before this PR there was no mechanism to flip pending rows to a final verdict, so they stayedNULLindefinitely even after the indexer caught up.Notes for reviewers
sql/01_schema.sqldiff is large because the dump hadn't been regenerated since Backfill sol_purchases from usdc_purchases #815 merged — it picks up that PR'shandle_sol_purchasefunction and a few other already-merged trigger updates alongside this PR'snotify_pending_purchase_revalidation.pgxpool.MaxConnsby 1 to budget for the revalidator's persistent LISTEN connection (in addition to the existing artist_coins listener).Stop(). Cancelling the parent ctx unblocksWaitForNotification, the deferredconn.Release()returns the LISTEN connection to the pool, both goroutines exit.Test plan
make test-schema)TestParseRevalidationPayload— unit coverage for payload parsingTestRevalidatorRevalidateContent— direct call: pending row + matchingsol_paymentsflips totrueTestRevalidatorEndToEnd— full trigger → NOTIFY → LISTEN → revalidate chain viaUPDATE tracks SET blocknumberTestPurchaseValidationstill passes🤖 Generated with Claude Code