rippled
Loading...
Searching...
No Matches
RCLConsensus.h
1#ifndef XRPL_APP_CONSENSUS_RCLCONSENSUS_H_INCLUDED
2#define XRPL_APP_CONSENSUS_RCLCONSENSUS_H_INCLUDED
3
4#include <xrpld/app/consensus/RCLCensorshipDetector.h>
5#include <xrpld/app/consensus/RCLCxLedger.h>
6#include <xrpld/app/consensus/RCLCxPeerPos.h>
7#include <xrpld/app/consensus/RCLCxTx.h>
8#include <xrpld/app/misc/FeeVote.h>
9#include <xrpld/app/misc/NegativeUNLVote.h>
10#include <xrpld/consensus/Consensus.h>
11#include <xrpld/core/JobQueue.h>
12
13#include <xrpl/beast/utility/Journal.h>
14#include <xrpl/protocol/RippleLedgerHash.h>
15#include <xrpl/shamap/SHAMap.h>
16
17#include <atomic>
18#include <memory>
19#include <mutex>
20#include <set>
21#include <sstream>
22#include <string>
23
24namespace ripple {
25
26class InboundTransactions;
27class LocalTxs;
28class LedgerMaster;
29class ValidatorKeys;
30
34{
37 constexpr static unsigned int censorshipWarnInternal = 15;
38
39 // Implements the Adaptor template interface required by Consensus.
40 class Adaptor
41 {
48
49 // If the server is validating, the necessary keying information:
51
52 // A randomly selected non-zero value used to tag our validations
54
55 // Ledger we most recently needed to acquire
58
59 // The timestamp of the last validation we used
61
62 // These members are queried via public accesors and are atomic for
63 // thread safety.
69
72
73 public:
79
81
82 Adaptor(
83 Application& app,
86 LocalTxs& localTxs,
87 InboundTransactions& inboundTransactions,
88 ValidatorKeys const& validatorKeys,
89 beast::Journal journal);
90
91 bool
92 validating() const
93 {
94 return validating_;
95 }
96
99 {
100 return prevProposers_;
101 }
102
105 {
106 return prevRoundTime_;
107 }
108
110 mode() const
111 {
112 return mode_;
113 }
114
121 bool
123 RCLCxLedger const& prevLedger,
124 hash_set<NodeID> const& nowTrusted);
125
126 bool
127 haveValidated() const;
128
130 getValidLedgerIndex() const;
131
133 getQuorumKeys() const;
134
136 laggards(Ledger_t::Seq const seq, hash_set<NodeKey_t>& trustedKeys)
137 const;
138
143 bool
144 validator() const;
145
153 void
154 updateOperatingMode(std::size_t const positions) const;
155
158 ConsensusParms const&
159 parms() const
160 {
161 return parms_;
162 }
163
164 private:
165 //---------------------------------------------------------------------
166 // The following members implement the generic Consensus requirements
167 // and are marked private to indicate ONLY Consensus<Adaptor> will call
168 // them (via friendship). Since they are called only from
169 // Consensus<Adaptor> methods and since RCLConsensus::consensus_ should
170 // only be accessed under lock, these will only be called under lock.
171 //
172 // In general, the idea is that there is only ONE thread that is running
173 // consensus code at anytime. The only special case is the dispatched
174 // onAccept call, which does not take a lock and relies on Consensus not
175 // changing state until a future call to startRound.
176 friend class Consensus<Adaptor>;
177
186 acquireLedger(LedgerHash const& hash);
187
192 void
193 share(RCLCxPeerPos const& peerPos);
194
201 void
202 share(RCLCxTx const& tx);
203
213 acquireTxSet(RCLTxSet::ID const& setId);
214
217 bool
218 hasOpenTransactions() const;
219
226 proposersValidated(LedgerHash const& h) const;
227
237 proposersFinished(RCLCxLedger const& ledger, LedgerHash const& h) const;
238
243 void
245
250 void
251 share(RCLTxSet const& txns);
252
264 uint256
266 uint256 ledgerID,
267 RCLCxLedger const& ledger,
269
275 void
277
285 Result
286 onClose(
287 RCLCxLedger const& ledger,
288 NetClock::time_point const& closeTime,
290
304 void
305 onAccept(
306 Result const& result,
307 RCLCxLedger const& prevLedger,
308 NetClock::duration const& closeResolution,
309 ConsensusCloseTimes const& rawCloseTimes,
310 ConsensusMode const& mode,
311 Json::Value&& consensusJson,
312 bool const validating);
313
319 void
321 Result const& result,
322 RCLCxLedger const& prevLedger,
323 NetClock::duration const& closeResolution,
324 ConsensusCloseTimes const& rawCloseTimes,
325 ConsensusMode const& mode,
326 Json::Value&& consensusJson);
327
334 void
335 notify(
336 protocol::NodeEvent ne,
337 RCLCxLedger const& ledger,
338 bool haveCorrectLCL);
339
344 void
345 doAccept(
346 Result const& result,
347 RCLCxLedger const& prevLedger,
348 NetClock::duration closeResolution,
349 ConsensusCloseTimes const& rawCloseTimes,
350 ConsensusMode const& mode,
351 Json::Value&& consensusJson);
352
375 buildLCL(
376 RCLCxLedger const& previousLedger,
377 CanonicalTXSet& retriableTxs,
378 NetClock::time_point closeTime,
379 bool closeTimeCorrect,
380 NetClock::duration closeResolution,
382 std::set<TxID>& failedTxs);
383
394 void
395 validate(
396 RCLCxLedger const& ledger,
397 RCLTxSet const& txns,
398 bool proposing);
399 };
400
401public:
404 Application& app,
405 std::unique_ptr<FeeVote>&& feeVote,
407 LocalTxs& localTxs,
408 InboundTransactions& inboundTransactions,
410 ValidatorKeys const& validatorKeys,
411 beast::Journal journal);
412
413 RCLConsensus(RCLConsensus const&) = delete;
414
416 operator=(RCLConsensus const&) = delete;
417
419 bool
421 {
422 return adaptor_.validating();
423 }
424
429 {
430 return adaptor_.prevProposers();
431 }
432
442 {
443 return adaptor_.prevRoundTime();
444 }
445
448 mode() const
449 {
450 return adaptor_.mode();
451 }
452
454 phase() const
455 {
456 return consensus_.phase();
457 }
458
461 getJson(bool full) const;
462
466 void
468 NetClock::time_point const& now,
469 RCLCxLedger::ID const& prevLgrId,
470 RCLCxLedger const& prevLgr,
471 hash_set<NodeID> const& nowUntrusted,
472 hash_set<NodeID> const& nowTrusted,
474
476 void
478 NetClock::time_point const& now,
479 std::unique_ptr<std::stringstream> const& clog = {});
480
482 void
483 gotTxSet(NetClock::time_point const& now, RCLTxSet const& txSet);
484
485 // @see Consensus::prevLedgerID
488 {
490 return consensus_.prevLedgerID();
491 }
492
494 void
495 simulate(
496 NetClock::time_point const& now,
498
500 bool
502 NetClock::time_point const& now,
503 RCLCxPeerPos const& newProposal);
504
505 ConsensusParms const&
506 parms() const
507 {
508 return adaptor_.parms();
509 }
510
511private:
512 // Since Consensus does not provide intrinsic thread-safety, this mutex
513 // guards all calls to consensus_. adaptor_ uses atomics internally
514 // to allow concurrent access of its data members that have getters.
516
520};
521
532{
536 std::chrono::steady_clock::time_point start_;
537
538public:
539 explicit RclConsensusLogger(
540 char const* label,
541 bool validating,
544
547 {
548 return ss_;
549 }
550};
551} // namespace ripple
552
553#endif
Represents a JSON value.
Definition json_value.h:130
A generic endpoint for log messages.
Definition Journal.h:41
Holds transactions which were deferred to the next pass of consensus.
Generic implementation of consensus algorithm.
Definition Consensus.h:279
Manages the acquisition and lifetime of transaction sets.
Manager to create NegativeUNL votes.
std::chrono::time_point< NetClock > time_point
Definition chrono.h:50
A public key.
Definition PublicKey.h:43
void propose(RCLCxPeerPos::Proposal const &proposal)
Propose the given position to my peers.
ValidatorKeys const & validatorKeys_
beast::Journal const j_
std::atomic< ConsensusMode > mode_
InboundTransactions & inboundTransactions_
std::atomic< std::size_t > prevProposers_
Result onClose(RCLCxLedger const &ledger, NetClock::time_point const &closeTime, ConsensusMode mode)
Close the open ledger and return initial consensus position.
void share(RCLCxPeerPos const &peerPos)
Share the given proposal with all peers.
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.
ConsensusMode mode() const
std::chrono::milliseconds prevRoundTime() const
void onModeChange(ConsensusMode before, ConsensusMode after)
Notified of change in consensus mode.
std::size_t laggards(Ledger_t::Seq const seq, hash_set< NodeKey_t > &trustedKeys) const
RCLCensorshipDetector< TxID, LedgerIndex > censorshipDetector_
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.
bool validator() const
Whether I am a validator.
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.
std::optional< RCLCxLedger > acquireLedger(LedgerHash const &hash)
Attempt to acquire a specific ledger.
std::unique_ptr< FeeVote > feeVote_
LedgerIndex getValidLedgerIndex() const
std::size_t proposersFinished(RCLCxLedger const &ledger, LedgerHash const &h) const
Number of proposers that have validated a ledger descended from requested ledger.
std::size_t prevProposers() const
ConsensusParms const & parms() const
Consensus simulation parameters.
NetClock::time_point lastValidationTime_
std::optional< RCLTxSet > acquireTxSet(RCLTxSet::ID const &setId)
Acquire the transaction set associated with a proposal.
bool hasOpenTransactions() const
Whether the open ledger has any transactions.
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.
void validate(RCLCxLedger const &ledger, RCLTxSet const &txns, bool proposing)
Validate the given ledger and share with peers as necessary.
std::atomic< std::chrono::milliseconds > prevRoundTime_
std::uint64_t const valCookie_
bool preStartRound(RCLCxLedger const &prevLedger, hash_set< NodeID > const &nowTrusted)
Called before kicking off a new consensus round.
uint256 getPrevLedger(uint256 ledgerID, RCLCxLedger const &ledger, ConsensusMode mode)
Get the ID of the previous ledger/last closed ledger(LCL) on the network.
std::size_t proposersValidated(LedgerHash const &h) const
Number of proposers that have validated the given ledger.
std::atomic< bool > validating_
void notify(protocol::NodeEvent ne, RCLCxLedger const &ledger, bool haveCorrectLCL)
Notify peers of a consensus state change.
void updateOperatingMode(std::size_t const positions) const
Update operating mode based on current peer positions.
std::pair< std::size_t, hash_set< NodeKey_t > > getQuorumKeys() const
Manages the generic consensus algorithm for use by the RCL.
RCLConsensus(RCLConsensus const &)=delete
void gotTxSet(NetClock::time_point const &now, RCLTxSet const &txSet)
std::size_t prevProposers() const
Get the number of proposing peers that participated in the previous round.
void simulate(NetClock::time_point const &now, std::optional< std::chrono::milliseconds > consensusDelay)
ConsensusPhase phase() const
bool validating() const
Whether we are validating consensus ledgers.
RCLConsensus & operator=(RCLConsensus const &)=delete
std::chrono::milliseconds prevRoundTime() const
Get duration of the previous round.
ConsensusMode mode() const
static constexpr unsigned int censorshipWarnInternal
Warn for transactions that haven't been included every so many ledgers.
std::recursive_mutex mutex_
Consensus< Adaptor > consensus_
bool peerProposal(NetClock::time_point const &now, RCLCxPeerPos const &newProposal)
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.
void timerEntry(NetClock::time_point const &now, std::unique_ptr< std::stringstream > const &clog={})
ConsensusParms const & parms() const
Json::Value getJson(bool full) const
RCLCxLedger::ID prevLedgerID() const
beast::Journal const j_
Represents a ledger in RCLConsensus.
Definition RCLCxLedger.h:17
LedgerHash ID
Unique identifier of a ledger.
Definition RCLCxLedger.h:20
LedgerIndex Seq
Sequence number of a ledger.
Definition RCLCxLedger.h:22
A peer's signed, proposed position for use in RCLConsensus.
Represents a transaction in RCLConsensus.
Definition RCLCxTx.h:14
Represents a set of transactions in RCLConsensus.
Definition RCLCxTx.h:44
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:6
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.
base_uint< 160, detail::NodeIDTag > NodeID
NodeID is a 160-bit hash representing one node.
Definition UintTypes.h:40
boost::outcome_v2::result< T, std::error_code > Result
Definition b58_utils.h:18
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:3247
@ ledgerMaster
ledger master data for signing
@ proposal
proposal for signing
Stores the set of initial close times.
Consensus algorithm parameters.
Encapsulates the result of consensus.