From 91847f6bb0466496a0cc781fa9765d29c5d0465a Mon Sep 17 00:00:00 2001 From: Nicholas Dudfield Date: Fri, 18 Sep 2026 10:19:25 +0700 Subject: [PATCH] fix(consensus): serialize consensus phase publication --- src/xrpld/app/misc/NetworkOPs.cpp | 40 +++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/xrpld/app/misc/NetworkOPs.cpp b/src/xrpld/app/misc/NetworkOPs.cpp index 75525d276d..1e35494c01 100644 --- a/src/xrpld/app/misc/NetworkOPs.cpp +++ b/src/xrpld/app/misc/NetworkOPs.cpp @@ -383,6 +383,11 @@ public: reportFeeChange() override; void reportConsensusStateChange(ConsensusPhase phase); + void + reportConsensusStateChangeIfNeeded( + ConsensusPhase phase, + std::unique_ptr const& clog, + bool logPhase); void updateLocalTx(ReadView const& view) override; @@ -674,7 +679,8 @@ private: RCLConsensus mConsensus; - ConsensusPhase mLastConsensusPhase; + std::mutex lastConsensusPhaseMutex_; + ConsensusPhase mLastConsensusPhase{ConsensusPhase::open}; LedgerMaster& m_ledgerMaster; @@ -1010,14 +1016,8 @@ NetworkOPsImp::processHeartbeatTimer() mConsensus.timerEntry(app_.timeKeeper().closeTime(), clog.ss()); - CLOG(clog.ss()) << "consensus phase " << to_string(mLastConsensusPhase); const ConsensusPhase currPhase = mConsensus.phase(); - if (mLastConsensusPhase != currPhase) - { - reportConsensusStateChange(currPhase); - mLastConsensusPhase = currPhase; - CLOG(clog.ss()) << " changed to " << to_string(mLastConsensusPhase); - } + reportConsensusStateChangeIfNeeded(currPhase, clog.ss(), true); CLOG(clog.ss()) << ". "; setHeartbeatTimer(); @@ -2094,11 +2094,7 @@ NetworkOPsImp::beginConsensus( clog); const ConsensusPhase currPhase = mConsensus.phase(); - if (mLastConsensusPhase != currPhase) - { - reportConsensusStateChange(currPhase); - mLastConsensusPhase = currPhase; - } + reportConsensusStateChangeIfNeeded(currPhase, clog, false); JLOG(m_journal.debug()) << "Initiating consensus engine"; return true; @@ -3225,6 +3221,24 @@ NetworkOPsImp::reportConsensusStateChange(ConsensusPhase phase) [this, phase]() { pubConsensus(phase); }); } +void +NetworkOPsImp::reportConsensusStateChangeIfNeeded( + ConsensusPhase phase, + std::unique_ptr const& clog, + bool logPhase) +{ + std::scoped_lock const lock(lastConsensusPhaseMutex_); + if (logPhase) + CLOG(clog) << "consensus phase " << to_string(mLastConsensusPhase); + if (mLastConsensusPhase != phase) + { + reportConsensusStateChange(phase); + mLastConsensusPhase = phase; + if (logPhase) + CLOG(clog) << " changed to " << to_string(mLastConsensusPhase); + } +} + inline void NetworkOPsImp::updateLocalTx(ReadView const& view) {