diff --git a/src/test/csf/Peer.h b/src/test/csf/Peer.h index d62cf29da..f6b25be85 100644 --- a/src/test/csf/Peer.h +++ b/src/test/csf/Peer.h @@ -462,6 +462,19 @@ struct Peer return myEntropySecret_; } + void + selfSeedReveal() + { + if (!enableRngConsensus_) + return; + // Self-seed our own reveal into pendingReveals_ so it + // counts toward reveal quorum. The real code does this + // in decorateMessage; the CSF does it here since it has + // no equivalent serialization hook. + if (myEntropySecret_ != uint256{}) + pendingReveals_[peer.id] = myEntropySecret_; + } + void setEntropyFailed() { diff --git a/src/xrpld/app/consensus/ConsensusExtensions.cpp b/src/xrpld/app/consensus/ConsensusExtensions.cpp index c99ba7eec..431f14c44 100644 --- a/src/xrpld/app/consensus/ConsensusExtensions.cpp +++ b/src/xrpld/app/consensus/ConsensusExtensions.cpp @@ -508,6 +508,17 @@ ConsensusExtensions::setEntropyFailed() entropyFailed_ = true; } +void +ConsensusExtensions::selfSeedReveal() +{ + auto const& valKeys = app_.getValidatorKeys(); + if (myEntropySecret_ != uint256{}) + { + pendingReveals_[valKeys.nodeID] = myEntropySecret_; + nodeIdToKey_.insert_or_assign(valKeys.nodeID, valKeys.keys->publicKey); + } +} + //@@start clear-rng-state void ConsensusExtensions::clearRngState() diff --git a/src/xrpld/app/consensus/ConsensusExtensions.h b/src/xrpld/app/consensus/ConsensusExtensions.h index 97c1e98bc..88890ec2b 100644 --- a/src/xrpld/app/consensus/ConsensusExtensions.h +++ b/src/xrpld/app/consensus/ConsensusExtensions.h @@ -195,6 +195,12 @@ public: void setEntropyFailed(); + /// Self-seed our own reveal into pendingReveals_. + /// Called from extensionsTick at reveal transition. + /// In production, decorateMessage also self-seeds (belt + suspenders). + void + selfSeedReveal(); + void clearRngState(); diff --git a/src/xrpld/consensus/ConsensusExtensionsTick.h b/src/xrpld/consensus/ConsensusExtensionsTick.h index c63f4c3eb..7876640ff 100644 --- a/src/xrpld/consensus/ConsensusExtensionsTick.h +++ b/src/xrpld/consensus/ConsensusExtensionsTick.h @@ -415,6 +415,12 @@ extensionsTick(Ext& ext, Ctx const& ctx) auto newPos = ctx.getPosition(); newPos.myReveal = ext.getEntropySecret(); + // Self-seed our own reveal into pendingReveals so it + // counts toward reveal quorum and appears in the + // entropy set. harvestRngData only sees peer proposals, + // not our own. + ext.selfSeedReveal(); + ctx.updatePosition(newPos); if (ctx.mode == ConsensusMode::proposing)