rippled
RCLConsensus.h
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2013 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #ifndef RIPPLE_APP_CONSENSUS_RCLCONSENSUS_H_INCLUDED
21 #define RIPPLE_APP_CONSENSUS_RCLCONSENSUS_H_INCLUDED
22 
23 #include <ripple/app/consensus/RCLCensorshipDetector.h>
24 #include <ripple/app/consensus/RCLCxLedger.h>
25 #include <ripple/app/consensus/RCLCxPeerPos.h>
26 #include <ripple/app/consensus/RCLCxTx.h>
27 #include <ripple/app/misc/FeeVote.h>
28 #include <ripple/app/misc/NegativeUNLVote.h>
29 #include <ripple/basics/CountedObject.h>
30 #include <ripple/basics/Log.h>
31 #include <ripple/beast/utility/Journal.h>
32 #include <ripple/consensus/Consensus.h>
33 #include <ripple/core/JobQueue.h>
34 #include <ripple/overlay/Message.h>
35 #include <ripple/protocol/RippleLedgerHash.h>
36 #include <ripple/protocol/STValidation.h>
37 #include <ripple/shamap/SHAMap.h>
38 #include <atomic>
39 #include <mutex>
40 #include <set>
41 namespace ripple {
42 
43 class InboundTransactions;
44 class LocalTxs;
45 class LedgerMaster;
46 class ValidatorKeys;
47 
51 {
54  constexpr static unsigned int censorshipWarnInternal = 15;
55 
56  // Implements the Adaptor template interface required by Consensus.
57  class Adaptor
58  {
65 
66  // If the server is validating, the necessary keying information:
68 
69  // A randomly selected non-zero value used to tag our validations
71 
72  // Ledger we most recently needed to acquire
75 
76  // The timestamp of the last validation we used
78 
79  // These members are queried via public accesors and are atomic for
80  // thread safety.
86 
89 
90  public:
92  using NodeID_t = NodeID;
94  using TxSet_t = RCLTxSet;
96 
98 
99  Adaptor(
100  Application& app,
101  std::unique_ptr<FeeVote>&& feeVote,
102  LedgerMaster& ledgerMaster,
103  LocalTxs& localTxs,
104  InboundTransactions& inboundTransactions,
105  ValidatorKeys const& validatorKeys,
106  beast::Journal journal);
107 
108  bool
109  validating() const
110  {
111  return validating_;
112  }
113 
116  {
117  return prevProposers_;
118  }
119 
122  {
123  return prevRoundTime_;
124  }
125 
127  mode() const
128  {
129  return mode_;
130  }
131 
138  bool
140  RCLCxLedger const& prevLedger,
141  hash_set<NodeID> const& nowTrusted);
142 
143  bool
144  haveValidated() const;
145 
147  getValidLedgerIndex() const;
148 
150  getQuorumKeys() const;
151 
153  laggards(Ledger_t::Seq const seq, hash_set<NodeKey_t>& trustedKeys)
154  const;
155 
160  bool
161  validator() const;
162 
170  void
171  updateOperatingMode(std::size_t const positions) const;
172 
175  ConsensusParms const&
176  parms() const
177  {
178  return parms_;
179  }
180 
181  private:
182  //---------------------------------------------------------------------
183  // The following members implement the generic Consensus requirements
184  // and are marked private to indicate ONLY Consensus<Adaptor> will call
185  // them (via friendship). Since they are called only from
186  // Consensus<Adaptor> methods and since RCLConsensus::consensus_ should
187  // only be accessed under lock, these will only be called under lock.
188  //
189  // In general, the idea is that there is only ONE thread that is running
190  // consensus code at anytime. The only special case is the dispatched
191  // onAccept call, which does not take a lock and relies on Consensus not
192  // changing state until a future call to startRound.
193  friend class Consensus<Adaptor>;
194 
203  acquireLedger(LedgerHash const& hash);
204 
209  void
210  share(RCLCxPeerPos const& peerPos);
211 
218  void
219  share(RCLCxTx const& tx);
220 
230  acquireTxSet(RCLTxSet::ID const& setId);
231 
234  bool
235  hasOpenTransactions() const;
236 
243  proposersValidated(LedgerHash const& h) const;
244 
254  proposersFinished(RCLCxLedger const& ledger, LedgerHash const& h) const;
255 
260  void
261  propose(RCLCxPeerPos::Proposal const& proposal);
262 
267  void
268  share(RCLTxSet const& txns);
269 
281  uint256
283  uint256 ledgerID,
284  RCLCxLedger const& ledger,
286 
292  void
294 
302  Result
303  onClose(
304  RCLCxLedger const& ledger,
305  NetClock::time_point const& closeTime,
307 
320  void
321  onAccept(
322  Result const& result,
323  RCLCxLedger const& prevLedger,
324  NetClock::duration const& closeResolution,
325  ConsensusCloseTimes const& rawCloseTimes,
326  ConsensusMode const& mode,
327  Json::Value&& consensusJson);
328 
334  void
336  Result const& result,
337  RCLCxLedger const& prevLedger,
338  NetClock::duration const& closeResolution,
339  ConsensusCloseTimes const& rawCloseTimes,
340  ConsensusMode const& mode,
341  Json::Value&& consensusJson);
342 
349  void
350  notify(
351  protocol::NodeEvent ne,
352  RCLCxLedger const& ledger,
353  bool haveCorrectLCL);
354 
359  void
360  doAccept(
361  Result const& result,
362  RCLCxLedger const& prevLedger,
363  NetClock::duration closeResolution,
364  ConsensusCloseTimes const& rawCloseTimes,
365  ConsensusMode const& mode,
366  Json::Value&& consensusJson);
367 
390  buildLCL(
391  RCLCxLedger const& previousLedger,
392  CanonicalTXSet& retriableTxs,
393  NetClock::time_point closeTime,
394  bool closeTimeCorrect,
395  NetClock::duration closeResolution,
396  std::chrono::milliseconds roundTime,
397  std::set<TxID>& failedTxs);
398 
409  void
410  validate(
411  RCLCxLedger const& ledger,
412  RCLTxSet const& txns,
413  bool proposing);
414  };
415 
416 public:
418  RCLConsensus(
419  Application& app,
420  std::unique_ptr<FeeVote>&& feeVote,
421  LedgerMaster& ledgerMaster,
422  LocalTxs& localTxs,
423  InboundTransactions& inboundTransactions,
424  Consensus<Adaptor>::clock_type const& clock,
425  ValidatorKeys const& validatorKeys,
426  beast::Journal journal);
427 
428  RCLConsensus(RCLConsensus const&) = delete;
429 
430  RCLConsensus&
431  operator=(RCLConsensus const&) = delete;
432 
434  bool
435  validating() const
436  {
437  return adaptor_.validating();
438  }
439 
444  {
445  return adaptor_.prevProposers();
446  }
447 
457  {
458  return adaptor_.prevRoundTime();
459  }
460 
463  mode() const
464  {
465  return adaptor_.mode();
466  }
467 
469  phase() const
470  {
471  return consensus_.phase();
472  }
473 
476  getJson(bool full) const;
477 
481  void
482  startRound(
483  NetClock::time_point const& now,
484  RCLCxLedger::ID const& prevLgrId,
485  RCLCxLedger const& prevLgr,
486  hash_set<NodeID> const& nowUntrusted,
487  hash_set<NodeID> const& nowTrusted);
488 
490  void
491  timerEntry(NetClock::time_point const& now);
492 
494  void
495  gotTxSet(NetClock::time_point const& now, RCLTxSet const& txSet);
496 
497  // @see Consensus::prevLedgerID
499  prevLedgerID() const
500  {
502  return consensus_.prevLedgerID();
503  }
504 
506  void
507  simulate(
508  NetClock::time_point const& now,
510 
512  bool
513  peerProposal(
514  NetClock::time_point const& now,
515  RCLCxPeerPos const& newProposal);
516 
517  ConsensusParms const&
518  parms() const
519  {
520  return adaptor_.parms();
521  }
522 
523 private:
524  // Since Consensus does not provide intrinsic thread-safety, this mutex
525  // guards all calls to consensus_. adaptor_ uses atomics internally
526  // to allow concurrent access of its data members that have getters.
528 
532 };
533 } // namespace ripple
534 
535 #endif
ripple::RCLConsensus::prevLedgerID
RCLCxLedger::ID prevLedgerID() const
Definition: RCLConsensus.h:499
ripple::RCLConsensus::phase
ConsensusPhase phase() const
Definition: RCLConsensus.h:469
ripple::Application
Definition: Application.h:115
ripple::RCLConsensus::Adaptor::prevRoundTime_
std::atomic< std::chrono::milliseconds > prevRoundTime_
Definition: RCLConsensus.h:83
ripple::RCLCxPeerPos
A peer's signed, proposed position for use in RCLConsensus.
Definition: RCLCxPeerPos.h:43
ripple::RCLConsensus::Adaptor::valCookie_
const std::uint64_t valCookie_
Definition: RCLConsensus.h:70
ripple::RCLCxLedger::Seq
LedgerIndex Seq
Sequence number of a ledger.
Definition: RCLCxLedger.h:41
ripple::RCLConsensus::Adaptor::prevRoundTime
std::chrono::milliseconds prevRoundTime() const
Definition: RCLConsensus.h:121
ripple::RCLConsensus::Adaptor
Definition: RCLConsensus.h:57
ripple::RCLConsensus::getJson
Json::Value getJson(bool full) const
Definition: RCLConsensus.cpp:893
ripple::RCLConsensus::Adaptor::mode_
std::atomic< ConsensusMode > mode_
Definition: RCLConsensus.h:85
ripple::RCLConsensus::Adaptor::feeVote_
std::unique_ptr< FeeVote > feeVote_
Definition: RCLConsensus.h:60
ripple::RCLConsensus::startRound
void startRound(NetClock::time_point const &now, RCLCxLedger::ID const &prevLgrId, RCLCxLedger const &prevLgr, hash_set< NodeID > const &nowUntrusted, hash_set< NodeID > const &nowTrusted)
Adjust the set of trusted validators and kick-off the next round of consensus.
Definition: RCLConsensus.cpp:1047
ripple::NodeID
base_uint< 160, detail::NodeIDTag > NodeID
NodeID is a 160-bit hash representing one node.
Definition: UintTypes.h:59
ripple::RCLConsensus::Adaptor::acquireLedger
std::optional< RCLCxLedger > acquireLedger(LedgerHash const &hash)
Attempt to acquire a specific ledger.
Definition: RCLConsensus.cpp:121
ripple::RCLConsensus::consensus_
Consensus< Adaptor > consensus_
Definition: RCLConsensus.h:530
std::unordered_set
STL class.
std::pair
ripple::RCLConsensus::Adaptor::preStartRound
bool preStartRound(RCLCxLedger const &prevLedger, hash_set< NodeID > const &nowTrusted)
Called before kicking off a new consensus round.
Definition: RCLConsensus.cpp:957
ripple::RCLConsensus::mutex_
std::recursive_mutex mutex_
Definition: RCLConsensus.h:527
ripple::LedgerMaster
Definition: LedgerMaster.h:70
ripple::RCLConsensus::Adaptor::hasOpenTransactions
bool hasOpenTransactions() const
Whether the open ledger has any transactions.
Definition: RCLConsensus.cpp:253
ripple::Consensus
Generic implementation of consensus algorithm.
Definition: Consensus.h:284
ripple::RCLConsensus::gotTxSet
void gotTxSet(NetClock::time_point const &now, RCLTxSet const &txSet)
Definition: RCLConsensus.cpp:921
std::chrono::milliseconds
ripple::RCLConsensus::Adaptor::getPrevLedger
uint256 getPrevLedger(uint256 ledgerID, RCLCxLedger const &ledger, ConsensusMode mode)
Get the ID of the previous ledger/last closed ledger(LCL) on the network.
Definition: RCLConsensus.cpp:275
std::recursive_mutex
STL class.
std::lock_guard
STL class.
ripple::RCLConsensus::j_
const beast::Journal j_
Definition: RCLConsensus.h:531
ripple::RCLConsensus::timerEntry
void timerEntry(NetClock::time_point const &now)
Definition: RCLConsensus.cpp:905
ripple::RCLConsensus::Adaptor::nUnlVote_
NegativeUNLVote nUnlVote_
Definition: RCLConsensus.h:88
ripple::RCLConsensus::Adaptor::onClose
Result onClose(RCLCxLedger const &ledger, NetClock::time_point const &closeTime, ConsensusMode mode)
Close the open ledger and return initial consensus position.
Definition: RCLConsensus.cpp:297
ripple::ConsensusResult
Encapsulates the result of consensus.
Definition: ConsensusTypes.h:201
ripple::RCLConsensus::Adaptor::parms
ConsensusParms const & parms() const
Consensus simulation parameters.
Definition: RCLConsensus.h:176
ripple::ValidatorKeys
Validator keys and manifest as set in configuration file.
Definition: ValidatorKeys.h:36
ripple::CanonicalTXSet
Holds transactions which were deferred to the next pass of consensus.
Definition: CanonicalTXSet.h:38
ripple::RCLConsensus::Adaptor::doAccept
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.
Definition: RCLConsensus.cpp:442
ripple::RCLConsensus::RCLConsensus
RCLConsensus(Application &app, std::unique_ptr< FeeVote > &&feeVote, LedgerMaster &ledgerMaster, LocalTxs &localTxs, InboundTransactions &inboundTransactions, Consensus< Adaptor >::clock_type const &clock, ValidatorKeys const &validatorKeys, beast::Journal journal)
Constructor.
Definition: RCLConsensus.cpp:52
ripple::RCLConsensus::simulate
void simulate(NetClock::time_point const &now, std::optional< std::chrono::milliseconds > consensusDelay)
Definition: RCLConsensus.cpp:939
ripple::RCLConsensus::Adaptor::onAccept
void onAccept(Result const &result, RCLCxLedger const &prevLedger, NetClock::duration const &closeResolution, ConsensusCloseTimes const &rawCloseTimes, ConsensusMode const &mode, Json::Value &&consensusJson)
Process the accepted ledger.
Definition: RCLConsensus.cpp:413
ripple::ConsensusMode::observing
@ observing
We are observing peer positions, but not proposing our position.
ripple::base_uint< 256 >
ripple::RCLConsensus::Adaptor::updateOperatingMode
void updateOperatingMode(std::size_t const positions) const
Update operating mode based on current peer positions.
Definition: RCLConsensus.cpp:1040
ripple::RCLConsensus
Manages the generic consensus algorithm for use by the RCL.
Definition: RCLConsensus.h:50
ripple::RCLConsensus::Adaptor::haveValidated
bool haveValidated() const
Definition: RCLConsensus.cpp:1008
ripple::RCLConsensus::Adaptor::prevProposers
std::size_t prevProposers() const
Definition: RCLConsensus.h:115
ripple::RCLConsensus::Adaptor::laggards
std::size_t laggards(Ledger_t::Seq const seq, hash_set< NodeKey_t > &trustedKeys) const
Definition: RCLConsensus.cpp:1026
ripple::RCLConsensus::Adaptor::share
void share(RCLCxPeerPos const &peerPos)
Share the given proposal with all peers.
Definition: RCLConsensus.cpp:154
ripple::PublicKey
A public key.
Definition: PublicKey.h:59
ripple::RCLConsensus::peerProposal
bool peerProposal(NetClock::time_point const &now, RCLCxPeerPos const &newProposal)
Definition: RCLConsensus.cpp:948
ripple::RCLTxSet
Represents a set of transactions in RCLConsensus.
Definition: RCLCxTx.h:65
ripple::RCLConsensus::Adaptor::validate
void validate(RCLCxLedger const &ledger, RCLTxSet const &txns, bool proposing)
Validate the given ledger and share with peers as necessary.
Definition: RCLConsensus.cpp:790
ripple::RCLConsensus::Adaptor::mode
ConsensusMode mode() const
Definition: RCLConsensus.h:127
ripple::ConsensusPhase
ConsensusPhase
Phases of consensus for a single ledger round.
Definition: ConsensusTypes.h:103
ripple::RCLConsensus::Adaptor::Adaptor
Adaptor(Application &app, std::unique_ptr< FeeVote > &&feeVote, LedgerMaster &ledgerMaster, LocalTxs &localTxs, InboundTransactions &inboundTransactions, ValidatorKeys const &validatorKeys, beast::Journal journal)
Definition: RCLConsensus.cpp:74
std::chrono::time_point
ripple::RCLConsensus::mode
ConsensusMode mode() const
Definition: RCLConsensus.h:463
ripple::LocalTxs
Definition: LocalTxs.h:33
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
std::uint64_t
ripple::RCLConsensus::Adaptor::censorshipDetector_
RCLCensorshipDetector< TxID, LedgerIndex > censorshipDetector_
Definition: RCLConsensus.h:87
atomic
ripple::RCLConsensus::Adaptor::notify
void notify(protocol::NodeEvent ne, RCLCxLedger const &ledger, bool haveCorrectLCL)
Notify peers of a consensus state change.
Definition: RCLConsensus.cpp:710
ripple::RCLConsensus::adaptor_
Adaptor adaptor_
Definition: RCLConsensus.h:529
ripple::RCLConsensus::Adaptor::validator
bool validator() const
Whether I am a validator.
Definition: RCLConsensus.cpp:1034
ripple::RCLConsensus::parms
ConsensusParms const & parms() const
Definition: RCLConsensus.h:518
ripple::RCLConsensus::Adaptor::parms_
ConsensusParms parms_
Definition: RCLConsensus.h:74
beast::abstract_clock< std::chrono::steady_clock >
ripple::RCLConsensus::Adaptor::j_
const beast::Journal j_
Definition: RCLConsensus.h:64
ripple::RCLConsensus::Adaptor::acquireTxSet
std::optional< RCLTxSet > acquireTxSet(RCLTxSet::ID const &setId)
Acquire the transaction set associated with a proposal.
Definition: RCLConsensus.cpp:243
ripple::RCLConsensus::Adaptor::buildLCL
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.
Definition: RCLConsensus.cpp:749
ripple::RCLConsensus::censorshipWarnInternal
constexpr static unsigned int censorshipWarnInternal
Warn for transactions that haven't been included every so many ledgers.
Definition: RCLConsensus.h:54
ripple::RCLConsensus::Adaptor::onModeChange
void onModeChange(ConsensusMode before, ConsensusMode after)
Notified of change in consensus mode.
Definition: RCLConsensus.cpp:877
ripple::RCLCxLedger
Represents a ledger in RCLConsensus.
Definition: RCLCxLedger.h:35
ripple::RCLConsensus::operator=
RCLConsensus & operator=(RCLConsensus const &)=delete
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::RCLConsensus::prevRoundTime
std::chrono::milliseconds prevRoundTime() const
Get duration of the previous round.
Definition: RCLConsensus.h:456
ripple::ConsensusMode
ConsensusMode
Represents how a node currently participates in Consensus.
Definition: ConsensusTypes.h:55
ripple::RCLConsensus::Adaptor::getValidLedgerIndex
LedgerIndex getValidLedgerIndex() const
Definition: RCLConsensus.cpp:1014
ripple::RCLCensorshipDetector
Definition: RCLCensorshipDetector.h:32
ripple::ConsensusParms
Consensus algorithm parameters.
Definition: ConsensusParms.h:33
ripple::RCLConsensus::Adaptor::acquiringLedger_
LedgerHash acquiringLedger_
Definition: RCLConsensus.h:73
ripple::RCLConsensus::Adaptor::validating_
std::atomic< bool > validating_
Definition: RCLConsensus.h:81
ripple::RCLConsensus::prevProposers
std::size_t prevProposers() const
Get the number of proposing peers that participated in the previous round.
Definition: RCLConsensus.h:443
ripple::RCLConsensus::Adaptor::ledgerMaster_
LedgerMaster & ledgerMaster_
Definition: RCLConsensus.h:61
ripple::RCLConsensus::Adaptor::proposersValidated
std::size_t proposersValidated(LedgerHash const &h) const
Number of proposers that have validated the given ledger.
Definition: RCLConsensus.cpp:259
std::optional
mutex
ripple::after
static bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
Definition: Escrow.cpp:88
std::size_t
ripple::NegativeUNLVote
Manager to create NegativeUNL votes.
Definition: NegativeUNLVote.h:46
ripple::RCLConsensus::Adaptor::inboundTransactions_
InboundTransactions & inboundTransactions_
Definition: RCLConsensus.h:63
ripple::RCLConsensus::validating
bool validating() const
Whether we are validating consensus ledgers.
Definition: RCLConsensus.h:435
ripple::RCLCxTx
Represents a transaction in RCLConsensus.
Definition: RCLCxTx.h:35
ripple::RCLConsensus::Adaptor::app_
Application & app_
Definition: RCLConsensus.h:59
std::unique_ptr
STL class.
ripple::RCLConsensus::Adaptor::propose
void propose(RCLCxPeerPos::Proposal const &proposal)
Propose the given position to my peers.
Definition: RCLConsensus.cpp:199
ripple::RCLConsensus::Adaptor::localTxs_
LocalTxs & localTxs_
Definition: RCLConsensus.h:62
ripple::RCLConsensus::Adaptor::lastValidationTime_
NetClock::time_point lastValidationTime_
Definition: RCLConsensus.h:77
ripple::RCLConsensus::Adaptor::proposersFinished
std::size_t proposersFinished(RCLCxLedger const &ledger, LedgerHash const &h) const
Number of proposers that have validated a ledger descended from requested ledger.
Definition: RCLConsensus.cpp:265
ripple::RCLConsensus::Adaptor::prevProposers_
std::atomic< std::size_t > prevProposers_
Definition: RCLConsensus.h:82
ripple::RCLConsensus::Adaptor::validatorKeys_
ValidatorKeys const & validatorKeys_
Definition: RCLConsensus.h:67
ripple::RCLConsensus::Adaptor::onForceAccept
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.
Definition: RCLConsensus.cpp:395
set
ripple::RCLConsensus::Adaptor::getQuorumKeys
std::pair< std::size_t, hash_set< NodeKey_t > > getQuorumKeys() const
Definition: RCLConsensus.cpp:1020
ripple::RCLConsensus::Adaptor::validating
bool validating() const
Definition: RCLConsensus.h:109
ripple::ConsensusCloseTimes
Stores the set of initial close times.
Definition: ConsensusTypes.h:174
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::InboundTransactions
Manages the acquisition and lifetime of transaction sets.
Definition: InboundTransactions.h:35
ripple::ConsensusProposal< NodeID, uint256, uint256 >