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());
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(
318  SHAMapItem(tx.first->getTransactionID(), std::move(s)),
319  true,
320  false);
321  }
322 
323  // Add pseudo-transactions to the set
324  if (app_.config().standalone() || (proposing && !wrongLCL))
325  {
326  if (prevLedger->isFlagLedger())
327  {
328  // previous ledger was flag ledger, add fee and amendment
329  // pseudo-transactions
330  auto validations = app_.validators().negativeUNLFilter(
331  app_.getValidations().getTrustedForLedger(
332  prevLedger->info().parentHash));
333  if (validations.size() >= app_.validators().quorum())
334  {
335  feeVote_->doVoting(prevLedger, validations, initialSet);
336  app_.getAmendmentTable().doVoting(
337  prevLedger, validations, initialSet);
338  }
339  }
340  else if (
341  prevLedger->isVotingLedger() &&
342  prevLedger->rules().enabled(featureNegativeUNL))
343  {
344  // previous ledger was a voting ledger,
345  // so the current consensus session is for a flag ledger,
346  // add negative UNL pseudo-transactions
347  nUnlVote_.doVoting(
348  prevLedger,
349  app_.validators().getTrustedMasterKeys(),
350  app_.getValidations(),
351  initialSet);
352  }
353  }
354 
355  // Now we need an immutable snapshot
356  initialSet = initialSet->snapShot(false);
357 
358  if (!wrongLCL)
359  {
360  LedgerIndex const seq = prevLedger->info().seq + 1;
362 
363  initialSet->visitLeaves(
364  [&proposed, seq](std::shared_ptr<SHAMapItem const> const& item) {
365  proposed.emplace_back(item->key(), seq);
366  });
367 
368  censorshipDetector_.propose(std::move(proposed));
369  }
370 
371  // Needed because of the move below.
372  auto const setHash = initialSet->getHash().as_uint256();
373 
374  return Result{
375  std::move(initialSet),
377  initialLedger->info().parentHash,
379  setHash,
380  closeTime,
381  app_.timeKeeper().closeTime(),
382  nodeID_}};
383 }
384 
385 void
387  Result const& result,
388  RCLCxLedger const& prevLedger,
389  NetClock::duration const& closeResolution,
390  ConsensusCloseTimes const& rawCloseTimes,
391  ConsensusMode const& mode,
392  Json::Value&& consensusJson)
393 {
394  doAccept(
395  result,
396  prevLedger,
397  closeResolution,
398  rawCloseTimes,
399  mode,
400  std::move(consensusJson));
401 }
402 
403 void
405  Result const& result,
406  RCLCxLedger const& prevLedger,
407  NetClock::duration const& closeResolution,
408  ConsensusCloseTimes const& rawCloseTimes,
409  ConsensusMode const& mode,
410  Json::Value&& consensusJson)
411 {
412  app_.getJobQueue().addJob(
413  jtACCEPT,
414  "acceptLedger",
415  [=, cj = std::move(consensusJson)](auto&) mutable {
416  // Note that no lock is held or acquired during this job.
417  // This is because generic Consensus guarantees that once a ledger
418  // is accepted, the consensus results and capture by reference state
419  // will not change until startRound is called (which happens via
420  // endConsensus).
421  this->doAccept(
422  result,
423  prevLedger,
424  closeResolution,
425  rawCloseTimes,
426  mode,
427  std::move(cj));
428  this->app_.getOPs().endConsensus();
429  });
430 }
431 
432 void
434  Result const& result,
435  RCLCxLedger const& prevLedger,
436  NetClock::duration closeResolution,
437  ConsensusCloseTimes const& rawCloseTimes,
438  ConsensusMode const& mode,
439  Json::Value&& consensusJson)
440 {
441  prevProposers_ = result.proposers;
442  prevRoundTime_ = result.roundTime.read();
443 
444  bool closeTimeCorrect;
445 
446  const bool proposing = mode == ConsensusMode::proposing;
447  const bool haveCorrectLCL = mode != ConsensusMode::wrongLedger;
448  const bool consensusFail = result.state == ConsensusState::MovedOn;
449 
450  auto consensusCloseTime = result.position.closeTime();
451 
452  if (consensusCloseTime == NetClock::time_point{})
453  {
454  // We agreed to disagree on the close time
455  using namespace std::chrono_literals;
456  consensusCloseTime = prevLedger.closeTime() + 1s;
457  closeTimeCorrect = false;
458  }
459  else
460  {
461  // We agreed on a close time
462  consensusCloseTime = effCloseTime(
463  consensusCloseTime, closeResolution, prevLedger.closeTime());
464  closeTimeCorrect = true;
465  }
466 
467  JLOG(j_.debug()) << "Report: Prop=" << (proposing ? "yes" : "no")
468  << " val=" << (validating_ ? "yes" : "no")
469  << " corLCL=" << (haveCorrectLCL ? "yes" : "no")
470  << " fail=" << (consensusFail ? "yes" : "no");
471  JLOG(j_.debug()) << "Report: Prev = " << prevLedger.id() << ":"
472  << prevLedger.seq();
473 
474  //--------------------------------------------------------------------------
475  std::set<TxID> failed;
476 
477  // We want to put transactions in an unpredictable but deterministic order:
478  // we use the hash of the set.
479  //
480  // FIXME: Use a std::vector and a custom sorter instead of CanonicalTXSet?
481  CanonicalTXSet retriableTxs{result.txns.map_->getHash().as_uint256()};
482 
483  JLOG(j_.debug()) << "Building canonical tx set: " << retriableTxs.key();
484 
485  for (auto const& item : *result.txns.map_)
486  {
487  try
488  {
489  retriableTxs.insert(
490  std::make_shared<STTx const>(SerialIter{item.slice()}));
491  JLOG(j_.debug()) << " Tx: " << item.key();
492  }
493  catch (std::exception const&)
494  {
495  failed.insert(item.key());
496  JLOG(j_.warn()) << " Tx: " << item.key() << " throws!";
497  }
498  }
499 
500  auto built = buildLCL(
501  prevLedger,
502  retriableTxs,
503  consensusCloseTime,
504  closeTimeCorrect,
505  closeResolution,
506  result.roundTime.read(),
507  failed);
508 
509  auto const newLCLHash = built.id();
510  JLOG(j_.debug()) << "Built ledger #" << built.seq() << ": " << newLCLHash;
511 
512  // Tell directly connected peers that we have a new LCL
513  notify(protocol::neACCEPTED_LEDGER, built, haveCorrectLCL);
514 
515  // As long as we're in sync with the network, attempt to detect attempts
516  // at censorship of transaction by tracking which ones don't make it in
517  // after a period of time.
518  if (haveCorrectLCL && result.state == ConsensusState::Yes)
519  {
521 
522  result.txns.map_->visitLeaves(
524  accepted.push_back(item->key());
525  });
526 
527  // Track all the transactions which failed or were marked as retriable
528  for (auto const& r : retriableTxs)
529  failed.insert(r.first.getTXID());
530 
531  censorshipDetector_.check(
532  std::move(accepted),
533  [curr = built.seq(),
534  j = app_.journal("CensorshipDetector"),
535  &failed](uint256 const& id, LedgerIndex seq) {
536  if (failed.count(id))
537  return true;
538 
539  auto const wait = curr - seq;
540 
541  if (wait && (wait % censorshipWarnInternal == 0))
542  {
543  std::ostringstream ss;
544  ss << "Potential Censorship: Eligible tx " << id
545  << ", which we are tracking since ledger " << seq
546  << " has not been included as of ledger " << curr << ".";
547 
548  JLOG(j.warn()) << ss.str();
549  }
550 
551  return false;
552  });
553  }
554 
555  if (validating_)
556  validating_ = ledgerMaster_.isCompatible(
557  *built.ledger_, j_.warn(), "Not validating");
558 
559  if (validating_ && !consensusFail &&
560  app_.getValidations().canValidateSeq(built.seq()))
561  {
562  validate(built, result.txns, proposing);
563  JLOG(j_.info()) << "CNF Val " << newLCLHash;
564  }
565  else
566  JLOG(j_.info()) << "CNF buildLCL " << newLCLHash;
567 
568  // See if we can accept a ledger as fully-validated
569  ledgerMaster_.consensusBuilt(
570  built.ledger_, result.txns.id(), std::move(consensusJson));
571 
572  //-------------------------------------------------------------------------
573  {
574  // Apply disputed transactions that didn't get in
575  //
576  // The first crack of transactions to get into the new
577  // open ledger goes to transactions proposed by a validator
578  // we trust but not included in the consensus set.
579  //
580  // These are done first because they are the most likely
581  // to receive agreement during consensus. They are also
582  // ordered logically "sooner" than transactions not mentioned
583  // in the previous consensus round.
584  //
585  bool anyDisputes = false;
586  for (auto const& [_, dispute] : result.disputes)
587  {
588  (void)_;
589  if (!dispute.getOurVote())
590  {
591  // we voted NO
592  try
593  {
594  JLOG(j_.debug())
595  << "Test applying disputed transaction that did"
596  << " not get in " << dispute.tx().id();
597 
598  SerialIter sit(dispute.tx().tx_.slice());
599  auto txn = std::make_shared<STTx const>(sit);
600 
601  // Disputed pseudo-transactions that were not accepted
602  // can't be successfully applied in the next ledger
603  if (isPseudoTx(*txn))
604  continue;
605 
606  retriableTxs.insert(txn);
607 
608  anyDisputes = true;
609  }
610  catch (std::exception const&)
611  {
612  JLOG(j_.debug())
613  << "Failed to apply transaction we voted NO on";
614  }
615  }
616  }
617 
618  // Build new open ledger
619  std::unique_lock lock{app_.getMasterMutex(), std::defer_lock};
620  std::unique_lock sl{ledgerMaster_.peekMutex(), std::defer_lock};
621  std::lock(lock, sl);
622 
623  auto const lastVal = ledgerMaster_.getValidatedLedger();
624  boost::optional<Rules> rules;
625  if (lastVal)
626  rules.emplace(*lastVal, app_.config().features);
627  else
628  rules.emplace(app_.config().features);
629  app_.openLedger().accept(
630  app_,
631  *rules,
632  built.ledger_,
633  localTxs_.getTxSet(),
634  anyDisputes,
635  retriableTxs,
636  tapNONE,
637  "consensus",
638  [&](OpenView& view, beast::Journal j) {
639  // Stuff the ledger with transactions from the queue.
640  return app_.getTxQ().accept(app_, view);
641  });
642 
643  // Signal a potential fee change to subscribers after the open ledger
644  // is created
645  app_.getOPs().reportFeeChange();
646  }
647 
648  //-------------------------------------------------------------------------
649  {
650  ledgerMaster_.switchLCL(built.ledger_);
651 
652  // Do these need to exist?
653  assert(ledgerMaster_.getClosedLedger()->info().hash == built.id());
654  assert(app_.openLedger().current()->info().parentHash == built.id());
655  }
656 
657  //-------------------------------------------------------------------------
658  // we entered the round with the network,
659  // see how close our close time is to other node's
660  // close time reports, and update our clock.
661  if ((mode == ConsensusMode::proposing ||
663  !consensusFail)
664  {
665  auto closeTime = rawCloseTimes.self;
666 
667  JLOG(j_.info()) << "We closed at "
668  << closeTime.time_since_epoch().count();
669  using usec64_t = std::chrono::duration<std::uint64_t>;
670  usec64_t closeTotal =
671  std::chrono::duration_cast<usec64_t>(closeTime.time_since_epoch());
672  int closeCount = 1;
673 
674  for (auto const& [t, v] : rawCloseTimes.peers)
675  {
676  JLOG(j_.info()) << std::to_string(v) << " time votes for "
677  << std::to_string(t.time_since_epoch().count());
678  closeCount += v;
679  closeTotal +=
680  std::chrono::duration_cast<usec64_t>(t.time_since_epoch()) * v;
681  }
682 
683  closeTotal += usec64_t(closeCount / 2); // for round to nearest
684  closeTotal /= closeCount;
685 
686  // Use signed times since we are subtracting
687  using duration = std::chrono::duration<std::int32_t>;
689  auto offset = time_point{closeTotal} -
690  std::chrono::time_point_cast<duration>(closeTime);
691  JLOG(j_.info()) << "Our close offset is estimated at " << offset.count()
692  << " (" << closeCount << ")";
693 
694  app_.timeKeeper().adjustCloseTime(offset);
695  }
696 }
697 
698 void
700  protocol::NodeEvent ne,
701  RCLCxLedger const& ledger,
702  bool haveCorrectLCL)
703 {
704  protocol::TMStatusChange s;
705 
706  if (!haveCorrectLCL)
707  s.set_newevent(protocol::neLOST_SYNC);
708  else
709  s.set_newevent(ne);
710 
711  s.set_ledgerseq(ledger.seq());
712  s.set_networktime(app_.timeKeeper().now().time_since_epoch().count());
713  s.set_ledgerhashprevious(
714  ledger.parentID().begin(),
715  std::decay_t<decltype(ledger.parentID())>::bytes);
716  s.set_ledgerhash(
717  ledger.id().begin(), std::decay_t<decltype(ledger.id())>::bytes);
718 
719  std::uint32_t uMin, uMax;
720  if (!ledgerMaster_.getFullValidatedRange(uMin, uMax))
721  {
722  uMin = 0;
723  uMax = 0;
724  }
725  else
726  {
727  // Don't advertise ledgers we're not willing to serve
728  uMin = std::max(uMin, ledgerMaster_.getEarliestFetch());
729  }
730  s.set_firstseq(uMin);
731  s.set_lastseq(uMax);
732  app_.overlay().foreach(
733  send_always(std::make_shared<Message>(s, protocol::mtSTATUS_CHANGE)));
734  JLOG(j_.trace()) << "send status change to peer";
735 }
736 
739  RCLCxLedger const& previousLedger,
740  CanonicalTXSet& retriableTxs,
741  NetClock::time_point closeTime,
742  bool closeTimeCorrect,
743  NetClock::duration closeResolution,
744  std::chrono::milliseconds roundTime,
745  std::set<TxID>& failedTxs)
746 {
747  std::shared_ptr<Ledger> built = [&]() {
748  if (auto const replayData = ledgerMaster_.releaseReplay())
749  {
750  assert(replayData->parent()->info().hash == previousLedger.id());
751  return buildLedger(*replayData, tapNONE, app_, j_);
752  }
753  return buildLedger(
754  previousLedger.ledger_,
755  closeTime,
756  closeTimeCorrect,
757  closeResolution,
758  app_,
759  retriableTxs,
760  failedTxs,
761  j_);
762  }();
763 
764  // Update fee computations based on accepted txs
765  using namespace std::chrono_literals;
766  app_.getTxQ().processClosedLedger(app_, *built, roundTime > 5s);
767 
768  // And stash the ledger in the ledger master
769  if (ledgerMaster_.storeLedger(built))
770  JLOG(j_.debug()) << "Consensus built ledger we already had";
771  else if (app_.getInboundLedgers().find(built->info().hash))
772  JLOG(j_.debug()) << "Consensus built ledger we were acquiring";
773  else
774  JLOG(j_.debug()) << "Consensus built new ledger";
775  return RCLCxLedger{std::move(built)};
776 }
777 
778 void
780  RCLCxLedger const& ledger,
781  RCLTxSet const& txns,
782  bool proposing)
783 {
784  using namespace std::chrono_literals;
785 
786  auto validationTime = app_.timeKeeper().closeTime();
787  if (validationTime <= lastValidationTime_)
788  validationTime = lastValidationTime_ + 1s;
789  lastValidationTime_ = validationTime;
790 
791  auto v = std::make_shared<STValidation>(
792  lastValidationTime_,
793  valPublic_,
794  valSecret_,
795  nodeID_,
796  [&](STValidation& v) {
797  v.setFieldH256(sfLedgerHash, ledger.id());
798  v.setFieldH256(sfConsensusHash, txns.id());
799 
800  v.setFieldU32(sfLedgerSequence, ledger.seq());
801 
802  if (proposing)
804 
805  if (ledger.ledger_->rules().enabled(featureHardenedValidations))
806  {
807  // Attest to the hash of what we consider to be the last fully
808  // validated ledger. This may be the hash of the ledger we are
809  // validating here, and that's fine.
810  if (auto const vl = ledgerMaster_.getValidatedLedger())
811  v.setFieldH256(sfValidatedHash, vl->info().hash);
812 
813  v.setFieldU64(sfCookie, valCookie_);
814 
815  // Report our server version every flag ledger:
816  if (ledger.ledger_->isVotingLedger())
817  v.setFieldU64(
818  sfServerVersion, BuildInfo::getEncodedVersion());
819  }
820 
821  // Report our load
822  {
823  auto const& ft = app_.getFeeTrack();
824  auto const fee = std::max(ft.getLocalFee(), ft.getClusterFee());
825  if (fee > ft.getLoadBase())
826  v.setFieldU32(sfLoadFee, fee);
827  }
828 
829  // If the next ledger is a flag ledger, suggest fee changes and
830  // new features:
831  if (ledger.ledger_->isVotingLedger())
832  {
833  // Fees:
834  feeVote_->doValidation(ledger.ledger_->fees(), v);
835 
836  // Amendments
837  // FIXME: pass `v` and have the function insert the array
838  // directly?
839  auto const amendments = app_.getAmendmentTable().doValidation(
840  getEnabledAmendments(*ledger.ledger_));
841 
842  if (!amendments.empty())
843  v.setFieldV256(
844  sfAmendments, STVector256(sfAmendments, amendments));
845  }
846  });
847 
848  // suppress it if we receive it
849  app_.getHashRouter().addSuppression(
851 
852  handleNewValidation(app_, v, "local");
853 
854  // Broadcast to all our peers:
856  protocol::TMValidation val;
857  val.set_validation(&validation[0], validation.size());
858  app_.overlay().broadcast(val);
859 
860  // Publish to all our subscribers:
861  app_.getOPs().pubValidation(v);
862 }
863 
864 void
866 {
867  JLOG(j_.info()) << "Consensus mode change before=" << to_string(before)
868  << ", after=" << to_string(after);
869 
870  // If we were proposing but aren't any longer, we need to reset the
871  // censorship tracking to avoid bogus warnings.
872  if ((before == ConsensusMode::proposing ||
873  before == ConsensusMode::observing) &&
874  before != after)
875  censorshipDetector_.reset();
876 
877  mode_ = after;
878 }
879 
881 RCLConsensus::getJson(bool full) const
882 {
883  Json::Value ret;
884  {
886  ret = consensus_.getJson(full);
887  }
888  ret["validating"] = adaptor_.validating();
889  return ret;
890 }
891 
892 void
894 {
895  try
896  {
898  consensus_.timerEntry(now);
899  }
900  catch (SHAMapMissingNode const& mn)
901  {
902  // This should never happen
903  JLOG(j_.error()) << "During consensus timerEntry: " << mn.what();
904  Rethrow();
905  }
906 }
907 
908 void
910 {
911  try
912  {
914  consensus_.gotTxSet(now, txSet);
915  }
916  catch (SHAMapMissingNode const& mn)
917  {
918  // This should never happen
919  JLOG(j_.error()) << "During consensus gotTxSet: " << mn.what();
920  Rethrow();
921  }
922 }
923 
925 
926 void
928  NetClock::time_point const& now,
929  boost::optional<std::chrono::milliseconds> consensusDelay)
930 {
932  consensus_.simulate(now, consensusDelay);
933 }
934 
935 bool
937  NetClock::time_point const& now,
938  RCLCxPeerPos const& newProposal)
939 {
941  return consensus_.peerProposal(now, newProposal);
942 }
943 
944 bool
946  RCLCxLedger const& prevLgr,
947  hash_set<NodeID> const& nowTrusted)
948 {
949  // We have a key, we do not want out of sync validations after a restart
950  // and are not amendment blocked.
951  validating_ = valPublic_.size() != 0 &&
952  prevLgr.seq() >= app_.getMaxDisallowedLedger() &&
953  !app_.getOPs().isAmendmentBlocked();
954 
955  // If we are not running in standalone mode and there's a configured UNL,
956  // check to make sure that it's not expired.
957  if (validating_ && !app_.config().standalone() && app_.validators().count())
958  {
959  auto const when = app_.validators().expires();
960 
961  if (!when || *when < app_.timeKeeper().now())
962  {
963  JLOG(j_.error()) << "Voluntarily bowing out of consensus process "
964  "because of an expired validator list.";
965  validating_ = false;
966  }
967  }
968 
969  const bool synced = app_.getOPs().getOperatingMode() == OperatingMode::FULL;
970 
971  if (validating_)
972  {
973  JLOG(j_.info()) << "Entering consensus process, validating, synced="
974  << (synced ? "yes" : "no");
975  }
976  else
977  {
978  // Otherwise we just want to monitor the validation process.
979  JLOG(j_.info()) << "Entering consensus process, watching, synced="
980  << (synced ? "yes" : "no");
981  }
982 
983  // Notify inbound ledgers that we are starting a new round
984  inboundTransactions_.newRound(prevLgr.seq());
985 
986  // Notify NegativeUNLVote that new validators are added
987  if (prevLgr.ledger_->rules().enabled(featureNegativeUNL) &&
988  !nowTrusted.empty())
989  nUnlVote_.newValidators(prevLgr.seq() + 1, nowTrusted);
990 
991  // propose only if we're in sync with the network (and validating)
992  return validating_ && synced;
993 }
994 
995 bool
997 {
998  return ledgerMaster_.haveValidated();
999 }
1000 
1003 {
1004  return ledgerMaster_.getValidLedgerIndex();
1005 }
1006 
1009 {
1010  return app_.validators().getQuorumKeys();
1011 }
1012 
1015  Ledger_t::Seq const seq,
1016  hash_set<RCLConsensus::Adaptor::NodeKey_t>& trustedKeys) const
1017 {
1018  return app_.getValidations().laggards(seq, trustedKeys);
1019 }
1020 
1021 bool
1023 {
1024  return !valPublic_.empty();
1025 }
1026 
1027 void
1029 {
1030  if (!positions && app_.getOPs().isFull())
1031  app_.getOPs().setMode(OperatingMode::CONNECTED);
1032 }
1033 
1034 void
1036  NetClock::time_point const& now,
1037  RCLCxLedger::ID const& prevLgrId,
1038  RCLCxLedger const& prevLgr,
1039  hash_set<NodeID> const& nowUntrusted,
1040  hash_set<NodeID> const& nowTrusted)
1041 {
1043  consensus_.startRound(
1044  now,
1045  prevLgrId,
1046  prevLgr,
1047  nowUntrusted,
1048  adaptor_.preStartRound(prevLgr, nowTrusted));
1049 }
1050 } // 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:881
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:1035
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::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:945
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:909
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:189
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:893
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::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:36
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:433
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::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:404
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:1028
ripple::isPseudoTx
bool isPseudoTx(STObject const &tx)
Check whether a transaction is a pseudo-transaction.
Definition: STTx.cpp:524
ripple::RCLConsensus::Adaptor::haveValidated
bool haveValidated() const
Definition: RCLConsensus.cpp:996
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:1014
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:34
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:936
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:779
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:156
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
ripple::sfLedgerSequence
const SF_U32 sfLedgerSequence(access, STI_UINT32, 6, "LedgerSequence")
Definition: SField.h:358
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:699
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:63
ripple::RCLConsensus::Adaptor::validator
bool validator() const
Whether I am a validator.
Definition: RCLConsensus.cpp:1022
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:738
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:865
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:1002
ripple::base_uint::begin
iterator begin()
Definition: base_uint.h:114
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:227
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:177
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::sfConsensusHash
const SF_U256 sfConsensusHash(access, STI_HASH256, 23, "ConsensusHash")
Definition: SField.h:435
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:386
ripple::sfLedgerHash
const SF_U256 sfLedgerHash(access, STI_HASH256, 1, "LedgerHash")
Definition: SField.h:417
std::set
STL class.
ripple::RCLConsensus::Adaptor::getQuorumKeys
std::pair< std::size_t, hash_set< NodeKey_t > > getQuorumKeys() const
Definition: RCLConsensus.cpp:1008
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:149
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:927
ripple::ConsensusProposal< NodeID, uint256, uint256 >
ripple::OperatingMode::FULL
@ FULL
we have the ledger and can even validate