test(postage): prove chain-state buffering equivalence (#5343)#5481
Draft
martinconic wants to merge 1 commit into
Draft
test(postage): prove chain-state buffering equivalence (#5343)#5481martinconic wants to merge 1 commit into
martinconic wants to merge 1 commit into
Conversation
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.
Checklist
Summary
Test-only PR. Adds regression coverage for #5343 (postage batch snapshot optimization), which is already merged and on production.
#5343 changed
batchserviceso thatUpdatePrice/UpdateBlockNumber no longer callstorer.PutChainStateper event. Instead the chain state is buffered inpendingChainState(set inTransactionStart) and flushed once per page atTransactionEnd.PutChainStateis what runscleanup(evict expired batches) andcomputeRadius`.A concern was raised: can the price fluctuate up/down within a window such that we skip
PutChainState, and therefore skip cleanup / radius change?These tests demonstrate the deferral is safe.
PutChainStateis not skipped — it is batched to once per page — and the final result is identical to the old per-event behaviour because:TotalAmountis monotonically non-decreasing, so a single cleanup at the end of a window evicts the same superset;computeRadiusis a pure function of the final batch set and depths (Create/TopUp/UpdateDepth recompute it immediately, never deferred);pendingChainStatealiases the batchstore's in-memory chain state, so mid-window batch operations still observe the accrued amount.What the tests do
Each test replays one identical event stream three ways against three independent real batchstores and asserts the final batch set, radius and chain state are byte-for-byte identical:
per-event — no transaction; every update persists immediately (pre-feat: optimize postage batch snapshot #5343 behaviour, the reference)
single-tx — whole stream buffered, a single flush at the end
per-page — one flush per page at
TransactionEnd(feat: optimize postage batch snapshot #5343 behaviour)TestChainStateBufferingEquivalence— deterministic; exercises Create, TopUp, UpdateDepth and UpdatePrice (price up 1→10 then down 10→2), evicting two batches while a third (topped up and diluted) survives and drives the final radius. Includes guards so the scenario can't silently become vacuous.TestChainStateBufferingEquivalenceRandomized— seeded fuzz (40 iterations) over random prices, top-ups, depth changes and random page boundaries. Top-ups/depth changes target only "permanent" batches whose value exceeds any reachableTotalAmount, so they're valid in all modes regardless of how flush timing shifts ephemeral evictions.The tests use the real
batchstoreon an in-memory leveldb state store. The map-backed mock state store can't be used: it iterates in random order, which breakscleanup's value-ordered early-stop and yields non-deterministic evictions.Validation
go test ./pkg/postage/batchservice/...passes, including under-racego vetclean, gofumpt-formattedTransactionEndskip the flush made the buffered modes diverge (3 surviving batches / radius 5 vs. the correct 1 / radius 3), and the tests caught itAI Disclosure