rippled
RCLConsensus.cpp
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 #include <ripple/app/consensus/RCLConsensus.h>
21 #include <ripple/app/consensus/RCLValidations.h>
22 #include <ripple/app/ledger/BuildLedger.h>
23 #include <ripple/app/ledger/InboundLedgers.h>
24 #include <ripple/app/ledger/InboundTransactions.h>
25 #include <ripple/app/ledger/Ledger.h>
26 #include <ripple/app/ledger/LedgerMaster.h>
27 #include <ripple/app/ledger/LocalTxs.h>
28 #include <ripple/app/ledger/OpenLedger.h>
29 #include <ripple/app/misc/AmendmentTable.h>
30 #include <ripple/app/misc/HashRouter.h>
31 #include <ripple/app/misc/LoadFeeTrack.h>
32 #include <ripple/app/misc/NegativeUNLVote.h>
33 #include <ripple/app/misc/NetworkOPs.h>
34 #include <ripple/app/misc/TxQ.h>
35 #include <ripple/app/misc/ValidatorKeys.h>
36 #include <ripple/app/misc/ValidatorList.h>
37 #include <ripple/basics/random.h>
38 #include <ripple/beast/core/LexicalCast.h>
39 #include <ripple/consensus/LedgerTiming.h>
40 #include <ripple/nodestore/DatabaseShard.h>
41 #include <ripple/overlay/Overlay.h>
42 #include <ripple/overlay/predicates.h>
43 #include <ripple/protocol/BuildInfo.h>
44 #include <ripple/protocol/Feature.h>
45 #include <ripple/protocol/digest.h>
46 
47 #include <algorithm>
48 #include <mutex>
49 
50 namespace ripple {
51 
53  Application& app,
54  std::unique_ptr<FeeVote>&& feeVote,
55  LedgerMaster& ledgerMaster,
56  LocalTxs& localTxs,
57  InboundTransactions& inboundTransactions,
58  Consensus<Adaptor>::clock_type const& clock,
59  ValidatorKeys const& validatorKeys,
60  beast::Journal journal)
61  : adaptor_(
62  app,
63  std::move(feeVote),
65  localTxs,
66  inboundTransactions,
67  validatorKeys,
68  journal)
69  , consensus_(clock, adaptor_, journal)
70  , j_(journal)
71 
72 {
73 }
74 
76  Application& app,
77  std::unique_ptr<FeeVote>&& feeVote,
78  LedgerMaster& ledgerMaster,
79  LocalTxs& localTxs,
80  InboundTransactions& inboundTransactions,
81  ValidatorKeys const& validatorKeys,
82  beast::Journal journal)
83  : app_(app)
84  , feeVote_(std::move(feeVote))
85  , ledgerMaster_(ledgerMaster)
86  , localTxs_(localTxs)
87  , inboundTransactions_{inboundTransactions}
88  , j_(journal)
89  , nodeID_{validatorKeys.nodeID}
90  , valPublic_{validatorKeys.publicKey}
91  , valSecret_{validatorKeys.secretKey}
92  , valCookie_{rand_int<std::uint64_t>(
93  1,
95  , nUnlVote_(nodeID_, j_)
96 {
97  assert(valCookie_ != 0);
98 
99  JLOG(j_.info()) << "Consensus engine started"
100  << " (Node: " << to_string(nodeID_)
101  << ", Cookie: " << valCookie_ << ")";
102 }
103 
104 boost::optional<RCLCxLedger>
106 {
107  // we need to switch the ledger we're working from
108  auto built = ledgerMaster_.getLedgerByHash(hash);
109  if (!built)
110  {
111  if (acquiringLedger_ != hash)
112  {
113  // need to start acquiring the correct consensus LCL
114  JLOG(j_.warn()) << "Need consensus ledger " << hash;
115 
116  // Tell the ledger acquire system that we need the consensus ledger
117  acquiringLedger_ = hash;
118 
119  app_.getJobQueue().addJob(
120  jtADVANCE,
121  "getConsensusLedger",
122  [id = hash, &app = app_](Job&) {
123  app.getInboundLedgers().acquire(
125  });
126  }
127  return boost::none;
128  }
129 
130  assert(!built->open() && built->isImmutable());
131  assert(built->info().hash == hash);
132 
133  // Notify inbound transactions of the new ledger sequence number
134  inboundTransactions_.newRound(built->info().seq);
135 
136  return RCLCxLedger(built);
137 }
138 
139 void
141 {
142  protocol::TMProposeSet prop;
143 
144  auto const& proposal = peerPos.proposal();
145 
146  prop.set_proposeseq(proposal.proposeSeq());
147  prop.set_closetime(proposal.closeTime().time_since_epoch().count());
148 
149  prop.set_currenttxhash(
150  proposal.position().begin(), proposal.position().size());
151  prop.set_previousledger(
152  proposal.prevLedger().begin(), proposal.position().size());
153 
154  auto const pk = peerPos.publicKey().slice();
155  prop.set_nodepubkey(pk.data(), pk.size());
156 
157  auto const sig = peerPos.signature();
158  prop.set_signature(sig.data(), sig.size());
159 
160  app_.overlay().relay(prop, peerPos.suppressionID(), peerPos.publicKey());
161 }
162 
163 void
165 {
166  // If we didn't relay this transaction recently, relay it to all peers
167  if (app_.getHashRouter().shouldRelay(tx.id()))
168  {
169  JLOG(j_.debug()) << "Relaying disputed tx " << tx.id();
170  auto const slice = tx.tx_.slice();
171  protocol::TMTransaction msg;
172  msg.set_rawtransaction(slice.data(), slice.size());
173  msg.set_status(protocol::tsNEW);
174  msg.set_receivetimestamp(
175  app_.timeKeeper().now().time_since_epoch().count());
176  app_.overlay().foreach(send_always(
177  std::make_shared<Message>(msg, protocol::mtTRANSACTION)));
178  }
179  else
180  {
181  JLOG(j_.debug()) << "Not relaying disputed tx " << tx.id();
182  }
183 }
184 void
186 {
187  JLOG(j_.trace()) << "We propose: "
188  << (proposal.isBowOut()
189  ? std::string("bowOut")
190  : ripple::to_string(proposal.position()));
191 
192  protocol::TMProposeSet prop;
193 
194  prop.set_currenttxhash(
195  proposal.position().begin(), proposal.position().size());
196  prop.set_previousledger(
197  proposal.prevLedger().begin(), proposal.prevLedger().size());
198  prop.set_proposeseq(proposal.proposeSeq());
199  prop.set_closetime(proposal.closeTime().time_since_epoch().count());
200 
201  prop.set_nodepubkey(valPublic_.data(), valPublic_.size());
202 
203  auto signingHash = sha512Half(
205  std::uint32_t(proposal.proposeSeq()),
206  proposal.closeTime().time_since_epoch().count(),
207  proposal.prevLedger(),
208  proposal.position());
209 
210  auto sig = signDigest(valPublic_, valSecret_, signingHash);
211 
212  prop.set_signature(sig.data(), sig.size());
213 
214  auto const suppression = proposalUniqueId(
215  proposal.position(),
216  proposal.prevLedger(),
217  proposal.proposeSeq(),
218  proposal.closeTime(),
219  valPublic_,
220  sig);
221 
222  app_.getHashRouter().addSuppression(suppression);
223 
224  app_.overlay().broadcast(prop);
225 }
226 
227 void
229 {
230  inboundTransactions_.giveSet(txns.id(), txns.map_, false);
231 }
232 
233 boost::optional<RCLTxSet>
235 {
236  if (auto txns = inboundTransactions_.getSet(setId, true))
237  {
238  return RCLTxSet{std::move(txns)};
239  }
240  return boost::none;
241 }
242 
243 bool
245 {
246  return !app_.openLedger().empty();
247 }
248 
251 {
252  return app_.getValidations().numTrustedForLedger(h);
253 }
254 
257  RCLCxLedger const& ledger,
258  LedgerHash const& h) const
259 {
260  RCLValidations& vals = app_.getValidations();
261  return vals.getNodesAfter(
262  RCLValidatedLedger(ledger.ledger_, vals.adaptor().journal()), h);
263 }
264 
265 uint256
267  uint256 ledgerID,
268  RCLCxLedger const& ledger,
270 {
271  RCLValidations& vals = app_.getValidations();
272  uint256 netLgr = vals.getPreferred(
273  RCLValidatedLedger{ledger.ledger_, vals.adaptor().journal()},
274  ledgerMaster_.getValidLedgerIndex());
275 
276  if (netLgr != ledgerID)
277  {
279  app_.getOPs().consensusViewChange();
280 
281  JLOG(j_.debug()) << Json::Compact(app_.getValidations().getJsonTrie());
282  }
283 
284  return netLgr;
285 }
286 
287 auto
289  RCLCxLedger const& ledger,
290  NetClock::time_point const& closeTime,
292 {
293  const bool wrongLCL = mode == ConsensusMode::wrongLedger;
294  const bool proposing = mode == ConsensusMode::proposing;
295 
296  notify(protocol::neCLOSING_LEDGER, ledger, !wrongLCL);
297 
298  auto const& prevLedger = ledger.ledger_;
299 
300  ledgerMaster_.applyHeldTransactions();
301  // Tell the ledger master not to acquire the ledger we're probably building
302  ledgerMaster_.setBuildingLedger(prevLedger->info().seq + 1);
303 
304  auto initialLedger = app_.openLedger().current();
305 
306  auto initialSet =
307  std::make_shared<SHAMap>(SHAMapType::TRANSACTION, app_.getNodeFamily());
308  initialSet->setUnbacked();
309 
310  // Build SHAMap containing all transactions in our open ledger
311  for (auto const& tx : initialLedger->txs)
312  {
313  JLOG(j_.trace()) << "Adding open ledger TX "
314  << tx.first->getTransactionID();
315  Serializer s(2048);
316  tx.first->add(s);
317  initialSet->addItem(
319  SHAMapItem(tx.first->getTransactionID(), std::move(s)));
320  }
321 
322  // Add pseudo-transactions to the set
323  if (app_.config().standalone() || (proposing && !wrongLCL))
324  {
325  if (prevLedger->isFlagLedger())
326  {
327  // previous ledger was flag ledger, add fee and amendment
328  // pseudo-transactions
329  auto validations = app_.validators().negativeUNLFilter(
330  app_.getValidations().getTrustedForLedger(
331  prevLedger->info().parentHash));
332  if (validations.size() >= app_.validators().quorum())
333  {
334  feeVote_->doVoting(prevLedger, validations, initialSet);
335  app_.getAmendmentTable().doVoting(
336  prevLedger, validations, initialSet);
337  }
338  }
339  else if (
340  prevLedger->isVotingLedger() &&
341  prevLedger->rules().enabled(featureNegativeUNL))
342  {
343  // previous ledger was a voting ledger,
344  // so the current consensus session is for a flag ledger,
345  // add negative UNL pseudo-transactions
346  nUnlVote_.doVoting(
347  prevLedger,
348  app_.validators().getTrustedMasterKeys(),
349  app_.getValidations(),
350  initialSet);
351  }
352  }
353 
354  // Now we need an immutable snapshot
355  initialSet = initialSet->snapShot(false);
356 
357  if (!wrongLCL)
358  {
359  LedgerIndex const seq = prevLedger->info().seq + 1;
361 
362  initialSet->visitLeaves(
363  [&proposed, seq](std::shared_ptr<SHAMapItem const> const& item) {
364  proposed.emplace_back(item->key(), seq);
365  });
366 
367  censorshipDetector_.propose(std::move(proposed));
368  }
369 
370  // Needed because of the move below.
371  auto const setHash = initialSet->getHash().as_uint256();
372 
373  return Result{
374  std::move(initialSet),
376  initialLedger->info().parentHash,
378  setHash,
379  closeTime,
380  app_.timeKeeper().closeTime(),
381  nodeID_}};
382 }
383 
384 void
386  Result const& result,
387  RCLCxLedger const& prevLedger,
388  NetClock::duration const& closeResolution,
389  ConsensusCloseTimes const& rawCloseTimes,
390  ConsensusMode const& mode,
391  Json::Value&& consensusJson)
392 {
393  doAccept(
394  result,
395  prevLedger,
396  closeResolution,
397  rawCloseTimes,
398  mode,
399  std::move(consensusJson));
400 }
401 
402 void
404  Result const& result,
405  RCLCxLedger const& prevLedger,
406  NetClock::duration const& closeResolution,
407  ConsensusCloseTimes const& rawCloseTimes,
408  ConsensusMode const& mode,
409  Json::Value&& consensusJson)
410 {
411  app_.getJobQueue().addJob(
412  jtACCEPT,
413  "acceptLedger",
414  [=, cj = std::move(consensusJson)](auto&) mutable {
415  // Note that no lock is held or acquired during this job.
416  // This is because generic Consensus guarantees that once a ledger
417  // is accepted, the consensus results and capture by reference state
418  // will not change until startRound is called (which happens via
419  // endConsensus).
420  this->doAccept(
421  result,
422  prevLedger,
423  closeResolution,
424  rawCloseTimes,
425  mode,
426  std::move(cj));
427  this->app_.getOPs().endConsensus();
428  });
429 }
430 
431 void
433  Result const& result,
434  RCLCxLedger const& prevLedger,
435  NetClock::duration closeResolution,
436  ConsensusCloseTimes const& rawCloseTimes,
437  ConsensusMode const& mode,
438  Json::Value&& consensusJson)
439 {
440  prevProposers_ = result.proposers;
441  prevRoundTime_ = result.roundTime.read();
442 
443  bool closeTimeCorrect;
444 
445  const bool proposing = mode == ConsensusMode::proposing;
446  const bool haveCorrectLCL = mode != ConsensusMode::wrongLedger;
447  const bool consensusFail = result.state == ConsensusState::MovedOn;
448 
449  auto consensusCloseTime = result.position.closeTime();
450 
451  if (consensusCloseTime == NetClock::time_point{})
452  {
453  // We agreed to disagree on the close time
454  using namespace std::chrono_literals;
455  consensusCloseTime = prevLedger.closeTime() + 1s;
456  closeTimeCorrect = false;
457  }
458  else
459  {
460  // We agreed on a close time
461  consensusCloseTime = effCloseTime(
462  consensusCloseTime, closeResolution, prevLedger.closeTime());
463  closeTimeCorrect = true;
464  }
465 
466  JLOG(j_.debug()) << "Report: Prop=" << (proposing ? "yes" : "no")
467  << " val=" << (validating_ ? "yes" : "no")
468  << " corLCL=" << (haveCorrectLCL ? "yes" : "no")
469  << " fail=" << (consensusFail ? "yes" : "no");
470  JLOG(j_.debug()) << "Report: Prev = " << prevLedger.id() << ":"
471  << prevLedger.seq();
472 
473  //--------------------------------------------------------------------------
474  std::set<TxID> failed;
475 
476  // We want to put transactions in an unpredictable but deterministic order:
477  // we use the hash of the set.
478  //
479  // FIXME: Use a std::vector and a custom sorter instead of CanonicalTXSet?
480  CanonicalTXSet retriableTxs{result.txns.map_->getHash().as_uint256()};
481 
482  JLOG(j_.debug()) << "Building canonical tx set: " << retriableTxs.key();
483 
484  for (auto const& item : *result.txns.map_)
485  {
486  try
487  {
488  retriableTxs.insert(
489  std::make_shared<STTx const>(SerialIter{item.slice()}));
490  JLOG(j_.debug()) << " Tx: " << item.key();
491  }
492  catch (std::exception const&)
493  {
494  failed.insert(item.key());
495  JLOG(j_.warn()) << " Tx: " << item.key() << " throws!";
496  }
497  }
498 
499  auto built = buildLCL(
500  prevLedger,
501  retriableTxs,
502  consensusCloseTime,
503  closeTimeCorrect,
504  closeResolution,
505  result.roundTime.read(),
506  failed);
507 
508  auto const newLCLHash = built.id();
509  JLOG(j_.debug()) << "Built ledger #" << built.seq() << ": " << newLCLHash;
510 
511  // Tell directly connected peers that we have a new LCL
512  notify(protocol::neACCEPTED_LEDGER, built, haveCorrectLCL);
513 
514  // As long as we're in sync with the network, attempt to detect attempts
515  // at censorship of transaction by tracking which ones don't make it in
516  // after a period of time.
517  if (haveCorrectLCL && result.state == ConsensusState::Yes)
518  {
520 
521  result.txns.map_->visitLeaves(
523  accepted.push_back(item->key());
524  });
525 
526  // Track all the transactions which failed or were marked as retriable
527  for (auto const& r : retriableTxs)
528  failed.insert(r.first.getTXID());
529 
530  censorshipDetector_.check(
531  std::move(accepted),
532  [curr = built.seq(),
533  j = app_.journal("CensorshipDetector"),
534  &failed](uint256 const& id, LedgerIndex seq) {
535  if (failed.count(id))
536  return true;
537 
538  auto const wait = curr - seq;
539 
540  if (wait && (wait % censorshipWarnInternal == 0))
541  {
542  std::ostringstream ss;
543  ss << "Potential Censorship: Eligible tx " << id
544  << ", which we are tracking since ledger " << seq
545  << " has not been included as of ledger " << curr << ".";
546 
547  JLOG(j.warn()) << ss.str();
548  }
549 
550  return false;
551  });
552  }
553 
554  if (validating_)
555  validating_ = ledgerMaster_.isCompatible(
556  *built.ledger_, j_.warn(), "Not validating");
557 
558  if (validating_ && !consensusFail &&
559  app_.getValidations().canValidateSeq(built.seq()))
560  {
561  validate(built, result.txns, proposing);
562  JLOG(j_.info()) << "CNF Val " << newLCLHash;
563  }
564  else
565  JLOG(j_.info()) << "CNF buildLCL " << newLCLHash;
566 
567  // See if we can accept a ledger as fully-validated
568  ledgerMaster_.consensusBuilt(
569  built.ledger_, result.txns.id(), std::move(consensusJson));
570 
571  //-------------------------------------------------------------------------
572  {
573  // Apply disputed transactions that didn't get in
574  //
575  // The first crack of transactions to get into the new
576  // open ledger goes to transactions proposed by a validator
577  // we trust but not included in the consensus set.
578  //
579  // These are done first because they are the most likely
580  // to receive agreement during consensus. They are also
581  // ordered logically "sooner" than transactions not mentioned
582  // in the previous consensus round.
583  //
584  bool anyDisputes = false;
585  for (auto const& [_, dispute] : result.disputes)
586  {
587  (void)_;
588  if (!dispute.getOurVote())
589  {
590  // we voted NO
591  try
592  {
593  JLOG(j_.debug())
594  << "Test applying disputed transaction that did"
595  << " not get in " << dispute.tx().id();
596 
597  SerialIter sit(dispute.tx().tx_.slice());
598  auto txn = std::make_shared<STTx const>(sit);
599 
600  // Disputed pseudo-transactions that were not accepted
601  // can't be successfully applied in the next ledger
602  if (isPseudoTx(*txn))
603  continue;
604 
605  retriableTxs.insert(txn);
606 
607  anyDisputes = true;
608  }
609  catch (std::exception const&)
610  {
611  JLOG(j_.debug())
612  << "Failed to apply transaction we voted NO on";
613  }
614  }
615  }
616 
617  // Build new open ledger
618  std::unique_lock lock{app_.getMasterMutex(), std::defer_lock};
619  std::unique_lock sl{ledgerMaster_.peekMutex(), std::defer_lock};
620  std::lock(lock, sl);
621 
622  auto const lastVal = ledgerMaster_.getValidatedLedger();
623  boost::optional<Rules> rules;
624  if (lastVal)
625  rules.emplace(*lastVal, app_.config().features);
626  else
627  rules.emplace(app_.config().features);
628  app_.openLedger().accept(
629  app_,
630  *rules,
631  built.ledger_,
632  localTxs_.getTxSet(),
633  anyDisputes,
634  retriableTxs,
635  tapNONE,
636  "consensus",
637  [&](OpenView& view, beast::Journal j) {
638  // Stuff the ledger with transactions from the queue.
639  return app_.getTxQ().accept(app_, view);
640  });
641 
642  // Signal a potential fee change to subscribers after the open ledger
643  // is created
644  app_.getOPs().reportFeeChange();
645  }
646 
647  //-------------------------------------------------------------------------
648  {
649  ledgerMaster_.switchLCL(built.ledger_);
650 
651  // Do these need to exist?
652  assert(ledgerMaster_.getClosedLedger()->info().hash == built.id());
653  assert(app_.openLedger().current()->info().parentHash == built.id());
654  }
655 
656  //-------------------------------------------------------------------------
657  // we entered the round with the network,
658  // see how close our close time is to other node's
659  // close time reports, and update our clock.
660  if ((mode == ConsensusMode::proposing ||
662  !consensusFail)
663  {
664  auto closeTime = rawCloseTimes.self;
665 
666  JLOG(j_.info()) << "We closed at "
667  << closeTime.time_since_epoch().count();
668  using usec64_t = std::chrono::duration<std::uint64_t>;
669  usec64_t closeTotal =
670  std::chrono::duration_cast<usec64_t>(closeTime.time_since_epoch());
671  int closeCount = 1;
672 
673  for (auto const& [t, v] : rawCloseTimes.peers)
674  {
675  JLOG(j_.info()) << std::to_string(v) << " time votes for "
676  << std::to_string(t.time_since_epoch().count());
677  closeCount += v;
678  closeTotal +=
679  std::chrono::duration_cast<usec64_t>(t.time_since_epoch()) * v;
680  }
681 
682  closeTotal += usec64_t(closeCount / 2); // for round to nearest
683  closeTotal /= closeCount;
684 
685  // Use signed times since we are subtracting
686  using duration = std::chrono::duration<std::int32_t>;
688  auto offset = time_point{closeTotal} -
689  std::chrono::time_point_cast<duration>(closeTime);
690  JLOG(j_.info()) << "Our close offset is estimated at " << offset.count()
691  << " (" << closeCount << ")";
692 
693  app_.timeKeeper().adjustCloseTime(offset);
694  }
695 }
696 
697 void
699  protocol::NodeEvent ne,
700  RCLCxLedger const& ledger,
701  bool haveCorrectLCL)
702 {
703  protocol::TMStatusChange s;
704 
705  if (!haveCorrectLCL)
706  s.set_newevent(protocol::neLOST_SYNC);
707  else
708  s.set_newevent(ne);
709 
710  s.set_ledgerseq(ledger.seq());
711  s.set_networktime(app_.timeKeeper().now().time_since_epoch().count());
712  s.set_ledgerhashprevious(
713  ledger.parentID().begin(),
714  std::decay_t<decltype(ledger.parentID())>::bytes);
715  s.set_ledgerhash(
716  ledger.id().begin(), std::decay_t<decltype(ledger.id())>::bytes);
717 
718  std::uint32_t uMin, uMax;
719  if (!ledgerMaster_.getFullValidatedRange(uMin, uMax))
720  {
721  uMin = 0;
722  uMax = 0;
723  }
724  else
725  {
726  // Don't advertise ledgers we're not willing to serve
727  uMin = std::max(uMin, ledgerMaster_.getEarliestFetch());
728  }
729  s.set_firstseq(uMin);
730  s.set_lastseq(uMax);
731  app_.overlay().foreach(
732  send_always(std::make_shared<Message>(s, protocol::mtSTATUS_CHANGE)));
733  JLOG(j_.trace()) << "send status change to peer";
734 }
735 
738  RCLCxLedger const& previousLedger,
739  CanonicalTXSet& retriableTxs,
740  NetClock::time_point closeTime,
741  bool closeTimeCorrect,
742  NetClock::duration closeResolution,
743  std::chrono::milliseconds roundTime,
744  std::set<TxID>& failedTxs)
745 {
746  std::shared_ptr<Ledger> built = [&]() {
747  if (auto const replayData = ledgerMaster_.releaseReplay())
748  {
749  assert(replayData->parent()->info().hash == previousLedger.id());
750  return buildLedger(*replayData, tapNONE, app_, j_);
751  }
752  return buildLedger(
753  previousLedger.ledger_,
754  closeTime,
755  closeTimeCorrect,
756  closeResolution,
757  app_,
758  retriableTxs,
759  failedTxs,
760  j_);
761  }();
762 
763  // Update fee computations based on accepted txs
764  using namespace std::chrono_literals;
765  app_.getTxQ().processClosedLedger(app_, *built, roundTime > 5s);
766 
767  // And stash the ledger in the ledger master
768  if (ledgerMaster_.storeLedger(built))
769  JLOG(j_.debug()) << "Consensus built ledger we already had";
770  else if (app_.getInboundLedgers().find(built->info().hash))
771  JLOG(j_.debug()) << "Consensus built ledger we were acquiring";
772  else
773  JLOG(j_.debug()) << "Consensus built new ledger";
774  return RCLCxLedger{std::move(built)};
775 }
776 
777 void
779  RCLCxLedger const& ledger,
780  RCLTxSet const& txns,
781  bool proposing)
782 {
783  using namespace std::chrono_literals;
784 
785  auto validationTime = app_.timeKeeper().closeTime();
786  if (validationTime <= lastValidationTime_)
787  validationTime = lastValidationTime_ + 1s;
788  lastValidationTime_ = validationTime;
789 
790  auto v = std::make_shared<STValidation>(
791  lastValidationTime_,
792  valPublic_,
793  valSecret_,
794  nodeID_,
795  [&](STValidation& v) {
796  v.setFieldH256(sfLedgerHash, ledger.id());
797  v.setFieldH256(sfConsensusHash, txns.id());
798 
799  v.setFieldU32(sfLedgerSequence, ledger.seq());
800 
801  if (proposing)
803 
804  if (ledger.ledger_->rules().enabled(featureHardenedValidations))
805  {
806  // Attest to the hash of what we consider to be the last fully
807  // validated ledger. This may be the hash of the ledger we are
808  // validating here, and that's fine.
809  if (auto const vl = ledgerMaster_.getValidatedLedger())
810  v.setFieldH256(sfValidatedHash, vl->info().hash);
811 
812  v.setFieldU64(sfCookie, valCookie_);
813 
814  // Report our server version every flag ledger:
815  if (ledger.ledger_->isVotingLedger())
816  v.setFieldU64(
817  sfServerVersion, BuildInfo::getEncodedVersion());
818  }
819 
820  // Report our load
821  {
822  auto const& ft = app_.getFeeTrack();
823  auto const fee = std::max(ft.getLocalFee(), ft.getClusterFee());
824  if (fee > ft.getLoadBase())
825  v.setFieldU32(sfLoadFee, fee);
826  }
827 
828  // If the next ledger is a flag ledger, suggest fee changes and
829  // new features:
830  if (ledger.ledger_->isVotingLedger())
831  {
832  // Fees:
833  feeVote_->doValidation(ledger.ledger_->fees(), v);
834 
835  // Amendments
836  // FIXME: pass `v` and have the function insert the array
837  // directly?
838  auto const amendments = app_.getAmendmentTable().doValidation(
839  getEnabledAmendments(*ledger.ledger_));
840 
841  if (!amendments.empty())
842  v.setFieldV256(
843  sfAmendments, STVector256(sfAmendments, amendments));
844  }
845  });
846 
847  // suppress it if we receive it
848  app_.getHashRouter().addSuppression(
850 
851  handleNewValidation(app_, v, "local");
852 
853  // Broadcast to all our peers:
855  protocol::TMValidation val;
856  val.set_validation(&validation[0], validation.size());
857  app_.overlay().broadcast(val);
858 
859  // Publish to all our subscribers:
860  app_.getOPs().pubValidation(v);
861 }
862 
863 void
865 {
866  JLOG(j_.info()) << "Consensus mode change before=" << to_string(before)
867  << ", after=" << to_string(after);
868 
869  // If we were proposing but aren't any longer, we need to reset the
870  // censorship tracking to avoid bogus warnings.
871  if ((before == ConsensusMode::proposing ||
872  before == ConsensusMode::observing) &&
873  before != after)
874  censorshipDetector_.reset();
875 
876  mode_ = after;
877 }
878 
880 RCLConsensus::getJson(bool full) const
881 {
882  Json::Value ret;
883  {
885  ret = consensus_.getJson(full);
886  }
887  ret["validating"] = adaptor_.validating();
888  return ret;
889 }
890 
891 void
893 {
894  try
895  {
897  consensus_.timerEntry(now);
898  }
899  catch (SHAMapMissingNode const& mn)
900  {
901  // This should never happen
902  JLOG(j_.error()) << "During consensus timerEntry: " << mn.what();
903  Rethrow();
904  }
905 }
906 
907 void
909 {
910  try
911  {
913  consensus_.gotTxSet(now, txSet);
914  }
915  catch (SHAMapMissingNode const& mn)
916  {
917  // This should never happen
918  JLOG(j_.error()) << "During consensus gotTxSet: " << mn.what();
919  Rethrow();
920  }
921 }
922 
924 
925 void
927  NetClock::time_point const& now,
928  boost::optional<std::chrono::milliseconds> consensusDelay)
929 {
931  consensus_.simulate(now, consensusDelay);
932 }
933 
934 bool
936  NetClock::time_point const& now,
937  RCLCxPeerPos const& newProposal)
938 {
940  return consensus_.peerProposal(now, newProposal);
941 }
942 
943 bool
945  RCLCxLedger const& prevLgr,
946  hash_set<NodeID> const& nowTrusted)
947 {
948  // We have a key, we do not want out of sync validations after a restart
949  // and are not amendment blocked.
950  validating_ = valPublic_.size() != 0 &&
951  prevLgr.seq() >= app_.getMaxDisallowedLedger() &&
952  !app_.getOPs().isAmendmentBlocked();
953 
954  // If we are not running in standalone mode and there's a configured UNL,
955  // check to make sure that it's not expired.
956  if (validating_ && !app_.config().standalone() && app_.validators().count())
957  {
958  auto const when = app_.validators().expires();
959 
960  if (!when || *when < app_.timeKeeper().now())
961  {
962  JLOG(j_.error()) << "Voluntarily bowing out of consensus process "
963  "because of an expired validator list.";
964  validating_ = false;
965  }
966  }
967 
968  const bool synced = app_.getOPs().getOperatingMode() == OperatingMode::FULL;
969 
970  if (validating_)
971  {
972  JLOG(j_.info()) << "Entering consensus process, validating, synced="
973  << (synced ? "yes" : "no");
974  }
975  else
976  {
977  // Otherwise we just want to monitor the validation process.
978  JLOG(j_.info()) << "Entering consensus process, watching, synced="
979  << (synced ? "yes" : "no");
980  }
981 
982  // Notify inbound ledgers that we are starting a new round
983  inboundTransactions_.newRound(prevLgr.seq());
984 
985  // Notify NegativeUNLVote that new validators are added
986  if (prevLgr.ledger_->rules().enabled(featureNegativeUNL) &&
987  !nowTrusted.empty())
988  nUnlVote_.newValidators(prevLgr.seq() + 1, nowTrusted);
989 
990  // propose only if we're in sync with the network (and validating)
991  return validating_ && synced;
992 }
993 
994 bool
996 {
997  return ledgerMaster_.haveValidated();
998 }
999 
1002 {
1003  return ledgerMaster_.getValidLedgerIndex();
1004 }
1005 
1008 {
1009  return app_.validators().getQuorumKeys();
1010 }
1011 
1014  Ledger_t::Seq const seq,
1015  hash_set<RCLConsensus::Adaptor::NodeKey_t>& trustedKeys) const
1016 {
1017  return app_.getValidations().laggards(seq, trustedKeys);
1018 }
1019 
1020 bool
1022 {
1023  return !valPublic_.empty();
1024 }
1025 
1026 void
1028 {
1029  if (!positions && app_.getOPs().isFull())
1030  app_.getOPs().setMode(OperatingMode::CONNECTED);
1031 }
1032 
1033 void
1035  NetClock::time_point const& now,
1036  RCLCxLedger::ID const& prevLgrId,
1037  RCLCxLedger const& prevLgr,
1038  hash_set<NodeID> const& nowUntrusted,
1039  hash_set<NodeID> const& nowTrusted)
1040 {
1042  consensus_.startRound(
1043  now,
1044  prevLgrId,
1045  prevLgr,
1046  nowUntrusted,
1047  adaptor_.preStartRound(prevLgr, nowTrusted));
1048 }
1049 } // namespace ripple
ripple::Application
Definition: Application.h:97
ripple::RCLCxPeerPos
A peer's signed, proposed position for use in RCLConsensus.
Definition: RCLCxPeerPos.h:42
ripple::HashPrefix::ledgerMaster
@ ledgerMaster
ledger master data for signing
std::lock
T lock(T... args)
ripple::makeSlice
std::enable_if_t< std::is_same< T, char >::value||std::is_same< T, unsigned char >::value, Slice > makeSlice(std::array< T, N > const &a)
Definition: Slice.h:240
std::string
STL class.
ripple::InboundLedger::Reason::CONSENSUS
@ CONSENSUS
ripple::RCLCxPeerPos::signature
Slice signature() const
Signature of the proposal (not necessarily verified)
Definition: RCLCxPeerPos.h:74
std::shared_ptr
STL class.
ripple::ConsensusMode::proposing
@ proposing
We are normal participant in consensus and propose our position.
ripple::RCLConsensus::getJson
Json::Value getJson(bool full) const
Definition: RCLConsensus.cpp:880
std::exception
STL class.
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:1034
beast::Journal::trace
Stream trace() const
Severity stream access functions.
Definition: Journal.h:309
ripple::RCLConsensus::consensus_
Consensus< Adaptor > consensus_
Definition: RCLConsensus.h:531
ripple::sfLedgerSequence
const SF_UINT32 sfLedgerSequence
ripple::jtACCEPT
@ jtACCEPT
Definition: Job.h:59
std::unordered_set
STL class.
std::pair
ripple::SHAMapType::TRANSACTION
@ TRANSACTION
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:944
ripple::RCLConsensus::mutex_
std::recursive_mutex mutex_
Definition: RCLConsensus.h:528
ripple::LedgerMaster
Definition: LedgerMaster.h:54
ripple::ConsensusMode::wrongLedger
@ wrongLedger
We have the wrong ledger and are attempting to acquire it.
Json::Compact
Decorator for streaming out compact json.
Definition: json_writer.h:316
ripple::RCLConsensus::Adaptor::hasOpenTransactions
bool hasOpenTransactions() const
Whether the open ledger has any transactions.
Definition: RCLConsensus.cpp:244
std::vector< TxIDSeq >
ripple::ConsensusState::Yes
@ Yes
We have consensus along with the network.
ripple::RCLConsensus::gotTxSet
void gotTxSet(NetClock::time_point const &now, RCLTxSet const &txSet)
Definition: RCLConsensus.cpp:908
std::chrono::duration
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:266
ripple::RCLTxSet::map_
std::shared_ptr< SHAMap > map_
The SHAMap representing the transactions.
Definition: RCLCxTx.h:190
beast::Journal::warn
Stream warn() const
Definition: Journal.h:327
std::lock_guard
STL class.
ripple::RCLConsensus::j_
const beast::Journal j_
Definition: RCLConsensus.h:532
ripple::PublicKey::slice
Slice slice() const noexcept
Definition: PublicKey.h:123
ripple::ConsensusResult::roundTime
ConsensusTimer roundTime
Definition: ConsensusTypes.h:233
ripple::RCLConsensus::timerEntry
void timerEntry(NetClock::time_point const &now)
Definition: RCLConsensus.cpp:892
ripple::RCLValidationsAdaptor::journal
beast::Journal journal() const
Definition: RCLValidations.h:225
ripple::to_string
std::string to_string(ListDisposition disposition)
Definition: ValidatorList.cpp:42
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:288
ripple::RCLCxLedger::closeTime
NetClock::time_point closeTime() const
The close time of this ledger.
Definition: RCLCxLedger.h:96
ripple::tapNONE
@ tapNONE
Definition: ApplyView.h:31
ripple::RCLValidatedLedger
Wraps a ledger instance for use in generic Validations LedgerTrie.
Definition: RCLValidations.h:153
ripple::ConsensusResult
Encapsulates the result of consensus.
Definition: ConsensusTypes.h:201
algorithm
ripple::SHAMapNodeType::tnTRANSACTION_NM
@ tnTRANSACTION_NM
ripple::ValidatorKeys
Validator keys and manifest as set in configuration file.
Definition: ValidatorKeys.h:36
ripple::RCLCxLedger::seq
Seq const & seq() const
Sequence number of the ledger.
Definition: RCLCxLedger.h:61
ripple::STValidation
Definition: STValidation.h:43
ripple::RCLCxLedger::parentID
ID const & parentID() const
Unique identifier (hash) of this ledger's parent.
Definition: RCLCxLedger.h:75
ripple::CanonicalTXSet
Holds transactions which were deferred to the next pass of consensus.
Definition: CanonicalTXSet.h:37
ripple::send_always
Sends a message to all peers.
Definition: predicates.h:31
ripple::RCLCxPeerPos::proposal
Proposal const & proposal() const
Definition: RCLCxPeerPos.h:94
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:432
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::SHAMapMissingNode
Definition: SHAMapMissingNode.h:55
ripple::sfLedgerHash
const SF_HASH256 sfLedgerHash
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:403
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:1027
ripple::isPseudoTx
bool isPseudoTx(STObject const &tx)
Check whether a transaction is a pseudo-transaction.
Definition: STTx.cpp:540
ripple::RCLConsensus::Adaptor::haveValidated
bool haveValidated() const
Definition: RCLConsensus.cpp:995
ripple::Validations::getPreferred
boost::optional< std::pair< Seq, ID > > getPreferred(Ledger const &curr)
Return the sequence number and ID of the preferred working ledger.
Definition: Validations.h:802
ripple::RCLConsensus::Adaptor::laggards
std::size_t laggards(Ledger_t::Seq const seq, hash_set< NodeKey_t > &trustedKeys) const
Definition: RCLConsensus.cpp:1013
ripple::RCLConsensus::Adaptor::share
void share(RCLCxPeerPos const &peerPos)
Share the given proposal with all peers.
Definition: RCLConsensus.cpp:140
ripple::OperatingMode::CONNECTED
@ CONNECTED
convinced we are talking to the network
ripple::ConsensusResult::state
ConsensusState state
Definition: ConsensusTypes.h:237
ripple::ConsensusTimer::read
std::chrono::milliseconds read() const
Definition: ConsensusTypes.h:142
ripple::SHAMapItem
Definition: SHAMapItem.h:35
ripple::signDigest
Buffer signDigest(PublicKey const &pk, SecretKey const &sk, uint256 const &digest)
Generate a signature for a message digest.
Definition: SecretKey.cpp:98
ripple::RCLConsensus::peerProposal
bool peerProposal(NetClock::time_point const &now, RCLCxPeerPos const &newProposal)
Definition: RCLConsensus.cpp:935
ripple::Rethrow
void Rethrow()
Rethrow the exception currently being handled.
Definition: contract.h:48
ripple::STObject::setFieldH256
void setFieldH256(SField const &field, uint256 const &)
Definition: STObject.cpp:650
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:778
ripple::Validations::getNodesAfter
std::size_t getNodesAfter(Ledger const &ledger, ID const &ledgerID)
Count the number of current trusted validators working on a ledger after the specified one.
Definition: Validations.h:926
ripple::STValidation::getSerialized
Blob getSerialized() const
Definition: STValidation.cpp:126
std::unique_lock
STL class.
ripple::RCLTxSet::id
ID id() const
The unique ID/hash of the transaction set.
Definition: RCLCxTx.h:157
std::to_string
T to_string(T... args)
ripple::RCLCxTx::tx_
const SHAMapItem tx_
The SHAMapItem that represents the transaction.
Definition: RCLCxTx.h:57
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:75
beast::Journal::error
Stream error() const
Definition: Journal.h:333
beast::Journal::info
Stream info() const
Definition: Journal.h:321
std::chrono::time_point
ripple::HashPrefix::proposal
@ proposal
proposal for signing
ripple::RCLCxLedger::id
ID const & id() const
Unique identifier (hash) of this ledger.
Definition: RCLCxLedger.h:68
ripple::RCLConsensus::mode
ConsensusMode mode() const
Definition: RCLConsensus.h:464
ripple::LocalTxs
Definition: LocalTxs.h:33
ripple::Job
Definition: Job.h:82
ripple::SerialIter
Definition: Serializer.h:308
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
ripple::HashPrefix::validation
@ validation
validation for signing
ripple::RCLConsensus::Adaptor::acquireLedger
boost::optional< RCLCxLedger > acquireLedger(LedgerHash const &hash)
Attempt to acquire a specific ledger.
Definition: RCLConsensus.cpp:105
std::uint32_t
ripple::RCLConsensus::Adaptor::notify
void notify(protocol::NodeEvent ne, RCLCxLedger const &ledger, bool haveCorrectLCL)
Notify peers of a consensus state change.
Definition: RCLConsensus.cpp:698
ripple::ConsensusState::MovedOn
@ MovedOn
The network has consensus without us.
ripple::RCLConsensus::adaptor_
Adaptor adaptor_
Definition: RCLConsensus.h:530
ripple::SHAMapItem::slice
Slice slice() const
Definition: SHAMapItem.h:64
ripple::RCLConsensus::Adaptor::validator
bool validator() const
Whether I am a validator.
Definition: RCLConsensus.cpp:1021
beast::abstract_clock< std::chrono::steady_clock >
ripple::proposalUniqueId
uint256 proposalUniqueId(uint256 const &proposeHash, uint256 const &previousLedger, std::uint32_t proposeSeq, NetClock::time_point closeTime, Slice const &publicKey, Slice const &signature)
Calculate a unique identifier for a signed proposal.
Definition: RCLCxPeerPos.cpp:72
ripple::featureHardenedValidations
const uint256 featureHardenedValidations
Definition: Feature.cpp:186
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:737
ripple::RCLCxPeerPos::publicKey
PublicKey const & publicKey() const
Public key of peer that sent the proposal.
Definition: RCLCxPeerPos.h:81
std::decay_t
ripple::RCLConsensus::Adaptor::onModeChange
void onModeChange(ConsensusMode before, ConsensusMode after)
Notified of change in consensus mode.
Definition: RCLConsensus.cpp:864
ripple::ManifestDisposition::accepted
@ accepted
Manifest is valid.
ripple::Serializer
Definition: Serializer.h:39
ripple::RCLCxLedger
Represents a ledger in RCLConsensus.
Definition: RCLCxLedger.h:35
ripple::ConsensusProposal::closeTime
NetClock::time_point const & closeTime() const
The current position on the consensus close time.
Definition: ConsensusProposal.h:124
std::vector::emplace_back
T emplace_back(T... args)
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
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:1001
ripple::sfConsensusHash
const SF_HASH256 sfConsensusHash
ripple::base_uint::begin
iterator begin()
Definition: base_uint.h:124
ripple::RCLConsensus::Adaptor::acquireTxSet
boost::optional< RCLTxSet > acquireTxSet(RCLTxSet::ID const &setId)
Acquire the transaction set associated with a proposal.
Definition: RCLConsensus.cpp:234
std
STL namespace.
ripple::featureNegativeUNL
const uint256 featureNegativeUNL
Definition: Feature.cpp:188
std::set::insert
T insert(T... args)
ripple::sha512Half
sha512_half_hasher::result_type sha512Half(Args const &... args)
Returns the SHA512-Half of a series of objects.
Definition: digest.h:216
ripple::ConsensusResult::position
Proposal_t position
Our proposed position on transactions/close time.
Definition: ConsensusTypes.h:224
ripple::ConsensusProposal< NodeID, uint256, uint256 >::seqJoin
static const std::uint32_t seqJoin
Definition: ConsensusProposal.h:58
ripple::buildLedger
std::shared_ptr< Ledger > buildLedger(std::shared_ptr< Ledger const > const &parent, NetClock::time_point closeTime, const bool closeTimeCorrect, NetClock::duration closeResolution, Application &app, CanonicalTXSet &txns, std::set< TxID > &failedTxs, beast::Journal j)
Build a new ledger by applying consensus transactions.
Definition: BuildLedger.cpp:175
ripple::STObject::setFlag
bool setFlag(std::uint32_t)
Definition: STObject.cpp:424
std::unordered_set::empty
T empty(T... args)
ripple::RCLConsensus::Adaptor::proposersValidated
std::size_t proposersValidated(LedgerHash const &h) const
Number of proposers that have validated the given ledger.
Definition: RCLConsensus.cpp:250
ripple::Validations< RCLValidationsAdaptor >
ripple::RCLCxPeerPos::suppressionID
uint256 const & suppressionID() const
Unique id used by hash router to suppress duplicates.
Definition: RCLCxPeerPos.h:88
mutex
ripple::ConsensusResult::txns
TxSet_t txns
The set of transactions consensus agrees go in the ledger.
Definition: ConsensusTypes.h:221
beast::Journal::debug
Stream debug() const
Definition: Journal.h:315
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::vfFullValidation
constexpr std::uint32_t vfFullValidation
Definition: STValidation.h:38
ripple::RCLCxLedger::ledger_
std::shared_ptr< Ledger const > ledger_
The ledger instance.
Definition: RCLCxLedger.h:120
ripple::jtADVANCE
@ jtADVANCE
Definition: Job.h:53
std::max
T max(T... args)
ripple::RCLCxTx
Represents a transaction in RCLConsensus.
Definition: RCLCxTx.h:35
ripple::Validations::adaptor
Adaptor const & adaptor() const
Return the adaptor instance.
Definition: Validations.h:578
ripple::RCLCxTx::id
ID const & id() const
The unique identifier/hash of the transaction.
Definition: RCLCxTx.h:51
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:185
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:256
std::numeric_limits
ripple::STObject::setFieldU32
void setFieldU32(SField const &field, std::uint32_t)
Definition: STObject.cpp:632
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:385
std::set
STL class.
ripple::RCLConsensus::Adaptor::getQuorumKeys
std::pair< std::size_t, hash_set< NodeKey_t > > getQuorumKeys() const
Definition: RCLConsensus.cpp:1007
ripple::handleNewValidation
void handleNewValidation(Application &app, std::shared_ptr< STValidation > const &val, std::string const &source)
Handle a new validation.
Definition: RCLValidations.cpp:152
ripple::RCLConsensus::Adaptor::validating
bool validating() const
Definition: RCLConsensus.h:110
std::runtime_error::what
T what(T... args)
ripple::effCloseTime
std::chrono::time_point< Clock, Duration > effCloseTime(std::chrono::time_point< Clock, Duration > closeTime, std::chrono::duration< Rep, Period > resolution, std::chrono::time_point< Clock, Duration > priorCloseTime)
Calculate the effective ledger close time.
Definition: LedgerTiming.h:152
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::ConsensusResult::proposers
std::size_t proposers
Definition: ConsensusTypes.h:240
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:926
ripple::ConsensusProposal< NodeID, uint256, uint256 >
ripple::OperatingMode::FULL
@ FULL
we have the ledger and can even validate