rippled
Loading...
Searching...
No Matches
RCLConsensus.h
1#pragma once
2
3#include <xrpld/app/consensus/RCLCensorshipDetector.h>
4#include <xrpld/app/consensus/RCLCxLedger.h>
5#include <xrpld/app/consensus/RCLCxPeerPos.h>
6#include <xrpld/app/consensus/RCLCxTx.h>
7#include <xrpld/app/misc/FeeVote.h>
8#include <xrpld/app/misc/NegativeUNLVote.h>
9#include <xrpld/consensus/Consensus.h>
10
11#include <xrpl/beast/utility/Journal.h>
12#include <xrpl/core/JobQueue.h>
13#include <xrpl/protocol/RippleLedgerHash.h>
14#include <xrpl/shamap/SHAMap.h>
15
16#include <atomic>
17#include <memory>
18#include <mutex>
19#include <set>
20#include <sstream>
21#include <string>
22
23namespace xrpl {
24
25class InboundTransactions;
26class LocalTxs;
27class LedgerMaster;
28class ValidatorKeys;
29
33{
36 constexpr static unsigned int censorshipWarnInternal = 15;
37
38 // Implements the Adaptor template interface required by Consensus.
39 class Adaptor
40 {
47
48 // If the server is validating, the necessary keying information:
50
51 // A randomly selected non-zero value used to tag our validations
53
54 // Ledger we most recently needed to acquire
57
58 // The timestamp of the last validation we used
60
61 // These members are queried via public accessors and are atomic for
62 // thread safety.
67
70
71 public:
77
79
80 Adaptor(
81 Application& app,
84 LocalTxs& localTxs,
85 InboundTransactions& inboundTransactions,
86 ValidatorKeys const& validatorKeys,
87 beast::Journal journal);
88
89 bool
90 validating() const
91 {
92 return validating_;
93 }
94
97 {
98 return prevProposers_;
99 }
100
103 {
104 return prevRoundTime_;
105 }
106
108 mode() const
109 {
110 return mode_;
111 }
112
119 bool
120 preStartRound(RCLCxLedger const& prevLedger, hash_set<NodeID> const& nowTrusted);
121
122 bool
123 haveValidated() const;
124
126 getValidLedgerIndex() const;
127
129 getQuorumKeys() const;
130
132 laggards(Ledger_t::Seq const seq, hash_set<NodeKey_t>& trustedKeys) const;
133
138 bool
139 validator() const;
140
148 void
149 updateOperatingMode(std::size_t const positions) const;
150
153 ConsensusParms const&
154 parms() const
155 {
156 return parms_;
157 }
158
159 private:
160 //---------------------------------------------------------------------
161 // The following members implement the generic Consensus requirements
162 // and are marked private to indicate ONLY Consensus<Adaptor> will call
163 // them (via friendship). Since they are called only from
164 // Consensus<Adaptor> methods and since RCLConsensus::consensus_ should
165 // only be accessed under lock, these will only be called under lock.
166 //
167 // In general, the idea is that there is only ONE thread that is running
168 // consensus code at anytime. The only special case is the dispatched
169 // onAccept call, which does not take a lock and relies on Consensus not
170 // changing state until a future call to startRound.
171 friend class Consensus<Adaptor>;
172
181 acquireLedger(LedgerHash const& hash);
182
187 void
188 share(RCLCxPeerPos const& peerPos);
189
196 void
197 share(RCLCxTx const& tx);
198
208 acquireTxSet(RCLTxSet::ID const& setId);
209
212 bool
213 hasOpenTransactions() const;
214
221 proposersValidated(LedgerHash const& h) const;
222
232 proposersFinished(RCLCxLedger const& ledger, LedgerHash const& h) const;
233
238 void
240
245 void
246 share(RCLTxSet const& txns);
247
259 uint256
260 getPrevLedger(uint256 ledgerID, RCLCxLedger const& ledger, ConsensusMode mode);
261
267 void
269
277 Result
278 onClose(RCLCxLedger const& ledger, NetClock::time_point const& closeTime, ConsensusMode mode);
279
293 void
294 onAccept(
295 Result const& result,
296 RCLCxLedger const& prevLedger,
297 NetClock::duration const& closeResolution,
298 ConsensusCloseTimes const& rawCloseTimes,
299 ConsensusMode const& mode,
300 Json::Value&& consensusJson,
301 bool const validating);
302
308 void
310 Result const& result,
311 RCLCxLedger const& prevLedger,
312 NetClock::duration const& closeResolution,
313 ConsensusCloseTimes const& rawCloseTimes,
314 ConsensusMode const& mode,
315 Json::Value&& consensusJson);
316
323 void
324 notify(protocol::NodeEvent ne, RCLCxLedger const& ledger, bool haveCorrectLCL);
325
330 void
331 doAccept(
332 Result const& result,
333 RCLCxLedger const& prevLedger,
334 NetClock::duration closeResolution,
335 ConsensusCloseTimes const& rawCloseTimes,
336 ConsensusMode const& mode,
337 Json::Value&& consensusJson);
338
361 buildLCL(
362 RCLCxLedger const& previousLedger,
363 CanonicalTXSet& retriableTxs,
364 NetClock::time_point closeTime,
365 bool closeTimeCorrect,
366 NetClock::duration closeResolution,
368 std::set<TxID>& failedTxs);
369
380 void
381 validate(RCLCxLedger const& ledger, RCLTxSet const& txns, bool proposing);
382 };
383
384public:
387 Application& app,
388 std::unique_ptr<FeeVote>&& feeVote,
390 LocalTxs& localTxs,
391 InboundTransactions& inboundTransactions,
393 ValidatorKeys const& validatorKeys,
394 beast::Journal journal);
395
396 RCLConsensus(RCLConsensus const&) = delete;
397
399 operator=(RCLConsensus const&) = delete;
400
402 bool
404 {
405 return adaptor_.validating();
406 }
407
412 {
413 return adaptor_.prevProposers();
414 }
415
425 {
426 return adaptor_.prevRoundTime();
427 }
428
431 mode() const
432 {
433 return adaptor_.mode();
434 }
435
437 phase() const
438 {
439 return consensus_.phase();
440 }
441
444 getJson(bool full) const;
445
449 void
451 NetClock::time_point const& now,
452 RCLCxLedger::ID const& prevLgrId,
453 RCLCxLedger const& prevLgr,
454 hash_set<NodeID> const& nowUntrusted,
455 hash_set<NodeID> const& nowTrusted,
457
459 void
461
463 void
464 gotTxSet(NetClock::time_point const& now, RCLTxSet const& txSet);
465
466 // @see Consensus::prevLedgerID
469 {
471 return consensus_.prevLedgerID();
472 }
473
475 void
477
479 bool
480 peerProposal(NetClock::time_point const& now, RCLCxPeerPos const& newProposal);
481
482 ConsensusParms const&
483 parms() const
484 {
485 return adaptor_.parms();
486 }
487
488private:
489 // Since Consensus does not provide intrinsic thread-safety, this mutex
490 // guards all calls to consensus_. adaptor_ uses atomics internally
491 // to allow concurrent access of its data members that have getters.
493
497};
498
509{
513 std::chrono::steady_clock::time_point start_;
514
515public:
516 explicit RclConsensusLogger(char const* label, bool validating, beast::Journal j);
518
521 {
522 return ss_;
523 }
524};
525} // namespace xrpl
Represents a JSON value.
Definition json_value.h:130
A generic endpoint for log messages.
Definition Journal.h:40
Holds transactions which were deferred to the next pass of consensus.
Generic implementation of consensus algorithm.
Definition Consensus.h:278
Manages the acquisition and lifetime of transaction sets.
Manager to create NegativeUNL votes.
std::chrono::time_point< NetClock > time_point
Definition chrono.h:45
A public key.
Definition PublicKey.h:42
InboundTransactions & inboundTransactions_
Result onClose(RCLCxLedger const &ledger, NetClock::time_point const &closeTime, ConsensusMode mode)
Close the open ledger and return initial consensus position.
bool preStartRound(RCLCxLedger const &prevLedger, hash_set< NodeID > const &nowTrusted)
Called before kicking off a new consensus round.
bool validator() const
Whether I am a validator.
LedgerIndex getValidLedgerIndex() const
void updateOperatingMode(std::size_t const positions) const
Update operating mode based on current peer positions.
std::size_t proposersFinished(RCLCxLedger const &ledger, LedgerHash const &h) const
Number of proposers that have validated a ledger descended from requested ledger.
void validate(RCLCxLedger const &ledger, RCLTxSet const &txns, bool proposing)
Validate the given ledger and share with peers as necessary.
std::size_t prevProposers() const
ConsensusParms const & parms() const
Consensus simulation parameters.
std::unique_ptr< FeeVote > feeVote_
std::atomic< bool > validating_
void doAccept(Result const &result, RCLCxLedger const &prevLedger, NetClock::duration closeResolution, ConsensusCloseTimes const &rawCloseTimes, ConsensusMode const &mode, Json::Value &&consensusJson)
Accept a new ledger based on the given transactions.
void propose(RCLCxPeerPos::Proposal const &proposal)
Propose the given position to my peers.
RCLCxLedger buildLCL(RCLCxLedger const &previousLedger, CanonicalTXSet &retriableTxs, NetClock::time_point closeTime, bool closeTimeCorrect, NetClock::duration closeResolution, std::chrono::milliseconds roundTime, std::set< TxID > &failedTxs)
Build the new last closed ledger.
ConsensusMode mode() const
NetClock::time_point lastValidationTime_
std::size_t proposersValidated(LedgerHash const &h) const
Number of proposers that have validated the given ledger.
void notify(protocol::NodeEvent ne, RCLCxLedger const &ledger, bool haveCorrectLCL)
Notify peers of a consensus state change.
void onAccept(Result const &result, RCLCxLedger const &prevLedger, NetClock::duration const &closeResolution, ConsensusCloseTimes const &rawCloseTimes, ConsensusMode const &mode, Json::Value &&consensusJson, bool const validating)
Process the accepted ledger.
std::atomic< ConsensusMode > mode_
std::pair< std::size_t, hash_set< NodeKey_t > > getQuorumKeys() const
std::optional< RCLTxSet > acquireTxSet(RCLTxSet::ID const &setId)
Acquire the transaction set associated with a proposal.
ValidatorKeys const & validatorKeys_
uint256 getPrevLedger(uint256 ledgerID, RCLCxLedger const &ledger, ConsensusMode mode)
Get the ID of the previous ledger/last closed ledger(LCL) on the network.
beast::Journal const j_
std::atomic< std::chrono::milliseconds > prevRoundTime_
std::size_t laggards(Ledger_t::Seq const seq, hash_set< NodeKey_t > &trustedKeys) const
void onForceAccept(Result const &result, RCLCxLedger const &prevLedger, NetClock::duration const &closeResolution, ConsensusCloseTimes const &rawCloseTimes, ConsensusMode const &mode, Json::Value &&consensusJson)
Process the accepted ledger that was a result of simulation/force accept.
std::optional< RCLCxLedger > acquireLedger(LedgerHash const &hash)
Attempt to acquire a specific ledger.
std::chrono::milliseconds prevRoundTime() const
bool hasOpenTransactions() const
Whether the open ledger has any transactions.
RCLCensorshipDetector< TxID, LedgerIndex > censorshipDetector_
std::atomic< std::size_t > prevProposers_
void onModeChange(ConsensusMode before, ConsensusMode after)
Notified of change in consensus mode.
std::uint64_t const valCookie_
void share(RCLCxPeerPos const &peerPos)
Share the given proposal with all peers.
Manages the generic consensus algorithm for use by the RCL.
Consensus< Adaptor > consensus_
void timerEntry(NetClock::time_point const &now, std::unique_ptr< std::stringstream > const &clog={})
void startRound(NetClock::time_point const &now, RCLCxLedger::ID const &prevLgrId, RCLCxLedger const &prevLgr, hash_set< NodeID > const &nowUntrusted, hash_set< NodeID > const &nowTrusted, std::unique_ptr< std::stringstream > const &clog)
Adjust the set of trusted validators and kick-off the next round of consensus.
bool validating() const
Whether we are validating consensus ledgers.
std::size_t prevProposers() const
Get the number of proposing peers that participated in the previous round.
RCLConsensus(RCLConsensus const &)=delete
beast::Journal const j_
bool peerProposal(NetClock::time_point const &now, RCLCxPeerPos const &newProposal)
void simulate(NetClock::time_point const &now, std::optional< std::chrono::milliseconds > consensusDelay)
ConsensusParms const & parms() const
RCLConsensus & operator=(RCLConsensus const &)=delete
Json::Value getJson(bool full) const
std::chrono::milliseconds prevRoundTime() const
Get duration of the previous round.
std::recursive_mutex mutex_
static constexpr unsigned int censorshipWarnInternal
Warn for transactions that haven't been included every so many ledgers.
ConsensusMode mode() const
void gotTxSet(NetClock::time_point const &now, RCLTxSet const &txSet)
RCLCxLedger::ID prevLedgerID() const
ConsensusPhase phase() const
Represents a ledger in RCLConsensus.
Definition RCLCxLedger.h:16
LedgerHash ID
Unique identifier of a ledger.
Definition RCLCxLedger.h:19
LedgerIndex Seq
Sequence number of a ledger.
Definition RCLCxLedger.h:21
A peer's signed, proposed position for use in RCLConsensus.
Represents a transaction in RCLConsensus.
Definition RCLCxTx.h:13
Represents a set of transactions in RCLConsensus.
Definition RCLCxTx.h:43
Collects logging information.
std::unique_ptr< std::stringstream > const & ss()
std::chrono::steady_clock::time_point start_
std::unique_ptr< std::stringstream > ss_
Validator keys and manifest as set in configuration file.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
base_uint< 160, detail::NodeIDTag > NodeID
NodeID is a 160-bit hash representing one node.
Definition UintTypes.h:39
ConsensusMode
Represents how a node currently participates in Consensus.
@ proposing
We are normal participant in consensus and propose our position.
@ observing
We are observing peer positions, but not proposing our position.
ConsensusPhase
Phases of consensus for a single ledger round.
bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
Definition View.cpp:3436
@ ledgerMaster
ledger master data for signing
@ proposal
proposal for signing
boost::outcome_v2::result< T, std::error_code > Result
Definition b58_utils.h:17
Stores the set of initial close times.
Consensus algorithm parameters.
Encapsulates the result of consensus.