Commit Graph

14563 Commits

Author SHA1 Message Date
Nicholas Dudfield
ddfb1dbeb6 docs: clarify entropy and runtime test APIs 2026-06-23 16:42:05 +07:00
Nicholas Dudfield
8bf1ece0a0 test(export): pin expiry and no-veto boundaries 2026-06-23 16:42:02 +07:00
Nicholas Dudfield
639e153f3b fix(consensus): gate proposal extensions by parent ledger 2026-06-23 16:41:58 +07:00
Nicholas Dudfield
8e542c32e0 test(testnet): clarify directed runtime latency syntax 2026-06-23 16:19:10 +07:00
Nicholas Dudfield
38f4d53ebf test(testnet): add runtime latency probe suite 2026-06-23 16:04:58 +07:00
Nicholas Dudfield
fe66a11c69 build(test): allow external hook Env tests 2026-06-23 13:38:43 +07:00
Nicholas Dudfield
77e48d553c test(export): cover sidecar rejection preflights 2026-06-23 11:53:51 +07:00
Nicholas Dudfield
439031dc92 Merge remote-tracking branch 'origin/dev' into feature-export-rng 2026-06-23 10:55:43 +07:00
Nicholas Dudfield
1a5b934881 test(csf): model sidecar split-brain equivocation 2026-06-23 10:52:38 +07:00
Nicholas Dudfield
7f0d2959e8 test(export): cover no-veto sidecar withholding 2026-06-23 10:34:01 +07:00
Nicholas Dudfield
1440d1495f test(consensus): cover split-brain sidecar threshold 2026-06-23 10:20:34 +07:00
Nicholas Dudfield
57f5a9d6cc test(testnet): cover export without UNLReport 2026-06-23 10:14:09 +07:00
Nicholas Dudfield
cacd1f71fe test(consensus): mint tier 2 with active nUNL 2026-06-23 10:11:40 +07:00
Nicholas Dudfield
93a6f0fbec docs(testnet): add export degradation projection marker 2026-06-23 10:07:02 +07:00
Nicholas Dudfield
c5b1cb222d docs(consensus): add test projection markers 2026-06-23 10:03:04 +07:00
Nicholas Dudfield
e447f9f021 docs(consensus): add export apply projection markers 2026-06-23 09:55:01 +07:00
Nicholas Dudfield
0757094ed2 docs(consensus): add formal proof projection markers 2026-06-23 09:41:55 +07:00
Nicholas Dudfield
4b8107d57c docs(consensus): clarify nUNL entropy gate thresholds 2026-06-23 08:42:22 +07:00
Nicholas Dudfield
d4b9e2f22c chore(formal): ignore local Lean proof workspace 2026-06-23 08:14:03 +07:00
Nicholas Dudfield
3fc199017e docs(cmake): note runtime config conan opt-in 2026-06-22 16:57:30 +07:00
Nicholas Dudfield
4d55443976 refactor(runtime-config): scope fault injection controls 2026-06-22 16:51:23 +07:00
Nicholas Dudfield
0d1d649867 refactor(consensus): remove orphaned txset cache callback 2026-06-22 15:33:29 +07:00
Nicholas Dudfield
60469dbd86 refactor(rng): remove explicit-final proposal path 2026-06-22 15:07:18 +07:00
Nicholas Dudfield
3970912735 chore: update levelization results 2026-06-22 13:31:56 +07:00
Nicholas Dudfield
456f4144ba docs(rng): mark explicit-final for removal 2026-06-22 12:50:19 +07:00
Nicholas Dudfield
570cad4c44 test(export): pin network apply regressions 2026-06-22 12:14:42 +07:00
Nicholas Dudfield
b13868b71e fix(export): apply agreed sidecar signatures
Use the agreed exportSigSetHash sidecar map, not the live ExportSigCollector, as the network-mode ttEXPORT signer snapshot. Preserve export convergence state through RNG onPreBuild cleanup so buildLCL apply can see the gate result, and require a UNLReport-backed validator view before non-standalone Export finalization. Add regression coverage for agreed-vs-live collector mutation and onPreBuild export-state preservation.
2026-06-22 09:43:03 +07:00
Nicholas Dudfield
288b9e6d25 docs(rng): clarify commit substate pipelining 2026-06-22 09:06:12 +07:00
Nicholas Dudfield
e55c2c6dc8 fix(export): allow quorum-aligned sidecar despite missing observation 2026-06-22 09:00:46 +07:00
Nicholas Dudfield
35e981e509 docs(rng): align ConsensusExtensionsDesign with the UNLReport-only + F1 changes
A drift review (10-section adversarial pass + skeptical verification) found the design doc had fallen behind two recent code changes: the UNLReport-only gate (8368e12ab) and the F1 active-view alignment filter (fb9e2710c).

