!5187test-quality-accounting → develop33516874aa

Seeded accounting conservation campaigns

AI-generatedEverything on this page was written by an AI agent from the diff: the summaries, the narration, the diagrams, the flags and the glossary. It can be wrong or incomplete, so check it against the code before you rely on it.

6commits
4files
854lines changed
854lines to read
0production lines
9property tests
4 / 32seeds fast / deep

Where the diff is

5-minute explainer

What changed

Ledger oracle

pool + pending + paid + Reserve fee = in; ±1 unit breaks it.

pool+pending+paid+fee= inexpected values from observed inputs + payouts only81 · 5 · 10 · 5 ≠ 100 → detected

Pool flow

24 seeded add / stage / withdraw steps; only dust rejections tolerated.

ASAWS✗AW…→ 10,000 bps
  • adds, completions, withdrawals each > 0
  • seeding deposit must mint

Swap flow

Pool + Reserve fee conserved both ways; LP units fixed.

  • 12 swaps, alternating RUNE↔ETH
  • every third split in 3 sub-swaps (swapper only)
  • ETH→ETH rejected, no trace

Persisted stream

V2 stream via the advanced queue; State.In/Out reconciled each block.

blk 1blk 2blk 3blk 4 → 1 outboundblk 5 · no repeat

no outbound before the last sub-swap

Pending liabilities

Staged deposit refunds once; native ADD lands as pending.

  • staged RUNE refunded once, repeat errors
  • account −x · Asgard +x · pool+LP pending x
  • seed 15: 664 units × 1 bps → reject, no change

Refund obligation

One bounded outbound across the whole TxOutDelayMax window.

1 outbound✗ retrynow+17,280 blocksvault DOGE unchanged until observed

Vault transfer

Retiring + active Asgard total survives keeper round-trips.

retiring −moveactive +movesum = initial

bookkeeping only · no migrate outbound

Seeds + CI

Seeds 1,2,3,15 by default; 32-seed scheduled deep job.

12315

fast = 4 · campaign = 32 · SEEDS ≤ 256

Line by line · every changed logic line, narrated

14:51runtime
17code chapters
100%logic lines narrated (717/717)
9flagged spots
speed

Chapters

What to check

Ask an AI about this change

Chat assistantClaude, ChatGPT, … (reads a link)

Coding agentClaude Code, Cursor, … (reads the repo)

The context file is context.md. Use Copy with context for an AI that can't open links; it pastes the whole file in.

Glossary

Accounting oracle
accountingLedgerBalanced: pool + pending + paid + Reserve fee must equal everything that came in, per side. Built from observed balances, never from the code's own maths. handler_accounting_property_test.go ↗
Advanced swap queue
The swap queue used while EnableAdvSwapQueue is on. A V2 stream's running input and output live in msg.State until settleSwap pays one outbound. docs/swap-guide/advanced-swap-queue.md ↗ streaming-swaps.md ↗
Asgard vault
A TSS-controlled vault holding L1 coins. A retiring one hands funds to the active one during churn; the vault test only checks the bookkeeping. types/type_vault.go ↗
Basis points (bps)
Hundredths of a percent. A withdrawal of 10,000 bps takes the whole position; 1 bps of 664 units rounds to zero.
gocheck
The gopkg.in/check.v1 test framework. AccountingPropertySuite is a gocheck suite, selected with -check.f, and runs inside go test ./x/thorchain. pkg.go.dev ↗
L1SlipMinBps
Mimir for the minimum slip per streaming sub-swap. Set to 10 here so admission runs the deposit cap on stream quantity. docs/mimir.md ↗
LP units
A liquidity provider's share of a pool. Swaps must not change them; withdrawals burn them in proportion to the basis points asked for. docs/concepts/math.md ↗ withdraw.go ↗
Pending inbound
RUNE or asset staged by one leg of a split (asymmetric-arrival) liquidity add. It mints no LP units yet but is still owed to the depositor. handler_add_liquidity.go ↗
Reserve
The protocol's RUNE module account. Swap fees in RUNE go there, so the oracle counts its growth as the fee term. docs/concepts/economic-model.md ↗
Seed
The math/rand source for one campaign run. THORNODE_ACCOUNTING_SEED pins one; THORNODE_ACCOUNTING_SEEDS runs 1..N (default 4, with seed 15 as the fourth). scripts/test-accounting-property.sh ↗
TxOutDelayMax
Most blocks an outbound may be delayed (17,280 by default). The refund test scans every height in that window for duplicate outbounds. docs/mimir.md ↗