Skip to content

test: Cover Vault dust custody end-to-end - #8019

Closed
Tapanito wants to merge 3 commits into
tapanito/vault-dust-overlayfrom
tapanito/vault-dust-tests
Closed

test: Cover Vault dust custody end-to-end#8019
Tapanito wants to merge 3 commits into
tapanito/vault-dust-overlayfrom
tapanito/vault-dust-tests

Conversation

@Tapanito

Copy link
Copy Markdown
Contributor

Summary

Final slice of the Vault-dust custody design, split out from #7970. Adds the behavior test suites that exercise sfDust, DustSplit, and the xrpl::vault_dust:: overlay together.

Stack:

New suites

  • VaultRoundingTrustlineDust_test: sub-quantum credit accounting on the trust-line layer, DustSplit contract asserts (Drain on receiver forbidden, issuer-side policy forbidden), accountHolds balance-only contract, ordinary payments never acquire sfDust, VaultDelete blocked when sfDust != 0.
  • VaultRounding_test: Vault-facing rounding scenarios (deposits, withdrawals, terminal drain, non-terminal Override after a dust-producing repayment, sender-leg Override dust reporting on non-terminal removal, sender-leg Drain end-to-end via a defaulted-loan terminal withdrawal, ValidVault regression around extended pseudo-account deltas).
  • VaultDustProbe: shared instrumentation used by both suites to inspect sfBalance / sfDust and the reported per-leg delta pair.

Additional coverage

  • VaultHelpers_test: exercises the vault_dust:: overlay dispatchers and their eligibility gate.
  • LoanPay_test: dust-producing repayment paths.

Test plan

  • VaultRoundingTrustlineDust_test passes with 0 failures
  • VaultRounding_test passes with 0 failures
  • VaultHelpers_test passes with 0 failures
  • LoanPay_test passes with 0 failures
  • Existing Vault / Loan suites remain green (regression check)

Introduces DustSplit, a per-leg dust policy struct threaded through
directSendNoFeeIOU / accountSend / accountSendMulti / doWithdraw, plus
the read-side creditBalanceExact helper.

DustSplit models an IOU payment as two independent trust-line touches
(sender leg, receiver leg). Each leg carries an optional LegPolicy in
one of two modes:

- Override: caller supplies the target STAmount scale; the credit path
  computes the extended balance (sfBalance + sfDust) in the leg's
  non-issuer party's terms, applies the delta, and re-splits at the
  requested scale. Any stranded sfDust above one quantum at the new
  scale is promoted into sfBalance as part of the same re-split, so
  scale-refinement is fold-in-place.
- Drain (sender-leg only): folds all sender-line sfDust into the
  outgoing transfer, leaving sfBalance == 0 and sfDust == 0. Used for
  terminal removals.

Reports back the observed per-leg deltas (balanceDelta and signed
dustDelta) in the leg-party's own sign convention, letting the caller
reconcile its own bookkeeping without re-reading the trust line.

directSendNoFeeIOU is the single site where sfDust writes happen.
Feature-gated: directSendNoFeeIOU asserts featureLendingProtocolV1_1
on any non-empty DustSplit; without the amendment the classic code
path runs unchanged.

creditBalanceExact reads the extended balance in the holder's terms;
classic accountHolds remains STAmount-only.

No consumers wired in yet; that lands in follow-ups.
Introduces the Vault-side consumer of DustSplit and its invariant
adjustments, wired via a single eligibility gate.

Overlay (xrpl::vault_dust::):
- useVaultDust(view, vault): eligibility gate — featureLendingProtocolV1_1
  + VaultVersion::CashBasis + !asset.integral(). Also the dispatcher
  used by the base xrpl::addVaultAssets / clawbackVaultAssets /
  removeVaultAssets / moveVaultAssets to route eligible vaults into
  vault_dust:: implementations.
- addVaultAssets: receiver-leg Override at posteriorScale(vault, delta).
- clawbackVaultAssets / non-terminal removeVaultAssets /
  moveVaultAssets: sender-leg Override at scale(sfAssetsTotal_post_op).
- Terminal removeVaultAssets (FinalRemoval::Yes): sender-leg Drain,
  landing sfDust and sfBalance at zero on the vault's custody line.

No trust-line writes anywhere in vault_dust:: code. Renormalisation is
implicit: the credit path re-splits the extended balance at every
accountSend under Override mode.

Invariant relaxation:
- ValidVault::DeltaInfo gains a signed dustDelta alongside delta.
  ttVAULT_WITHDRAW now compares the extended pseudo-account delta
  (delta + dustDelta) against the destination's extended delta, so a
  scale-refinement dust promotion (an internal move on the
  pseudo-account's line) doesn't spuriously fail "vault and destination
  balance must change by equal amount".
- O2 "dust bounded by one quantum" relaxed to
  10 x quantum(scale(sfAssetsTotal)) to accept up-to-one-decade drift
  under Override mode when the ex-ante scale estimate lands on a
  decade boundary; drift is caught on the next accountSend.

Wiring:
- LoanPay routes through the vault_dust:: overlay when useVaultDust is
  true.
- VaultDeposit / VaultWithdraw pass the DustSplit through into the
  base helpers.

Docs:
- docs/dust-mechanism.md describes the model, DustSplit shape, Override
  vs Drain semantics, reporting sign convention, contract asserts,
  how to add a new consumer, amendment-gate policy, and the ValidVault
  sign-handling.
Adds the behavior test suites that exercise the sfDust field, DustSplit
credit path, and the xrpl::vault_dust:: overlay together.

New suites:
- VaultRoundingTrustlineDust_test: sub-quantum credit accounting on the
  trust-line layer, DustSplit contract asserts (Drain on receiver
  forbidden, issuer-side policy forbidden), accountHolds balance-only
  contract, ordinary payments never acquire sfDust, VaultDelete blocked
  when sfDust != 0.
- VaultRounding_test: Vault-facing rounding scenarios (deposits,
  withdrawals, terminal drain, non-terminal Override after a
  dust-producing repayment, sender-leg Override dust reporting on
  non-terminal removal, sender-leg Drain end-to-end via a
  defaulted-loan terminal withdrawal, ValidVault regression around
  extended pseudo-account deltas).
- VaultDustProbe: shared instrumentation used by both suites to inspect
  sfBalance / sfDust and the reported per-leg delta pair.

Additional coverage:
- VaultHelpers_test: exercises the vault_dust:: overlay dispatchers
  and their eligibility gate.
- LoanPay_test: dust-producing repayment paths.

Also adds 'parameterise*' to .cspell.config.yaml, used in the new
test suites.
@Tapanito
Tapanito force-pushed the tapanito/vault-dust-overlay branch from 1036e47 to c4e80e7 Compare August 13, 2026 08:31
@Tapanito

Copy link
Copy Markdown
Contributor Author

Closing this PR. Its tests have been redistributed into the appropriate slices of the stack: RippleStateSfDust tests moved to #8016, DustSplitCreditPath tests to #8017, and the vault_dust:: overlay / VaultRounding / VaultRoundingTrustlineDust suites to #8018. The tapanito/vault-dust-tests branch will be deleted.

@Tapanito Tapanito closed this Aug 13, 2026
@Tapanito
Tapanito deleted the tapanito/vault-dust-tests branch August 13, 2026 08:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant