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