mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Migrate thread safety to RCLConsensus (RIPD-1389):
Moves thread safety from generic Consensus to RCLConsensus and switch generic Consensus to adaptor design.
This commit is contained in:
@@ -21,7 +21,8 @@
|
||||
|
||||
#include <boost/container/flat_map.hpp>
|
||||
#include <boost/container/flat_set.hpp>
|
||||
|
||||
#include <ripple/consensus/Consensus.h>
|
||||
#include <ripple/consensus/ConsensusProposal.h>
|
||||
#include <test/csf/Ledger.h>
|
||||
#include <test/csf/Tx.h>
|
||||
#include <test/csf/UNL.h>
|
||||
@@ -115,20 +116,43 @@ public:
|
||||
directly from the generic types.
|
||||
*/
|
||||
using Proposal = ConsensusProposal<PeerID, Ledger::ID, TxSetType>;
|
||||
class PeerPosition
|
||||
{
|
||||
public:
|
||||
PeerPosition(Proposal const & p)
|
||||
: proposal_(p)
|
||||
{
|
||||
}
|
||||
|
||||
struct Traits
|
||||
Proposal const&
|
||||
proposal() const
|
||||
{
|
||||
return proposal_;
|
||||
}
|
||||
|
||||
Json::Value
|
||||
getJson() const
|
||||
{
|
||||
return proposal_.getJson();
|
||||
}
|
||||
|
||||
private:
|
||||
Proposal proposal_;
|
||||
};
|
||||
|
||||
|
||||
/** Represents a single node participating in the consensus process.
|
||||
It implements the Adaptor requirements of generic Consensus.
|
||||
*/
|
||||
struct Peer
|
||||
{
|
||||
using Ledger_t = Ledger;
|
||||
using NodeID_t = PeerID;
|
||||
using TxSet_t = TxSet;
|
||||
};
|
||||
using PeerPosition_t = PeerPosition;
|
||||
using Result = ConsensusResult<Peer>;
|
||||
|
||||
/** Represents a single node participating in the consensus process.
|
||||
It implements the Callbacks required by Consensus.
|
||||
*/
|
||||
struct Peer : public Consensus<Peer, Traits>
|
||||
{
|
||||
using Base = Consensus<Peer, Traits>;
|
||||
Consensus<Peer> consensus;
|
||||
|
||||
//! Our unique ID
|
||||
PeerID id;
|
||||
@@ -172,12 +196,17 @@ struct Peer : public Consensus<Peer, Traits>
|
||||
bool validating_ = true;
|
||||
bool proposing_ = true;
|
||||
|
||||
ConsensusParms parms_;
|
||||
std::size_t prevProposers_ = 0;
|
||||
std::chrono::milliseconds prevRoundTime_;
|
||||
|
||||
//! All peers start from the default constructed ledger
|
||||
Peer(PeerID i, BasicNetwork<Peer*>& n, UNL const& u, ConsensusParms p)
|
||||
: Consensus<Peer, Traits>(n.clock(), p, beast::Journal{})
|
||||
: consensus(n.clock(), *this, beast::Journal{})
|
||||
, id{i}
|
||||
, net{n}
|
||||
, unl(u)
|
||||
, parms_(p)
|
||||
{
|
||||
ledgers[lastClosedLedger.id()] = lastClosedLedger;
|
||||
}
|
||||
@@ -210,12 +239,6 @@ struct Peer : public Consensus<Peer, Traits>
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto const&
|
||||
proposals(Ledger::ID const& ledgerHash)
|
||||
{
|
||||
return peerPositions_[ledgerHash];
|
||||
}
|
||||
|
||||
TxSet const*
|
||||
acquireTxSet(TxSet::ID const& setId)
|
||||
{
|
||||
@@ -245,17 +268,17 @@ struct Peer : public Consensus<Peer, Traits>
|
||||
}
|
||||
|
||||
Result
|
||||
onClose(Ledger const& prevLedger, NetClock::time_point closeTime, Mode mode)
|
||||
onClose(Ledger const& prevLedger, NetClock::time_point closeTime, ConsensusMode mode)
|
||||
{
|
||||
TxSet res{openTxs};
|
||||
|
||||
return Result{TxSet{openTxs},
|
||||
Proposal{prevLedger.id(),
|
||||
return Result(TxSet{openTxs},
|
||||
Proposal(prevLedger.id(),
|
||||
Proposal::seqJoin,
|
||||
res.id(),
|
||||
closeTime,
|
||||
now(),
|
||||
id}};
|
||||
id));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -263,10 +286,17 @@ struct Peer : public Consensus<Peer, Traits>
|
||||
Result const& result,
|
||||
Ledger const& prevLedger,
|
||||
NetClock::duration const& closeResolution,
|
||||
CloseTimes const& rawCloseTimes,
|
||||
Mode const& mode)
|
||||
ConsensusCloseTimes const& rawCloseTimes,
|
||||
ConsensusMode const& mode,
|
||||
Json::Value && consensusJson)
|
||||
{
|
||||
onAccept(result, prevLedger, closeResolution, rawCloseTimes, mode);
|
||||
onAccept(
|
||||
result,
|
||||
prevLedger,
|
||||
closeResolution,
|
||||
rawCloseTimes,
|
||||
mode,
|
||||
std::move(consensusJson));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -274,8 +304,9 @@ struct Peer : public Consensus<Peer, Traits>
|
||||
Result const& result,
|
||||
Ledger const& prevLedger,
|
||||
NetClock::duration const& closeResolution,
|
||||
CloseTimes const& rawCloseTimes,
|
||||
Mode const& mode)
|
||||
ConsensusCloseTimes const& rawCloseTimes,
|
||||
ConsensusMode const& mode,
|
||||
Json::Value && consensusJson)
|
||||
{
|
||||
auto newLedger = prevLedger.close(
|
||||
result.set.txs_,
|
||||
@@ -283,7 +314,8 @@ struct Peer : public Consensus<Peer, Traits>
|
||||
rawCloseTimes.self,
|
||||
result.position.closeTime() != NetClock::time_point{});
|
||||
ledgers[newLedger.id()] = newLedger;
|
||||
|
||||
prevProposers_ = result.proposers;
|
||||
prevRoundTime_ = result.roundTime.read();
|
||||
lastClosedLedger = newLedger;
|
||||
|
||||
auto it =
|
||||
@@ -304,16 +336,16 @@ struct Peer : public Consensus<Peer, Traits>
|
||||
// TODO: reconsider this and instead just save LCL generated here?
|
||||
if (completedLedgers <= targetLedgers)
|
||||
{
|
||||
startRound(
|
||||
consensus.startRound(
|
||||
now(), lastClosedLedger.id(), lastClosedLedger, proposing_);
|
||||
}
|
||||
}
|
||||
|
||||
Ledger::ID
|
||||
getPrevLedger(Ledger::ID const& ledgerID, Ledger const& ledger, Mode mode)
|
||||
getPrevLedger(Ledger::ID const& ledgerID, Ledger const& ledger, ConsensusMode mode)
|
||||
{
|
||||
// TODO: Use generic validation code
|
||||
if (mode != Mode::wrongLedger && ledgerID.seq > 0 &&
|
||||
if (mode != ConsensusMode::wrongLedger && ledgerID.seq > 0 &&
|
||||
ledger.id().seq > 0)
|
||||
return peerValidations.getBestLCL(ledgerID, ledger.parentID());
|
||||
return ledgerID;
|
||||
@@ -323,24 +355,31 @@ struct Peer : public Consensus<Peer, Traits>
|
||||
propose(Proposal const& pos)
|
||||
{
|
||||
if (proposing_)
|
||||
relay(pos);
|
||||
relay(PeerPosition(pos));
|
||||
}
|
||||
|
||||
ConsensusParms const &
|
||||
parms() const
|
||||
{
|
||||
return parms_;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// non-callback helpers
|
||||
void
|
||||
receive(Proposal const& p)
|
||||
receive(PeerPosition const& peerPos)
|
||||
{
|
||||
Proposal const & p = peerPos.proposal();
|
||||
if (unl.find(p.nodeID()) == unl.end())
|
||||
return;
|
||||
|
||||
// TODO: Be sure this is a new proposal!!!!!
|
||||
// TODO: Supress repeats more efficiently
|
||||
auto& dest = peerPositions_[p.prevLedger()];
|
||||
if (std::find(dest.begin(), dest.end(), p) != dest.end())
|
||||
return;
|
||||
|
||||
dest.push_back(p);
|
||||
peerProposal(now(), p);
|
||||
consensus.peerProposal(now(), peerPos);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -349,7 +388,7 @@ struct Peer : public Consensus<Peer, Traits>
|
||||
// save and map complete?
|
||||
auto it = txSets.insert(std::make_pair(txs.id(), txs));
|
||||
if (it.second)
|
||||
gotTxSet(now(), txs);
|
||||
consensus.gotTxSet(now(), txs);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -392,7 +431,7 @@ struct Peer : public Consensus<Peer, Traits>
|
||||
void
|
||||
timerEntry()
|
||||
{
|
||||
Base::timerEntry(now());
|
||||
consensus.timerEntry(now());
|
||||
// only reschedule if not completed
|
||||
if (completedLedgers < targetLedgers)
|
||||
net.timer(parms().ledgerGRANULARITY, [&]() { timerEntry(); });
|
||||
@@ -406,7 +445,7 @@ struct Peer : public Consensus<Peer, Traits>
|
||||
// so there is no gaurantee that bestLCL == lastClosedLedger.id()
|
||||
auto bestLCL = peerValidations.getBestLCL(
|
||||
lastClosedLedger.id(), lastClosedLedger.parentID());
|
||||
startRound(now(), bestLCL, lastClosedLedger, proposing_);
|
||||
consensus.startRound(now(), bestLCL, lastClosedLedger, proposing_);
|
||||
}
|
||||
|
||||
NetClock::time_point
|
||||
@@ -435,6 +474,28 @@ struct Peer : public Consensus<Peer, Traits>
|
||||
else
|
||||
net.timer(when, std::forward<T>(what));
|
||||
}
|
||||
|
||||
Ledger::ID
|
||||
prevLedgerID()
|
||||
{
|
||||
return consensus.prevLedgerID();
|
||||
}
|
||||
|
||||
std::size_t
|
||||
prevProposers()
|
||||
{
|
||||
return prevProposers_;
|
||||
}
|
||||
|
||||
std::chrono::milliseconds
|
||||
prevRoundTime()
|
||||
{
|
||||
return prevRoundTime_;
|
||||
}
|
||||
|
||||
// Not interested in tracking consensus mode
|
||||
void
|
||||
onModeChange(ConsensusMode, ConsensusMode) {}
|
||||
};
|
||||
|
||||
} // csf
|
||||
|
||||
Reference in New Issue
Block a user