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/RCLCxLedger.h>
24 #include <ripple/app/consensus/RCLCxPeerPos.h>
25 #include <ripple/app/consensus/RCLCxTx.h>
26 #include <ripple/app/consensus/RCLCensorshipDetector.h>
27 #include <ripple/app/misc/FeeVote.h>
28 #include <ripple/basics/CountedObject.h>
29 #include <ripple/basics/Log.h>
30 #include <ripple/beast/utility/Journal.h>
31 #include <ripple/consensus/Consensus.h>
32 #include <ripple/core/JobQueue.h>
33 #include <ripple/overlay/Message.h>
34 #include <ripple/protocol/RippleLedgerHash.h>
35 #include <ripple/protocol/STValidation.h>
36 #include <ripple/shamap/SHAMap.h>
37 #include <atomic>
38 #include <mutex>
39 #include <set>
40 namespace ripple {
41 
42 class InboundTransactions;
43 class LocalTxs;
44 class LedgerMaster;
45 class ValidatorKeys;
46 
50 {
52  constexpr static unsigned int censorshipWarnInternal = 15;
53 
54  // Implements the Adaptor template interface required by Consensus.
55  class Adaptor
56  {
63 
64  NodeID const nodeID_;
67 
68  // Ledger we most recently needed to acquire
71 
72  // The timestamp of the last validation we used
74 
75  // These members are queried via public accesors and are atomic for
76  // thread safety.
82 
84 
85  public:
87  using NodeID_t = NodeID;
89  using TxSet_t = RCLTxSet;
91 
93 
94  Adaptor(
95  Application& app,
96  std::unique_ptr<FeeVote>&& feeVote,
97  LedgerMaster& ledgerMaster,
98  LocalTxs& localTxs,
99  InboundTransactions& inboundTransactions,
100  ValidatorKeys const & validatorKeys,
101  beast::Journal journal);
102 
103  bool
104  validating() const
105  {
106  return validating_;
107  }
108 
111  {
112  return prevProposers_;
113  }
114 
117  {
118  return prevRoundTime_;
119  }
120 
122  mode() const
123  {
124  return mode_;
125  }
126 
132  bool
133  preStartRound(RCLCxLedger const & prevLedger);
134 
135  bool
136  haveValidated() const;
137 
139  getValidLedgerIndex() const;
140 
142  getQuorumKeys() const;
143 
145  laggards(Ledger_t::Seq const seq,
146  hash_set<NodeKey_t >& trustedKeys) const;
147 
152  bool
153  validator() const;
154 
162  void updateOperatingMode(std::size_t const positions) const;
163 
166  ConsensusParms const&
167  parms() const
168  {
169  return parms_;
170  }
171 
172  private:
173  //---------------------------------------------------------------------
174  // The following members implement the generic Consensus requirements
175  // and are marked private to indicate ONLY Consensus<Adaptor> will call
176  // them (via friendship). Since they are called only from Consensus<Adaptor>
177  // methods and since RCLConsensus::consensus_ should only be accessed
178  // under lock, these will only be called under lock.
179  //
180  // In general, the idea is that there is only ONE thread that is running
181  // consensus code at anytime. The only special case is the dispatched
182  // onAccept call, which does not take a lock and relies on Consensus not
183  // changing state until a future call to startRound.
184  friend class Consensus<Adaptor>;
185 
193  boost::optional<RCLCxLedger>
194  acquireLedger(LedgerHash const& hash);
195 
200  void
201  share(RCLCxPeerPos const& peerPos);
202 
209  void
210  share(RCLCxTx const& tx);
211 
220  boost::optional<RCLTxSet>
221  acquireTxSet(RCLTxSet::ID const& setId);
222 
225  bool
226  hasOpenTransactions() const;
227 
234  proposersValidated(LedgerHash const& h) const;
235 
245  proposersFinished(RCLCxLedger const & ledger, LedgerHash const& h) const;
246 
251  void
252  propose(RCLCxPeerPos::Proposal const& proposal);
253 
258  void
259  share(RCLTxSet const& txns);
260 
272  uint256
274  uint256 ledgerID,
275  RCLCxLedger const& ledger,
277 
283  void
284  onModeChange(
285  ConsensusMode before,
287 
295  Result
296  onClose(
297  RCLCxLedger const& ledger,
298  NetClock::time_point const& closeTime,
300 
313  void
314  onAccept(
315  Result const& result,
316  RCLCxLedger const& prevLedger,
317  NetClock::duration const& closeResolution,
318  ConsensusCloseTimes const& rawCloseTimes,
319  ConsensusMode const& mode,
320  Json::Value&& consensusJson);
321 
327  void
329  Result const& result,
330  RCLCxLedger const& prevLedger,
331  NetClock::duration const& closeResolution,
332  ConsensusCloseTimes const& rawCloseTimes,
333  ConsensusMode const& mode,
334  Json::Value&& consensusJson);
335 
342  void
343  notify(
344  protocol::NodeEvent ne,
345  RCLCxLedger const& ledger,
346  bool haveCorrectLCL);
347 
352  void
353  doAccept(
354  Result const& result,
355  RCLCxLedger const& prevLedger,
356  NetClock::duration closeResolution,
357  ConsensusCloseTimes const& rawCloseTimes,
358  ConsensusMode const& mode,
359  Json::Value&& consensusJson);
360 
383  buildLCL(
384  RCLCxLedger const& previousLedger,
385  CanonicalTXSet& retriableTxs,
386  NetClock::time_point closeTime,
387  bool closeTimeCorrect,
388  NetClock::duration closeResolution,
389  std::chrono::milliseconds roundTime,
390  std::set<TxID>& failedTxs);
391 
402  void
403  validate(RCLCxLedger const& ledger, RCLTxSet const& txns, bool proposing);
404  };
405 
406 public:
408  RCLConsensus(
409  Application& app,
410  std::unique_ptr<FeeVote>&& feeVote,
411  LedgerMaster& ledgerMaster,
412  LocalTxs& localTxs,
413  InboundTransactions& inboundTransactions,
414  Consensus<Adaptor>::clock_type const& clock,
415  ValidatorKeys const & validatorKeys,
416  beast::Journal journal);
417 
418  RCLConsensus(RCLConsensus const&) = delete;
419 
420  RCLConsensus&
421  operator=(RCLConsensus const&) = delete;
422 
424  bool
425  validating() const
426  {
427  return adaptor_.validating();
428  }
429 
434  {
435  return adaptor_.prevProposers();
436  }
437 
447  {
448  return adaptor_.prevRoundTime();
449  }
450 
453  mode() const
454  {
455  return adaptor_.mode();
456  }
457 
459  phase() const
460  {
461  return consensus_.phase();
462  }
463 
466  getJson(bool full) const;
467 
469  void
470  startRound(
471  NetClock::time_point const& now,
472  RCLCxLedger::ID const& prevLgrId,
473  RCLCxLedger const& prevLgr,
474  hash_set<NodeID> const& nowUntrusted);
475 
477  void
478  timerEntry(NetClock::time_point const& now);
479 
481  void
482  gotTxSet(NetClock::time_point const& now, RCLTxSet const& txSet);
483 
484  // @see Consensus::prevLedgerID
486  prevLedgerID() const
487  {
489  return consensus_.prevLedgerID();
490  }
491 
493  void
494  simulate(
495  NetClock::time_point const& now,
496  boost::optional<std::chrono::milliseconds> consensusDelay);
497 
499  bool
500  peerProposal(
501  NetClock::time_point const& now,
502  RCLCxPeerPos const& newProposal);
503 
504  ConsensusParms const &
505  parms() const
506  {
507  return adaptor_.parms();
508  }
509 
510 private:
511  // Since Consensus does not provide intrinsic thread-safety, this mutex
512  // guards all calls to consensus_. adaptor_ uses atomics internally
513  // to allow concurrent access of its data members that have getters.
515 
519 };
520 }
521 
522 #endif
ripple::RCLConsensus::prevLedgerID
RCLCxLedger::ID prevLedgerID() const
Definition: RCLConsensus.h:486
ripple::RCLConsensus::phase
ConsensusPhase phase() const
Definition: RCLConsensus.h:459
ripple::Application
Definition: Application.h:85
ripple::RCLConsensus::Adaptor::prevRoundTime_
std::atomic< std::chrono::milliseconds > prevRoundTime_
Definition: RCLConsensus.h:79
ripple::RCLCxPeerPos
A peer's signed, proposed position for use in RCLConsensus.
Definition: RCLCxPeerPos.h:42
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:116
ripple::RCLConsensus::Adaptor
Definition: RCLConsensus.h:55
ripple::RCLConsensus::getJson
Json::Value getJson(bool full) const
Definition: RCLConsensus.cpp:808
ripple::RCLConsensus::Adaptor::mode_
std::atomic< ConsensusMode > mode_
Definition: RCLConsensus.h:81
ripple::RCLConsensus::Adaptor::feeVote_
std::unique_ptr< FeeVote > feeVote_
Definition: RCLConsensus.h:58
ripple::NodeID
base_uint< 160, detail::NodeIDTag > NodeID
NodeID is a 160-bit hash representing one node.
Definition: UintTypes.h:59
ripple::RCLConsensus::consensus_
Consensus< Adaptor > consensus_
Definition: RCLConsensus.h:517
std::unordered_set
STL class.
std::pair
ripple::RCLConsensus::mutex_
std::recursive_mutex mutex_
Definition: RCLConsensus.h:514
ripple::LedgerMaster
Definition: LedgerMaster.h:60
ripple::RCLConsensus::Adaptor::hasOpenTransactions
bool hasOpenTransactions() const
Whether the open ledger has any transactions.
Definition: RCLConsensus.cpp:230
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:836
std::chrono::milliseconds
ripple::RCLConsensus::Adaptor::valSecret_
const SecretKey valSecret_
Definition: RCLConsensus.h:66
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:252
std::recursive_mutex
STL class.
std::lock_guard
STL class.
ripple::RCLConsensus::j_
const beast::Journal j_
Definition: RCLConsensus.h:518
ripple::RCLConsensus::timerEntry
void timerEntry(NetClock::time_point const &now)
Definition: RCLConsensus.cpp:820
ripple::RCLConsensus::Adaptor::valPublic_
const PublicKey valPublic_
Definition: RCLConsensus.h:65
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:274
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:167
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:36
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:405
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:48
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:376
ripple::ConsensusMode::observing
@ observing
We are observing peer positions, but not proposing our position.
ripple::base_uint
Definition: base_uint.h:65
ripple::RCLConsensus::Adaptor::updateOperatingMode
void updateOperatingMode(std::size_t const positions) const
Update operating mode based on current peer positions.
Definition: RCLConsensus.cpp:949
ripple::RCLConsensus
Manages the generic consensus algorithm for use by the RCL.
Definition: RCLConsensus.h:49
ripple::RCLConsensus::parms
const ConsensusParms & parms() const
Definition: RCLConsensus.h:505
ripple::RCLConsensus::Adaptor::haveValidated
bool haveValidated() const
Definition: RCLConsensus.cpp:918
ripple::RCLConsensus::Adaptor::prevProposers
std::size_t prevProposers() const
Definition: RCLConsensus.h:110
ripple::RCLConsensus::Adaptor::laggards
std::size_t laggards(Ledger_t::Seq const seq, hash_set< NodeKey_t > &trustedKeys) const
Definition: RCLConsensus.cpp:936
ripple::RCLConsensus::Adaptor::share
void share(RCLCxPeerPos const &peerPos)
Share the given proposal with all peers.
Definition: RCLConsensus.cpp:126
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:864
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:740
ripple::RCLConsensus::Adaptor::mode
ConsensusMode mode() const
Definition: RCLConsensus.h:122
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:71
std::chrono::time_point
ripple::RCLConsensus::mode
ConsensusMode mode() const
Definition: RCLConsensus.h:453
ripple::LocalTxs
Definition: LocalTxs.h:33
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:60
ripple::RCLConsensus::Adaptor::acquireLedger
boost::optional< RCLCxLedger > acquireLedger(LedgerHash const &hash)
Attempt to acquire a specific ledger.
Definition: RCLConsensus.cpp:92
std::uint32_t
ripple::RCLConsensus::Adaptor::censorshipDetector_
RCLCensorshipDetector< TxID, LedgerIndex > censorshipDetector_
Definition: RCLConsensus.h:83
ripple::SecretKey
A secret key.
Definition: SecretKey.h:36
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:665
ripple::RCLConsensus::adaptor_
Adaptor adaptor_
Definition: RCLConsensus.h:516
ripple::RCLConsensus::Adaptor::validator
bool validator() const
Whether I am a validator.
Definition: RCLConsensus.cpp:943
ripple::RCLConsensus::Adaptor::parms_
ConsensusParms parms_
Definition: RCLConsensus.h:70
beast::abstract_clock< std::chrono::steady_clock >
ripple::RCLConsensus::Adaptor::j_
const beast::Journal j_
Definition: RCLConsensus.h:62
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:705
ripple::RCLConsensus::censorshipWarnInternal
constexpr static unsigned int censorshipWarnInternal
Warn for transactions that haven't been included every so many ledgers.
Definition: RCLConsensus.h:52
ripple::RCLConsensus::Adaptor::onModeChange
void onModeChange(ConsensusMode before, ConsensusMode after)
Notified of change in consensus mode.
Definition: RCLConsensus.cpp:792
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:446
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:924
ripple::RCLCensorshipDetector
Definition: RCLCensorshipDetector.h:32
ripple::ConsensusParms
Consensus algorithm parameters.
Definition: ConsensusParms.h:33
ripple::RCLConsensus::Adaptor::acquiringLedger_
LedgerHash acquiringLedger_
Definition: RCLConsensus.h:69
ripple::RCLConsensus::Adaptor::acquireTxSet
boost::optional< RCLTxSet > acquireTxSet(RCLTxSet::ID const &setId)
Acquire the transaction set associated with a proposal.
Definition: RCLConsensus.cpp:220
ripple::RCLConsensus::Adaptor::validating_
std::atomic< bool > validating_
Definition: RCLConsensus.h:77
ripple::RCLConsensus::prevProposers
std::size_t prevProposers() const
Get the number of proposing peers that participated in the previous round.
Definition: RCLConsensus.h:433
ripple::RCLConsensus::Adaptor::ledgerMaster_
LedgerMaster & ledgerMaster_
Definition: RCLConsensus.h:59
ripple::RCLConsensus::Adaptor::preStartRound
bool preStartRound(RCLCxLedger const &prevLedger)
Called before kicking off a new consensus round.
Definition: RCLConsensus.cpp:873
ripple::RCLConsensus::Adaptor::proposersValidated
std::size_t proposersValidated(LedgerHash const &h) const
Number of proposers that have validated the given ledger.
Definition: RCLConsensus.cpp:236
mutex
ripple::after
static bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
Definition: Escrow.cpp:87
std::size_t
ripple::RCLConsensus::Adaptor::inboundTransactions_
InboundTransactions & inboundTransactions_
Definition: RCLConsensus.h:61
ripple::RCLConsensus::validating
bool validating() const
Whether we are validating consensus ledgers.
Definition: RCLConsensus.h:425
ripple::RCLCxTx
Represents a transaction in RCLConsensus.
Definition: RCLCxTx.h:35
ripple::RCLConsensus::Adaptor::app_
Application & app_
Definition: RCLConsensus.h:57
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:171
ripple::RCLConsensus::Adaptor::localTxs_
LocalTxs & localTxs_
Definition: RCLConsensus.h:60
ripple::RCLConsensus::Adaptor::lastValidationTime_
NetClock::time_point lastValidationTime_
Definition: RCLConsensus.h:73
ripple::RCLConsensus::Adaptor::nodeID_
const NodeID nodeID_
Definition: RCLConsensus.h:64
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:242
ripple::RCLConsensus::Adaptor::prevProposers_
std::atomic< std::size_t > prevProposers_
Definition: RCLConsensus.h:78
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:358
set
ripple::RCLConsensus::Adaptor::getQuorumKeys
std::pair< std::size_t, hash_set< NodeKey_t > > getQuorumKeys() const
Definition: RCLConsensus.cpp:930
ripple::RCLConsensus::Adaptor::validating
bool validating() const
Definition: RCLConsensus.h:104
ripple::ConsensusCloseTimes
Stores the set of initial close times.
Definition: ConsensusTypes.h:174
Json::Value
Represents a JSON value.
Definition: json_value.h:141
ripple::InboundTransactions
Manages the acquisition and lifetime of transaction sets.
Definition: InboundTransactions.h:36
ripple::RCLConsensus::simulate
void simulate(NetClock::time_point const &now, boost::optional< std::chrono::milliseconds > consensusDelay)
Definition: RCLConsensus.cpp:855
ripple::RCLConsensus::startRound
void startRound(NetClock::time_point const &now, RCLCxLedger::ID const &prevLgrId, RCLCxLedger const &prevLgr, hash_set< NodeID > const &nowUntrusted)
Definition: RCLConsensus.cpp:956
ripple::ConsensusProposal< NodeID, uint256, uint256 >