From 954990101488fb85628ea456512a5365db4487f5 Mon Sep 17 00:00:00 2001 From: Nicholas Dudfield Date: Wed, 24 Jun 2026 13:35:25 +0700 Subject: [PATCH] docs(consensus): clarify extended position identity --- .../app/consensus/ConsensusExtensionsDesign.md | 14 ++++++++------ src/xrpld/app/consensus/RCLCxPeerPos.h | 11 ++++++----- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/xrpld/app/consensus/ConsensusExtensionsDesign.md b/src/xrpld/app/consensus/ConsensusExtensionsDesign.md index e1ff1c798..676baf77c 100644 --- a/src/xrpld/app/consensus/ConsensusExtensionsDesign.md +++ b/src/xrpld/app/consensus/ConsensusExtensionsDesign.md @@ -42,10 +42,12 @@ treated as complete and must retry or expire under transaction rules. 1. Core consensus remains keyed by the transaction set. - `ExtendedPosition::operator==` intentionally compares only `txSetHash`. - RNG, export sig, commit-set, and entropy-set hashes are proposal sidecars. - They are coordinated during establish, but they do not define whether peers - agree on the ordinary transaction set. + `ExtendedPosition` has no whole-position equality or implicit `uint256` + conversion. Callers that need the ordinary consensus identity compare + `txSetHash` explicitly, or use the generic `positionTxSetID(position)` helper + in templated consensus code. RNG, export sig, commit-set, and entropy-set + hashes are proposal sidecars. They are coordinated during establish, but they + do not define whether peers agree on the ordinary transaction set. 2. Extension waits are bounded. @@ -129,7 +131,7 @@ signed proposal field remains the hash. This field is diagnostic only: - It is covered by the proposal signature and duplicate-suppression identity. -- It does not participate in `ExtendedPosition::operator==`. +- It does not participate in core tx-set identity. - It does not lower the active validator quorum denominator. - It is intended to explain timing/degraded-network cases where commits, reveals, or sidecar hashes arrive late or asymmetrically. @@ -357,7 +359,7 @@ Export-only quorum behavior. When changing consensus extension code, check these questions: -- Does this preserve transaction-set equality as the core consensus identity? +- Does this preserve transaction-set identity as the core consensus identity? - Does every extension wait have a bounded fallback? - Does validator_quorum entropy require active-validator quorum alignment? - Can one bad validator deny entropy to an honest quorum? It must not. diff --git a/src/xrpld/app/consensus/RCLCxPeerPos.h b/src/xrpld/app/consensus/RCLCxPeerPos.h index 185033814..21d7fab99 100644 --- a/src/xrpld/app/consensus/RCLCxPeerPos.h +++ b/src/xrpld/app/consensus/RCLCxPeerPos.h @@ -54,12 +54,13 @@ struct ExtendedPosition // === Core Convergence Target === uint256 txSetHash; - // === Set Hashes (sub-state quorum, not in operator==) === + // === Set Hashes (sub-state quorum, not core tx-set identity) === std::optional commitSetHash; std::optional entropySetHash; std::optional exportSigSetHash; std::optional exportSignaturesHash; - // Signed diagnostic only: not a quorum input and not part of operator==. + // Signed diagnostic only: not a quorum input and not part of tx-set + // identity. std::optional observedParticipantsHash; // === Per-Validator Leaves (unique per proposer) === @@ -100,13 +101,13 @@ struct ExtendedPosition // entropy result is verified deterministically from collected reveals. // - Leaves (myCommitment, myReveal) are also excluded — they are // per-validator data unique to each proposer. - //@@start rng-extended-position-equality + //@@start rng-extended-position-identity // No operator== and no implicit uint256 conversion on purpose: comparing // an ExtendedPosition as if it were a whole value is misleading because // consensus convergence intentionally ignores sidecar hashes and leaves. // Callers that need tx-set identity compare txSetHash explicitly, or use // the generic positionTxSetID(position) helper. - //@@end rng-extended-position-equality + //@@end rng-extended-position-identity // CRITICAL: Include ALL fields for signing (prevents stripping attacks) // @@ -260,7 +261,7 @@ operator<<(std::ostream& os, ExtendedPosition const& pos) The resulting digest is embedded in ExtendedPosition and therefore covered by the normal proposal signature. The raw protobuf field remains outside - consensus equality, but stripping or mutating it invalidates the signed + core tx-set identity, but stripping or mutating it invalidates the signed digest before duplicate suppression. */ template