Reuse SidecarPeerAlignment::quorumAligned for export sidecar gates, name the shared sidecar convergence timeout, and centralize the RNG commitment tuple.
Also make ExportLimits::maxExportsPerHook the value enforced by xport_reserve, with a static assertion against the hook ABI constant.
Bound proposal-carried export signature blobs before hashing them during proposal precheck, and apply the same size cap at export signature harvest as defense in depth.
Cap the unverified export-signature cache by distinct tx hash while leaving verified signatures and existing entries ungated, so real exports can still reach quorum.
Domain-separate Hook RNG using the actual strong/weak execution role at draw time, and document the residual commit/reveal withholding bias across all entropy tiers.
Codex final-review minors, both comment-only (no behavior change): EntropyTier participant_aligned no longer says "reserved for a future" tier (it is implemented in this stack); and the commit-timeout path comment said "fixed UNL quorum" but the code now uses entropyGateThreshold() (min(quorum, tier2)).
The entropy-quality requirement becomes an explicit, required argument
at every call site — there is deliberately no default and no network
constant:
- dice(sides) -> dice(sides, min_tier, min_count)
- random(ptr, len) -> random(ptr, len, min_tier, min_count)
- fairRng gates on freshness && tier >= min_tier && count >= min_count;
the hard-coded 'EntropyCount >= 5' network constant is deleted —
the hook author states what their application needs and gets
TOO_LITTLE_ENTROPY when this ledger cannot meet it
- WASM imports have no default parameters, so the old no-argument shape
was really a hidden constant invisible at the call site; requiring the
arguments makes weak-entropy acceptance (min_tier=1) a deliberate,
reviewable opt-in rather than an accident
- hook/extern.h and hook/sfcodes.h regenerated (CI-verified)
- test hooks updated and recompiled; new test pins the requirement
gate: dice(6, 3, 21) against count=20 returns TOO_LITTLE_ENTROPY
Replace the zero-entropy fallback with a deterministic consensus-bound
digest so every RNG-enabled ledger carries usable entropy:
- sha512Half(HashPrefix::entropyFallback, prevLedgerHash, baseTxSetHash,
seq) — all inputs are already consensus-agreed at injection time, so
no new agreement machinery is needed and the digest is identical on
every node building the same ledger
- new sfEntropyTier (UINT8) on the ttCONSENSUS_ENTROPY pseudo-tx and
ConsensusEntropy ledger entry: EntropyCount says how many validators
contributed, EntropyTier says which gate the result passed
(validator_quorum vs consensus_fallback; participant_aligned reserved)
- the fallback digest derives from the BASE (pre-injection) tx set hash
to avoid circularity; entropy pseudo-tx dedup is now type-based since
an explicit-final synthetic set can carry a pseudo-tx whose txID
implicit nodes cannot re-derive
- unparseable-entropy-set residual now falls back instead of skipping
injection, so a fresh ConsensusEntropy entry exists every ledger
- CSF Peer mirrors the fallback analog; sims assert deterministic
non-zero fallback digests across same-LCL peers
- testnet scenarios updated: degraded windows expect labeled fallback
entropy, never validator-tier
The fallback tier is user-influenceable via tx submission (quiet-ledger
grinding) and is labeled accordingly — hook-facing gating lands with the
min_tier/min_count API change.