- Fallback Semantics: add the second fallback trigger -- a non-UNLReport-backed view mints consensus_fallback regardless of alignment.
- Validator Set And Quorum: note the config-fallback view is !fromUNLReport and forces consensus_fallback entropy.
- Entropy Alignment Rules: state the UNLReport precondition for non-fallback tiers; correct the alignment-count formula to the active-view-filtered count (non-active proposers and a non-active local +1 excluded -- the F1 fix); separate the two distinct counts (the peer-alignment GATE count vs the agreed entropySetMap_ leaf count that drives the tier LABEL); flag the explicit-final unfiltered exception.
- Worked examples: note they assume a UNLReport-anchored view (else all fall back).
- Export Principles: document that export success also requires full observation (peersSeen == txConverged), not just quorum alignment.
- Review Checklist: add items for the UNLReport-anchored-tier and alignment-count-universe (F1) invariants.

Doc-only. Raw drift findings kept in .ai-docs (gitignored).
2026-06-22 08:41:11 +07:00
Richard Holland
bb244ef772 put release builds into a candidate folder to prevent auto-update scripts running before smoke tests (#761) 2026.6.21-release+3350 2026-06-21 12:12:43 +10:00
Nicholas Dudfield
b9a733c831 docs(rng): flag the F1 gap on the explicit-final alignment path
The explicit-final proposal path counts participants/alignment over the unfiltered trusted-proposer set (ctx.peerPositions) plus an unconditional local +1, not the active validator view -- the same gap the F1 fix closed for the main entropy gate (inspectTxConvergedSidecarPeers). It is default-off/experimental with no robust timing model found (per the existing TBD, may never ship); if it is ever enabled it must apply the same active-view membership filter. Comment-only.

Follow-up to F1 (fb9e2710c).
2026-06-18 13:32:38 +07:00
Nicholas Dudfield
301e546aa9 chore(rng): assert active view source at round start 2026-06-18 10:42:28 +07:00
Nicholas Dudfield
e2da1db6d2 chore(rng): harden entropy fallback diagnostics 2026-06-18 10:32:07 +07:00
Nicholas Dudfield
16cd02156e test(rng): use a nonzero sentinel in the hook entropy-requirement test
testInvalidEntropyRequirements rejects four invalid dice/random requirements then returned accept(0,0,0) on success. But a valid dice(6,..) returns 0..5, so a regression that let the min_tier=0 requirement through (returning a value that happened to be 0) would still pass ~1/6 of the time -- the weakest spot is exactly the min_tier lower bound it most needs to prove (review finding). Return sentinel 42 (distinct from any dice/random result and from INVALID_ARGUMENT) and assert ==42, so any leaked requirement returns its own non-42 code and fails. WASM block recompiled; ConsensusEntropy 138 tests, 0 failures.

Follow-up to F1 (fb9e2710c).
2026-06-18 09:54:30 +07:00
Nicholas Dudfield
fb9e2710cc fix(rng): scope sidecar alignment count to the active validator view (F1)
The entropy/export bless-vs-fallback gate counted alignment over ALL tx-converged trusted proposers (currPeerPositions_), while the thresholds and the entropy leaf set are computed over the active validator view. A node that locally trusts proposers outside the on-ledger UNLReport active set could pad alignedParticipants(), inflating the counting universe N above originalViewSize and eroding the Tier-2 intersection margin (2t - N) below the Byzantine floor f -- so two equivocation cohorts padded by non-active aligners could each clear the gate (review finding F1). Backstopped by the 80% validation quorum, but the proof's universe and the code's universe must match.

inspectTxConvergedSidecarPeers now takes an active-view membership predicate and counts only member peers toward alignment; the local +1 is gated on localIsActiveValidator(). Both the RNG entropy gate and the export-sig gate pass ext.isUNLReportMember / ext.localIsActiveValidator, mirroring buildEntropySet / hasQuorumOfCommits' containsNode filter. New method on ConsensusExtensions + CSF Peer + the FakeExtensions stub.

Regression test (Sidecar peer alignment helper): a trusted-but-non-active aligned proposer pushes unfiltered aligned to 2 but filtered aligned stays 1, and a non-active local node's +1 is suppressed -- padding cannot satisfy the gate. ConsensusExtensions 900, ConsensusRng 386, Consensus 1399, all green.

Note: the explicit-final proposal path (ConsensusExtensionsTick.h ~:934) counts over prevProposers and is NOT yet filtered (separate, experimental path).
2026-06-18 09:44:56 +07:00
Nicholas Dudfield
c8fad50d66 Merge origin/dev into feature-export-rng
# Conflicts:
#	src/xrpld/app/hook/applyHook.h
2026-06-17 11:45:42 +07:00
Nicholas Dudfield
d9b5fc26fc style(rng): apply clang-format 2026-06-17 11:35:05 +07:00
Nicholas Dudfield
72d03620f9 test(rng): require UNLReport in testnet entropy suites 2026-06-17 11:33:04 +07:00
Nicholas Dudfield
8368e12ab3 fix(rng): require UNLReport view for non-fallback entropy 2026-06-17 11:32:51 +07:00
Nicholas Dudfield
23f745bd01 fix(hook): validate entropy requirements 2026-06-17 11:32:38 +07:00
Nicholas Dudfield
27ae39b91a fix(rng): use a genuinely forkable nUNL config in the anchor test
The tier-2 anchor pin (20d52d8b6) used an 8/6 (original/effective) nUNL config whose rationale was wrong: it computed cohort overlap against the original view (2*4-8=0), but aligned cohorts form in the EFFECTIVE view, so two 4-of-6 cohorts overlap by 2*4-6=2 > floor(8/5)=1 -- 8/6 is NOT actually forkable, the original-view anchor is merely conservative there. The test still caught the originalViewSize->size() regression, but the stated reason was misleading (review catch).

Switch to 10 active / 2 disabled (original 10, effective 8), a genuinely forkable case: a 5-of-8 cohort (what the effective-size threshold would admit) overlaps only 2*5-8=2, which does NOT exceed the f=floor(10/5)=2 faulty the original UNL still tolerates -> an equivocator could mint two distinct tier-2 digests. The correct original anchor requires 7 (overlap 6 > 2) and keeps the band closed (tier2==quorum==7); a regression to size() drops the floor to 5 and re-opens the forkable [5,7) band. Assertions and rationale updated to match; suite green (897, 0 failures).
2026-06-16 17:33:57 +07:00
Nicholas Dudfield
20d52d8b66 test(rng): pin tier-2 threshold to pre-nUNL original view
tier2Threshold() anchors to originalViewSize (pre-nUNL), not the effective post-nUNL size(): nUNL shrinks the effective view while leaving faulty nodes in it, so a sub-quorum fraction of the effective view can exceed the Byzantine bound. A one-line regression to size() would relabel a forkable cohort as participant_aligned -- and no existing test caught it (the only nUNL test never calls tier2Threshold()/selectEntropy, and the only tier-2 selection test has no nUNL, so original == effective there).

Add testTier2ThresholdAnchorsToOriginalView: 8 active validators, 2 disabled via NegativeUNL (original 8, effective 6), asserting tier2Threshold()==5 (from the original 8) not 4 (from the effective 6), with quorum/gate cross-checks. Mutation-verified: flipping the production read to size() turns exactly this test red (tier2Threshold + entropyGateThreshold) while the existing tier-2 selection test stays green.

Also: pointer comment at tier2Threshold() linking the invariant to its guard test, and a design-doc fix -- the worked example used n=5, where the band is empty (quorum == participant_aligned == 4) so it illustrated an unreachable tier; now n=6.
2026-06-16 17:02:00 +07:00
Richard Holland
639ea34377 Fixhookmap (#756) 2026-06-16 17:06:25 +10:00
tequ
089c0dc3fe Fix ammLPHolds logic to include escrowed cases (#757) 2026-06-16 15:26:29 +10:00
Nicholas Dudfield
b070785dee fix(rng): make tier-2 scenario's 5/6 check fallback-tolerant
The 5/6 phase asserted validator_quorum on whichever single ledger the validated tip happened to sit on. But the ledger right at the node-5 drop can be a transient consensus_fallback (EntropyTier=1, count=0) — deterministic and by design, while the commit/reveal pipeline re-primes — so when the tip landed there the assert failed (tier=1, observed ~1 run in 4). Same class of bug as the old post-recovery flake: depending on exactly where the tip lands.

Now settle 4 ledgers past the drop, then scan the post-drop validated ledgers for a clean validator_quorum (tier 3, count >= quorum). The window is entirely 5-node cohorts, so a tier-3 there has count == 5 (faithful to '5/6 still tier 3'); the transition fallback is tolerated, not asserted on. Verified 3/3: each run found tier=3 count=5.

Also harden _closed_entropy() to raise on != 1 ConsensusEntropy pseudo-tx (mirroring get_entropy_tx) instead of silently skipping — a duplicate/missing injection now fails with a clear error rather than resurfacing as a generic 'no tier-2 ledger'.
2026-06-16 11:15:55 +07:00
tequ
78167e09c0 change sfHookOn of ltHookDefinition to soeOptional for HookOnV2 (#755) 2026-06-16 13:58:53 +10:00
tequ
607a7fdf98 Change AMM to Supported::no (#758) 2026-06-16 13:56:58 +10:00
Nicholas Dudfield
def617e3f9 test(rng): harden tier-2 testnet scenario per review + robust on-ledger check
Codex review minors: assert_validator_quorum at the 5/6 boundary (EntropyTier=3 AND count >= quorum AND non-zero digest, not just tier==3 — catches a bad tier/count pairing); added explicit assert_validator_quorum / assert_consensus_fallback helpers and an entropy_fields() warning that its is_fallback (tier != 3) lumps participant_aligned in with fallback (safe only where no tier-2 band exists).

Robustness: tier 2 is below the validation quorum, so the validated tip stalls and which provisional ledgers it later reaches is timing-dependent (the post-recovery inspection was fragile). Replaced it with direct inspection of the surviving cohort's CLOSED ledger via ledger('closed') DURING the window; recovery is now a pure liveness check.

Verified on a live testnet: PASS — EntropyTier=2 count=4 confirmed on 4 distinct provisional ledgers (seq 7-10).
2026-06-16 10:51:33 +07:00
Nicholas Dudfield
c322b59961 test(rng): tier-2 (participant_aligned) testnet scenario at n=6
A 6-node smoke (the smallest NON-degenerate tier-2 size: tier2 floor 4, quorum 5) driving the 4/6 band. n=5 has no band (tier2 == quorum), which is why the existing degradation smoke only ever sees tier 3 / fallback.

Tier 2 is below the 80% validation quorum, so the 4/6 cohort's ledgers are provisional: the scenario confirms tier-2 injection from the cohort's logs during the window, then verifies the on-ledger EntropyTier=2 count=4 POST-RECOVERY once those ledgers become canonical and validate (the mechanism the degradation smoke also relies on). Adds the assert_participant_aligned helper and the node_count:6 suite entry.

Verified on a live testnet: PASS — 12 tier-2 injections in the 4/6 window, seq 7 & 8 validated as participant_aligned (count 4).
2026-06-16 10:28:57 +07:00