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/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 {
53  constexpr static unsigned int censorshipWarnInternal = 15;
54 
55  // Implements the Adaptor template interface required by Consensus.
56  class Adaptor
57  {
64 
65  NodeID const nodeID_;
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 
88 
89  public:
91  using NodeID_t = NodeID;
93  using TxSet_t = RCLTxSet;
95 
97 
98  Adaptor(
99  Application& app,
100  std::unique_ptr<FeeVote>&& feeVote,
101  LedgerMaster& ledgerMaster,
102  LocalTxs& localTxs,
103  InboundTransactions& inboundTransactions,
104  ValidatorKeys const& validatorKeys,
105  beast::Journal journal);
106 
107  bool
108  validating() const
109  {
110  return validating_;
111  }
112 
115  {
116  return prevProposers_;
117  }
118 
121  {
122  return prevRoundTime_;
123  }
124 
126  mode() const
127  {
128  return mode_;
129  }
130 
136  bool
137  preStartRound(RCLCxLedger const& prevLedger);
138 
139  bool
140  haveValidated() const;
141 
143  getValidLedgerIndex() const;
144 
146  getQuorumKeys() const;
147 
149  laggards(Ledger_t::Seq const seq, hash_set<NodeKey_t>& trustedKeys)
150  const;
151 
156  bool
157  validator() const;
158 
166  void
167  updateOperatingMode(std::size_t const positions) const;
168 
171  ConsensusParms const&
172  parms() const
173  {
174  return parms_;
175  }
176 
177  private:
178  //---------------------------------------------------------------------
179  // The following members implement the generic Consensus requirements
180  // and are marked private to indicate ONLY Consensus<Adaptor> will call
181  // them (via friendship). Since they are called only from
182  // Consensus<Adaptor> methods and since RCLConsensus::consensus_ should
183  // only be accessed under lock, these will only be called under lock.
184  //
185  // In general, the idea is that there is only ONE thread that is running
186  // consensus code at anytime. The only special case is the dispatched
187  // onAccept call, which does not take a lock and relies on Consensus not
188  // changing state until a future call to startRound.
189  friend class Consensus<Adaptor>;
190 
198  boost::optional<RCLCxLedger>
199  acquireLedger(LedgerHash const& hash);
200 
205  void
206  share(RCLCxPeerPos const& peerPos);
207 
214  void
215  share(RCLCxTx const& tx);
216 
225  boost::optional<RCLTxSet>
226  acquireTxSet(RCLTxSet::ID const& setId);
227 
230  bool
231  hasOpenTransactions() const;
232 
239  proposersValidated(LedgerHash const& h) const;
240 
250  proposersFinished(RCLCxLedger const& ledger, LedgerHash const& h) const;
251 
256  void
257  propose(RCLCxPeerPos::Proposal const& proposal);
258 
263  void
264  share(RCLTxSet const& txns);
265 
277  uint256
279  uint256 ledgerID,
280  RCLCxLedger const& ledger,
282 
288  void
290 
298  Result
299  onClose(
300  RCLCxLedger const& ledger,
301  NetClock::time_point const& closeTime,
303 
316  void
317  onAccept(
318  Result const& result,
319  RCLCxLedger const& prevLedger,
320  NetClock::duration const& closeResolution,
321  ConsensusCloseTimes const& rawCloseTimes,
322  ConsensusMode const& mode,
323  Json::Value&& consensusJson);
324 
330  void
332  Result const& result,
333  RCLCxLedger const& prevLedger,
334  NetClock::duration const& closeResolution,
335  ConsensusCloseTimes const& rawCloseTimes,
336  ConsensusMode const& mode,
337  Json::Value&& consensusJson);
338 
345  void
346  notify(
347  protocol::NodeEvent ne,
348  RCLCxLedger const& ledger,
349  bool haveCorrectLCL);
350 
355  void
356  doAccept(
357  Result const& result,
358  RCLCxLedger const& prevLedger,
359  NetClock::duration closeResolution,
360  ConsensusCloseTimes const& rawCloseTimes,
361  ConsensusMode const& mode,
362  Json::Value&& consensusJson);
363 
386  buildLCL(
387  RCLCxLedger const& previousLedger,
388  CanonicalTXSet& retriableTxs,
389  NetClock::time_point closeTime,
390  bool closeTimeCorrect,
391  NetClock::duration closeResolution,
392  std::chrono::milliseconds roundTime,
393  std::set<TxID>& failedTxs);
394 
405  void
406  validate(
407  RCLCxLedger const& ledger,
408  RCLTxSet const& txns,
409  bool proposing);
410  };
411 
412 public:
414  RCLConsensus(
415  Application& app,
416  std::unique_ptr<FeeVote>&& feeVote,
417  LedgerMaster& ledgerMaster,
418  LocalTxs& localTxs,
419  InboundTransactions& inboundTransactions,
420  Consensus<Adaptor>::clock_type const& clock,
421  ValidatorKeys const& validatorKeys,
422  beast::Journal journal);
423 
424  RCLConsensus(RCLConsensus const&) = delete;
425 
426  RCLConsensus&
427  operator=(RCLConsensus const&) = delete;
428 
430  bool
431  validating() const
432  {
433  return adaptor_.validating();
434  }
435 
440  {
441  return adaptor_.prevProposers();
442  }
443 
453  {
454  return adaptor_.prevRoundTime();
455  }
456 
459  mode() const
460  {
461  return adaptor_.mode();
462  }
463 
465  phase() const
466  {
467  return consensus_.phase();
468  }
469 
472  getJson(bool full) const;
473 
475  void
476  startRound(
477  NetClock::time_point const& now,
478  RCLCxLedger::ID const& prevLgrId,
479  RCLCxLedger const& prevLgr,
480  hash_set<NodeID> const& nowUntrusted);
481 
483  void
484  timerEntry(NetClock::time_point const& now);
485 
487  void
488  gotTxSet(NetClock::time_point const& now, RCLTxSet const& txSet);
489 
490  // @see Consensus::prevLedgerID
492  prevLedgerID() const
493  {
495  return consensus_.prevLedgerID();
496  }
497 
499  void
500  simulate(
501  NetClock::time_point const& now,
502  boost::optional<std::chrono::milliseconds> consensusDelay);
503 
505  bool
506  peerProposal(
507  NetClock::time_point const& now,
508  RCLCxPeerPos const& newProposal);
509 
510  ConsensusParms const&
511  parms() const
512  {
513  return adaptor_.parms();
514  }
515 
516 private:
517  // Since Consensus does not provide intrinsic thread-safety, this mutex
518  // guards all calls to consensus_. adaptor_ uses atomics internally
519  // to allow concurrent access of its data members that have getters.
521 
525 };
526 } // namespace ripple
527 
528 #endif
ripple::RCLConsensus::prevLedgerID
RCLCxLedger::ID prevLedgerID() const
Definition: RCLConsensus.h:492
ripple::RCLConsensus::phase
ConsensusPhase phase() const
Definition: RCLConsensus.h:465
ripple::Application
Definition: Application.h:94
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:42
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:120
ripple::RCLConsensus::Adaptor
Definition: RCLConsensus.h:56
ripple::RCLConsensus::getJson
Json::Value getJson(bool full) const
Definition: RCLConsensus.cpp:856
ripple::RCLConsensus::Adaptor::mode_
std::atomic< ConsensusMode > mode_
Definition: RCLConsensus.h:85
ripple::RCLConsensus::Adaptor::feeVote_
std::unique_ptr< FeeVote > feeVote_
Definition: RCLConsensus.h:59
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:523
std::unordered_set
STL class.
std::pair
ripple::RCLConsensus::mutex_
std::recursive_mutex mutex_
Definition: RCLConsensus.h:520
ripple::LedgerMaster
Definition: LedgerMaster.h:54
ripple::RCLConsensus::Adaptor::hasOpenTransactions
bool hasOpenTransactions() const
Whether the open ledger has any transactions.
Definition: RCLConsensus.cpp:240
ripple::Consensus
Generic implementation of consensus algorithm.
Definition: Consensus.h:283
ripple::RCLConsensus::gotTxSet
void gotTxSet(NetClock::time_point const &now, RCLTxSet const &txSet)
Definition: RCLConsensus.cpp:884
std::chrono::milliseconds
ripple::RCLConsensus::Adaptor::valSecret_
const SecretKey valSecret_
Definition: RCLConsensus.h:67
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:262
std::recursive_mutex
STL class.
std::lock_guard
STL class.
ripple::RCLConsensus::j_
const beast::Journal j_
Definition: RCLConsensus.h:524
ripple::RCLConsensus::timerEntry
void timerEntry(NetClock::time_point const &now)
Definition: RCLConsensus.cpp:868
ripple::RCLConsensus::Adaptor::valPublic_
const PublicKey valPublic_
Definition: RCLConsensus.h:66
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:284
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:172
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:413
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:50
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:384
ripple::ConsensusMode::observing
@ observing
We are observing peer positions, but not proposing our position.
ripple::base_uint
Definition: base_uint.h:63
ripple::RCLConsensus::Adaptor::updateOperatingMode
void updateOperatingMode(std::size_t const positions) const
Update operating mode based on current peer positions.
Definition: RCLConsensus.cpp:996
ripple::RCLConsensus
Manages the generic consensus algorithm for use by the RCL.
Definition: RCLConsensus.h:49
ripple::RCLConsensus::Adaptor::haveValidated
bool haveValidated() const
Definition: RCLConsensus.cpp:964
ripple::RCLConsensus::Adaptor::prevProposers
std::size_t prevProposers() const
Definition: RCLConsensus.h:114
ripple::RCLConsensus::Adaptor::laggards
std::size_t laggards(Ledger_t::Seq const seq, hash_set< NodeKey_t > &trustedKeys) const
Definition: RCLConsensus.cpp:982
ripple::RCLConsensus::Adaptor::share
void share(RCLCxPeerPos const &peerPos)
Share the given proposal with all peers.
Definition: RCLConsensus.cpp:136
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:911
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:759
ripple::RCLConsensus::Adaptor::mode
ConsensusMode mode() const
Definition: RCLConsensus.h:126
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:73
std::chrono::time_point
ripple::RCLConsensus::mode
ConsensusMode mode() const
Definition: RCLConsensus.h:459
ripple::LocalTxs
Definition: LocalTxs.h:33
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
ripple::RCLConsensus::Adaptor::acquireLedger
boost::optional< RCLCxLedger > acquireLedger(LedgerHash const &hash)
Attempt to acquire a specific ledger.
Definition: RCLConsensus.cpp:101
std::uint64_t
ripple::RCLConsensus::Adaptor::censorshipDetector_
RCLCensorshipDetector< TxID, LedgerIndex > censorshipDetector_
Definition: RCLConsensus.h:87
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:679
ripple::RCLConsensus::adaptor_
Adaptor adaptor_
Definition: RCLConsensus.h:522
ripple::RCLConsensus::Adaptor::validator
bool validator() const
Whether I am a validator.
Definition: RCLConsensus.cpp:990
ripple::RCLConsensus::parms
ConsensusParms const & parms() const
Definition: RCLConsensus.h:511
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:63
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:718
ripple::RCLConsensus::censorshipWarnInternal
constexpr static unsigned int censorshipWarnInternal
Warn for transactions that haven't been included every so many ledgers.
Definition: RCLConsensus.h:53
ripple::RCLConsensus::Adaptor::onModeChange
void onModeChange(ConsensusMode before, ConsensusMode after)
Notified of change in consensus mode.
Definition: RCLConsensus.cpp:840
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:452
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:970
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::acquireTxSet
boost::optional< RCLTxSet > acquireTxSet(RCLTxSet::ID const &setId)
Acquire the transaction set associated with a proposal.
Definition: RCLConsensus.cpp:230
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:439
ripple::RCLConsensus::Adaptor::ledgerMaster_
LedgerMaster & ledgerMaster_
Definition: RCLConsensus.h:60
ripple::RCLConsensus::Adaptor::preStartRound
bool preStartRound(RCLCxLedger const &prevLedger)
Called before kicking off a new consensus round.
Definition: RCLConsensus.cpp:920
ripple::RCLConsensus::Adaptor::proposersValidated
std::size_t proposersValidated(LedgerHash const &h) const
Number of proposers that have validated the given ledger.
Definition: RCLConsensus.cpp:246
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::RCLConsensus::Adaptor::inboundTransactions_
InboundTransactions & inboundTransactions_
Definition: RCLConsensus.h:62
ripple::RCLConsensus::validating
bool validating() const
Whether we are validating consensus ledgers.
Definition: RCLConsensus.h:431
ripple::RCLCxTx
Represents a transaction in RCLConsensus.
Definition: RCLCxTx.h:35
ripple::RCLConsensus::Adaptor::app_
Application & app_
Definition: RCLConsensus.h:58
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:181
ripple::RCLConsensus::Adaptor::localTxs_
LocalTxs & localTxs_
Definition: RCLConsensus.h:61
ripple::RCLConsensus::Adaptor::lastValidationTime_
NetClock::time_point lastValidationTime_
Definition: RCLConsensus.h:77
ripple::RCLConsensus::Adaptor::nodeID_
const NodeID nodeID_
Definition: RCLConsensus.h:65
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:252
ripple::RCLConsensus::Adaptor::prevProposers_
std::atomic< std::size_t > prevProposers_
Definition: RCLConsensus.h:82
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:366
set
ripple::RCLConsensus::Adaptor::getQuorumKeys
std::pair< std::size_t, hash_set< NodeKey_t > > getQuorumKeys() const
Definition: RCLConsensus.cpp:976
ripple::RCLConsensus::Adaptor::validating
bool validating() const
Definition: RCLConsensus.h:108
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:36
ripple::RCLConsensus::simulate
void simulate(NetClock::time_point const &now, boost::optional< std::chrono::milliseconds > consensusDelay)
Definition: RCLConsensus.cpp:902
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:1003
ripple::ConsensusProposal< NodeID, uint256, uint256 >