rippled
AmendmentTable.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/main/Application.h>
21 #include <ripple/app/misc/AmendmentTable.h>
22 #include <ripple/app/rdb/RelationalDBInterface_global.h>
23 #include <ripple/core/ConfigSections.h>
24 #include <ripple/protocol/Feature.h>
25 #include <ripple/protocol/STValidation.h>
26 #include <ripple/protocol/TxFlags.h>
27 #include <ripple/protocol/jss.h>
28 #include <boost/format.hpp>
29 #include <boost/regex.hpp>
30 #include <algorithm>
31 #include <mutex>
32 
33 namespace ripple {
34 
36 parseSection(Section const& section)
37 {
38  static boost::regex const re1(
39  "^" // start of line
40  "(?:\\s*)" // whitespace (optional)
41  "([abcdefABCDEF0-9]{64})" // <hexadecimal amendment ID>
42  "(?:\\s+)" // whitespace
43  "(\\S+)" // <description>
44  ,
45  boost::regex_constants::optimize);
46 
48 
49  for (auto const& line : section.lines())
50  {
51  boost::smatch match;
52 
53  if (!boost::regex_match(line, match, re1))
54  Throw<std::runtime_error>(
55  "Invalid entry '" + line + "' in [" + section.name() + "]");
56 
57  uint256 id;
58 
59  if (!id.parseHex(match[1]))
60  Throw<std::runtime_error>(
61  "Invalid amendment ID '" + match[1] + "' in [" +
62  section.name() + "]");
63 
64  names.push_back(std::make_pair(id, match[2]));
65  }
66 
67  return names;
68 }
69 
75 {
77  bool vetoed = false;
78 
84  bool enabled = false;
85 
87  bool supported = false;
88 
91 
92  explicit AmendmentState() = default;
93 };
94 
97 {
98 private:
99  // How many yes votes each amendment received
101  Rules const& rules_;
102  // number of trusted validations
104  // number of votes needed
105  int threshold_ = 0;
106 
107 public:
109  Rules const& rules,
111  : rules_(rules)
112  {
113  // process validations for ledger before flag ledger
114  for (auto const& val : valSet)
115  {
116  if (val->isTrusted())
117  {
118  if (val->isFieldPresent(sfAmendments))
119  {
120  auto const choices = val->getFieldV256(sfAmendments);
122  choices.begin(),
123  choices.end(),
124  [&](auto const& amendment) { ++votes_[amendment]; });
125  }
126 
128  }
129  }
130 
132  ? std::max(
133  1L,
134  static_cast<long>(
138  : std::max(
139  1L,
140  static_cast<long>(
144  }
145 
146  bool
147  passes(uint256 const& amendment) const
148  {
149  auto const& it = votes_.find(amendment);
150 
151  if (it == votes_.end())
152  return false;
153 
154  // Before this fix, it was possible for an amendment to activate with a
155  // percentage slightly less than 80% because we compared for "greater
156  // than or equal to" instead of strictly "greater than".
157  // One validator is an exception, otherwise it is not possible
158  // to gain majority.
160  trustedValidations_ == 1)
161  return it->second >= threshold_;
162 
163  return it->second > threshold_;
164  }
165 
166  int
167  votes(uint256 const& amendment) const
168  {
169  auto const& it = votes_.find(amendment);
170 
171  if (it == votes_.end())
172  return 0;
173 
174  return it->second;
175  }
176 
177  int
179  {
180  return trustedValidations_;
181  }
182 
183  int
184  threshold() const
185  {
186  return threshold_;
187  }
188 };
189 
190 //------------------------------------------------------------------------------
191 
198 class AmendmentTableImpl final : public AmendmentTable
199 {
200 private:
202 
205 
206  // Time that an amendment must hold a majority for
208 
209  // The results of the last voting round - may be empty if
210  // we haven't participated in one yet.
212 
213  // True if an unsupported amendment is enabled
215 
216  // Unset if no unsupported amendments reach majority,
217  // else set to the earliest time an unsupported amendment
218  // will be enabled.
220 
222 
223  // Database which persists veto/unveto vote
225 
226  // Finds or creates state. Must be called with mutex_ locked.
228  add(uint256 const& amendment, std::lock_guard<std::mutex> const& sl);
229 
230  // Finds existing state. Must be called with mutex_ locked.
232  get(uint256 const& amendment, std::lock_guard<std::mutex> const& sl);
233 
234  AmendmentState const*
235  get(uint256 const& amendment, std::lock_guard<std::mutex> const& sl) const;
236 
237  // Injects amendment json into v. Must be called with mutex_ locked.
238  void
239  injectJson(
240  Json::Value& v,
241  uint256 const& amendment,
242  AmendmentState const& state,
243  std::lock_guard<std::mutex> const& sl) const;
244 
245  void
246  persistVote(
247  uint256 const& amendment,
248  std::string const& name,
249  bool vote_to_veto) const;
250 
251 public:
253  Application& app,
254  std::chrono::seconds majorityTime,
255  Section const& supported,
256  Section const& enabled,
257  Section const& vetoed,
258  beast::Journal journal);
259 
260  uint256
261  find(std::string const& name) const override;
262 
263  bool
264  veto(uint256 const& amendment) override;
265  bool
266  unVeto(uint256 const& amendment) override;
267 
268  bool
269  enable(uint256 const& amendment) override;
270 
271  bool
272  isEnabled(uint256 const& amendment) const override;
273  bool
274  isSupported(uint256 const& amendment) const override;
275 
276  bool
277  hasUnsupportedEnabled() const override;
278 
280  firstUnsupportedExpected() const override;
281 
283  getJson() const override;
285  getJson(uint256 const&) const override;
286 
287  bool
288  needValidatedLedger(LedgerIndex seq) const override;
289 
290  void
292  LedgerIndex seq,
293  std::set<uint256> const& enabled,
294  majorityAmendments_t const& majority) override;
295 
297  doValidation(std::set<uint256> const& enabledAmendments) const override;
298 
300  getDesired() const override;
301 
303  doVoting(
304  Rules const& rules,
305  NetClock::time_point closeTime,
306  std::set<uint256> const& enabledAmendments,
307  majorityAmendments_t const& majorityAmendments,
308  std::vector<std::shared_ptr<STValidation>> const& validations) override;
309 };
310 
311 //------------------------------------------------------------------------------
312 
314  Application& app,
315  std::chrono::seconds majorityTime,
316  Section const& supported,
317  Section const& enabled,
318  Section const& vetoed,
319  beast::Journal journal)
320  : lastUpdateSeq_(0)
321  , majorityTime_(majorityTime)
322  , unsupportedEnabled_(false)
323  , j_(journal)
324  , db_(app.getWalletDB())
325 {
327 
328  // Find out if the FeatureVotes table exists in WalletDB
329  bool const featureVotesExist = [this]() {
330  auto db = db_.checkoutDb();
331  return createFeatureVotes(*db);
332  }();
333 
334  // Parse supported amendments
335  for (auto const& a : parseSection(supported))
336  {
337  if (auto s = add(a.first, sl))
338  {
339  JLOG(j_.debug()) << "Amendment " << a.first << " is supported.";
340 
341  if (!a.second.empty())
342  s->name = a.second;
343 
344  s->supported = true;
345  }
346  }
347 
348  hash_set<uint256> detect_conflict;
349  // Parse enabled amendments from config
350  for (auto const& a : parseSection(enabled))
351  {
352  if (featureVotesExist)
353  { // If the table existed, warn about duplicate config info
354  JLOG(j_.warn()) << "[amendments] section in config file ignored"
355  " in favor of data in db/wallet.db.";
356  break;
357  }
358  else
359  { // Otherwise transfer config data into the table
360  detect_conflict.insert(a.first);
361  persistVote(a.first, a.second, false); // un-veto
362  }
363  }
364 
365  // Parse vetoed amendments from config
366  for (auto const& a : parseSection(vetoed))
367  {
368  if (featureVotesExist)
369  { // If the table existed, warn about duplicate config info
370  JLOG(j_.warn())
371  << "[veto_amendments] section in config file ignored"
372  " in favor of data in db/wallet.db.";
373  break;
374  }
375  else
376  { // Otherwise transfer config data into the table
377  if (detect_conflict.count(a.first) == 0)
378  {
379  persistVote(a.first, a.second, true); // veto
380  }
381  else
382  {
383  JLOG(j_.warn())
384  << "[veto_amendments] section in config has amendment "
385  << '(' << a.first << ", " << a.second
386  << ") both [veto_amendments] and [amendments].";
387  }
388  }
389  }
390 
391  // Read amendment votes from wallet.db
392  auto db = db_.checkoutDb();
394  *db,
395  [&](boost::optional<std::string> amendment_hash,
396  boost::optional<std::string> amendment_name,
397  boost::optional<int> vote_to_veto) {
398  uint256 amend_hash;
399  if (!amend_hash.parseHex(*amendment_hash))
400  {
401  Throw<std::runtime_error>(
402  "Invalid amendment ID '" + *amendment_hash +
403  " in wallet.db");
404  }
405  if (*vote_to_veto)
406  {
407  // Unknown amendments are effectively vetoed already
408  if (auto s = get(amend_hash, sl))
409  {
410  JLOG(j_.info()) << "Amendment {" << *amendment_name << ", "
411  << amend_hash << "} is vetoed.";
412  if (!amendment_name->empty())
413  s->name = *amendment_name;
414  s->vetoed = true;
415  }
416  }
417  else // un-veto
418  {
419  if (auto s = add(amend_hash, sl))
420  {
421  JLOG(j_.debug()) << "Amendment {" << *amendment_name << ", "
422  << amend_hash << "} is un-vetoed.";
423  if (!amendment_name->empty())
424  s->name = *amendment_name;
425  s->vetoed = false;
426  }
427  }
428  });
429 }
430 
433  uint256 const& amendmentHash,
435 {
436  // call with the mutex held
437  return &amendmentMap_[amendmentHash];
438 }
439 
442  uint256 const& amendmentHash,
443  std::lock_guard<std::mutex> const& sl)
444 {
445  // Forward to the const version of get.
446  return const_cast<AmendmentState*>(
447  std::as_const(*this).get(amendmentHash, sl));
448 }
449 
450 AmendmentState const*
452  uint256 const& amendmentHash,
453  std::lock_guard<std::mutex> const&) const
454 {
455  // call with the mutex held
456  auto ret = amendmentMap_.find(amendmentHash);
457 
458  if (ret == amendmentMap_.end())
459  return nullptr;
460 
461  return &ret->second;
462 }
463 
464 uint256
466 {
468 
469  for (auto const& e : amendmentMap_)
470  {
471  if (name == e.second.name)
472  return e.first;
473  }
474 
475  return {};
476 }
477 
478 void
480  uint256 const& amendment,
481  std::string const& name,
482  bool vote_to_veto) const
483 {
484  auto db = db_.checkoutDb();
485  voteAmendment(*db, amendment, name, vote_to_veto);
486 }
487 
488 bool
490 {
492  auto s = add(amendment, sl);
493 
494  if (s->vetoed)
495  return false;
496  s->vetoed = true;
497  persistVote(amendment, s->name, s->vetoed);
498  return true;
499 }
500 
501 bool
503 {
505  auto s = get(amendment, sl);
506 
507  if (!s || !s->vetoed)
508  return false;
509  s->vetoed = false;
510  persistVote(amendment, s->name, s->vetoed);
511  return true;
512 }
513 
514 bool
516 {
518  auto s = add(amendment, sl);
519 
520  if (s->enabled)
521  return false;
522 
523  s->enabled = true;
524 
525  if (!s->supported)
526  {
527  JLOG(j_.error()) << "Unsupported amendment " << amendment
528  << " activated.";
529  unsupportedEnabled_ = true;
530  }
531 
532  return true;
533 }
534 
535 bool
536 AmendmentTableImpl::isEnabled(uint256 const& amendment) const
537 {
539  auto s = get(amendment, sl);
540  return s && s->enabled;
541 }
542 
543 bool
545 {
547  auto s = get(amendment, sl);
548  return s && s->supported;
549 }
550 
551 bool
553 {
555  return unsupportedEnabled_;
556 }
557 
560 {
563 }
564 
567 {
568  // Get the list of amendments we support and do not
569  // veto, but that are not already enabled
570  std::vector<uint256> amendments;
571 
572  {
574  amendments.reserve(amendmentMap_.size());
575  for (auto const& e : amendmentMap_)
576  {
577  if (e.second.supported && !e.second.vetoed &&
578  (enabled.count(e.first) == 0))
579  {
580  amendments.push_back(e.first);
581  }
582  }
583  }
584 
585  if (!amendments.empty())
586  std::sort(amendments.begin(), amendments.end());
587 
588  return amendments;
589 }
590 
593 {
594  // Get the list of amendments we support and do not veto
595  return doValidation({});
596 }
597 
600  Rules const& rules,
601  NetClock::time_point closeTime,
602  std::set<uint256> const& enabledAmendments,
603  majorityAmendments_t const& majorityAmendments,
605 {
606  JLOG(j_.trace()) << "voting at " << closeTime.time_since_epoch().count()
607  << ": " << enabledAmendments.size() << ", "
608  << majorityAmendments.size() << ", " << valSet.size();
609 
610  auto vote = std::make_unique<AmendmentSet>(rules, valSet);
611 
612  JLOG(j_.debug()) << "Received " << vote->trustedValidations()
613  << " trusted validations, threshold is: "
614  << vote->threshold();
615 
616  // Map of amendments to the action to be taken for each one. The action is
617  // the value of the flags in the pseudo-transaction
619 
621 
622  // process all amendments we know of
623  for (auto const& entry : amendmentMap_)
624  {
625  NetClock::time_point majorityTime = {};
626 
627  bool const hasValMajority = vote->passes(entry.first);
628 
629  {
630  auto const it = majorityAmendments.find(entry.first);
631  if (it != majorityAmendments.end())
632  majorityTime = it->second;
633  }
634 
635  if (enabledAmendments.count(entry.first) != 0)
636  {
637  JLOG(j_.debug()) << entry.first << ": amendment already enabled";
638  }
639  else if (
640  hasValMajority && (majorityTime == NetClock::time_point{}) &&
641  !entry.second.vetoed)
642  {
643  // Ledger says no majority, validators say yes
644  JLOG(j_.debug()) << entry.first << ": amendment got majority";
645  actions[entry.first] = tfGotMajority;
646  }
647  else if (!hasValMajority && (majorityTime != NetClock::time_point{}))
648  {
649  // Ledger says majority, validators say no
650  JLOG(j_.debug()) << entry.first << ": amendment lost majority";
651  actions[entry.first] = tfLostMajority;
652  }
653  else if (
654  (majorityTime != NetClock::time_point{}) &&
655  ((majorityTime + majorityTime_) <= closeTime) &&
656  !entry.second.vetoed)
657  {
658  // Ledger says majority held
659  JLOG(j_.debug()) << entry.first << ": amendment majority held";
660  actions[entry.first] = 0;
661  }
662  }
663 
664  // Stash for reporting
665  lastVote_ = std::move(vote);
666  return actions;
667 }
668 
669 bool
671 {
673 
674  // Is there a ledger in which an amendment could have been enabled
675  // between these two ledger sequences?
676 
677  return ((ledgerSeq - 1) / 256) != ((lastUpdateSeq_ - 1) / 256);
678 }
679 
680 void
682  LedgerIndex ledgerSeq,
683  std::set<uint256> const& enabled,
684  majorityAmendments_t const& majority)
685 {
686  for (auto& e : enabled)
687  enable(e);
688 
690 
691  // Remember the ledger sequence of this update.
692  lastUpdateSeq_ = ledgerSeq;
693 
694  // Since we have the whole list in `majority`, reset the time flag, even
695  // if it's currently set. If it's not set when the loop is done, then any
696  // prior unknown amendments have lost majority.
698  for (auto const& [hash, time] : majority)
699  {
700  auto s = add(hash, sl);
701 
702  if (s->enabled)
703  continue;
704 
705  if (!s->supported)
706  {
707  JLOG(j_.info()) << "Unsupported amendment " << hash
708  << " reached majority at " << to_string(time);
711  }
712  }
715 }
716 
717 void
719  Json::Value& v,
720  const uint256& id,
721  const AmendmentState& fs,
722  std::lock_guard<std::mutex> const&) const
723 {
724  if (!fs.name.empty())
725  v[jss::name] = fs.name;
726 
727  v[jss::supported] = fs.supported;
728  v[jss::vetoed] = fs.vetoed;
729  v[jss::enabled] = fs.enabled;
730 
731  if (!fs.enabled && lastVote_)
732  {
733  auto const votesTotal = lastVote_->trustedValidations();
734  auto const votesNeeded = lastVote_->threshold();
735  auto const votesFor = lastVote_->votes(id);
736 
737  v[jss::count] = votesFor;
738  v[jss::validations] = votesTotal;
739 
740  if (votesNeeded)
741  v[jss::threshold] = votesNeeded;
742  }
743 }
744 
747 {
749  {
751  for (auto const& e : amendmentMap_)
752  {
753  injectJson(
754  ret[to_string(e.first)] = Json::objectValue,
755  e.first,
756  e.second,
757  sl);
758  }
759  }
760  return ret;
761 }
762 
764 AmendmentTableImpl::getJson(uint256 const& amendmentID) const
765 {
767  Json::Value& jAmendment = (ret[to_string(amendmentID)] = Json::objectValue);
768 
769  {
771  auto a = get(amendmentID, sl);
772  if (a)
773  injectJson(jAmendment, amendmentID, *a, sl);
774  }
775 
776  return ret;
777 }
778 
781  Application& app,
782  std::chrono::seconds majorityTime,
783  Section const& supported,
784  Section const& enabled,
785  Section const& vetoed,
786  beast::Journal journal)
787 {
788  return std::make_unique<AmendmentTableImpl>(
789  app, majorityTime, supported, enabled, vetoed, journal);
790 }
791 
792 } // namespace ripple
ripple::Section
Holds a collection of configuration values.
Definition: BasicConfig.h:42
ripple::Application
Definition: Application.h:103
ripple::AmendmentTableImpl::db_
DatabaseCon & db_
Definition: AmendmentTable.cpp:224
ripple::AmendmentState::supported
bool supported
Indicates an amendment that this server has code support for.
Definition: AmendmentTable.cpp:87
ripple::AmendmentTableImpl::lastUpdateSeq_
std::uint32_t lastUpdateSeq_
Definition: AmendmentTable.cpp:204
std::for_each
T for_each(T... args)
ripple::AmendmentState
Current state of an amendment.
Definition: AmendmentTable.cpp:74
std::string
STL class.
std::shared_ptr
STL class.
beast::Journal::trace
Stream trace() const
Severity stream access functions.
Definition: Journal.h:309
ripple::AmendmentSet::threshold_
int threshold_
Definition: AmendmentTable.cpp:105
ripple::AmendmentTableImpl::firstUnsupportedExpected_
std::optional< NetClock::time_point > firstUnsupportedExpected_
Definition: AmendmentTable.cpp:219
std::unordered_set
STL class.
ripple::readAmendments
void readAmendments(soci::session &session, std::function< void(boost::optional< std::string > amendment_hash, boost::optional< std::string > amendment_name, boost::optional< int > vote_to_veto)> const &callback)
readAmendments Read all amendments from FeatureVotes table.
Definition: RelationalDBInterface_global.cpp:256
ripple::AmendmentTableImpl::getDesired
std::vector< uint256 > getDesired() const override
Definition: AmendmentTable.cpp:592
ripple::AmendmentTableImpl::mutex_
std::mutex mutex_
Definition: AmendmentTable.cpp:201
ripple::AmendmentTableImpl::unsupportedEnabled_
bool unsupportedEnabled_
Definition: AmendmentTable.cpp:214
ripple::AmendmentTableImpl::doValidation
std::vector< uint256 > doValidation(std::set< uint256 > const &enabledAmendments) const override
Definition: AmendmentTable.cpp:566
ripple::createFeatureVotes
bool createFeatureVotes(soci::session &session)
createFeatureVotes Creates FeatureVote table if it is not exists.
Definition: RelationalDBInterface_global.cpp:232
std::vector
STL class.
std::map::find
T find(T... args)
std::set::size
T size(T... args)
std::chrono::seconds
ripple::AmendmentTableImpl::find
uint256 find(std::string const &name) const override
Definition: AmendmentTable.cpp:465
ripple::AmendmentState::vetoed
bool vetoed
If an amendment is vetoed, a server will not support it.
Definition: AmendmentTable.cpp:77
beast::Journal::warn
Stream warn() const
Definition: Journal.h:327
ripple::AmendmentSet::votes_
hash_map< uint256, int > votes_
Definition: AmendmentTable.cpp:100
std::lock_guard
STL class.
ripple::AmendmentTableImpl::unVeto
bool unVeto(uint256 const &amendment) override
Definition: AmendmentTable.cpp:502
ripple::AmendmentSet
The status of all amendments requested in a given window.
Definition: AmendmentTable.cpp:96
ripple::tfLostMajority
const std::uint32_t tfLostMajority
Definition: TxFlags.h:102
std::as_const
T as_const(T... args)
ripple::tfGotMajority
const std::uint32_t tfGotMajority
Definition: TxFlags.h:101
ripple::AmendmentTableImpl
Track the list of "amendments".
Definition: AmendmentTable.cpp:198
std::sort
T sort(T... args)
algorithm
ripple::parseSection
static std::vector< std::pair< uint256, std::string > > parseSection(Section const &section)
Definition: AmendmentTable.cpp:36
std::vector::push_back
T push_back(T... args)
ripple::AmendmentSet::passes
bool passes(uint256 const &amendment) const
Definition: AmendmentTable.cpp:147
ripple::base_uint
Integers of any length that is a multiple of 32-bits.
Definition: base_uint.h:74
ripple::Section::name
std::string const & name() const
Returns the name of this section.
Definition: BasicConfig.h:59
std::chrono::time_point::time_since_epoch
T time_since_epoch(T... args)
ripple::AmendmentTableImpl::persistVote
void persistVote(uint256 const &amendment, std::string const &name, bool vote_to_veto) const
Definition: AmendmentTable.cpp:479
ripple::AmendmentSet::threshold
int threshold() const
Definition: AmendmentTable.cpp:184
ripple::voteAmendment
void voteAmendment(soci::session &session, uint256 const &amendment, std::string const &name, bool vote_to_veto)
voteAmendment Set veto value for particular amendment.
Definition: RelationalDBInterface_global.cpp:283
ripple::DatabaseCon::checkoutDb
LockedSociSession checkoutDb()
Definition: DatabaseCon.h:178
Json::objectValue
@ objectValue
object value (collection of name/value pairs).
Definition: json_value.h:43
ripple::AmendmentTableImpl::firstUnsupportedExpected
std::optional< NetClock::time_point > firstUnsupportedExpected() const override
Definition: AmendmentTable.cpp:559
ripple::preFixAmendmentMajorityCalcThreshold
constexpr std::ratio< 204, 256 > preFixAmendmentMajorityCalcThreshold
The minimum amount of support an amendment should have.
Definition: SystemParameters.h:71
ripple::fixAmendmentMajorityCalc
const uint256 fixAmendmentMajorityCalc
Definition: Feature.cpp:191
ripple::AmendmentState::AmendmentState
AmendmentState()=default
ripple::AmendmentTableImpl::doVoting
std::map< uint256, std::uint32_t > doVoting(Rules const &rules, NetClock::time_point closeTime, std::set< uint256 > const &enabledAmendments, majorityAmendments_t const &majorityAmendments, std::vector< std::shared_ptr< STValidation >> const &validations) override
Definition: AmendmentTable.cpp:599
ripple::AmendmentSet::rules_
Rules const & rules_
Definition: AmendmentTable.cpp:101
ripple::AmendmentTableImpl::isSupported
bool isSupported(uint256 const &amendment) const override
Definition: AmendmentTable.cpp:544
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::AmendmentTableImpl::AmendmentTableImpl
AmendmentTableImpl(Application &app, std::chrono::seconds majorityTime, Section const &supported, Section const &enabled, Section const &vetoed, beast::Journal journal)
Definition: AmendmentTable.cpp:313
ripple::make_AmendmentTable
std::unique_ptr< AmendmentTable > make_AmendmentTable(Application &app, std::chrono::seconds majorityTime, Section const &supported, Section const &enabled, Section const &vetoed, beast::Journal journal)
Definition: AmendmentTable.cpp:780
ripple::Section::lines
std::vector< std::string > const & lines() const
Returns all the lines in the section.
Definition: BasicConfig.h:68
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
std::uint32_t
ripple::Rules::enabled
bool enabled(uint256 const &id) const
Returns true if a feature is enabled.
Definition: ReadView.cpp:102
std::map
STL class.
ripple::AmendmentTableImpl::veto
bool veto(uint256 const &amendment) override
Definition: AmendmentTable.cpp:489
ripple::AmendmentSet::trustedValidations_
int trustedValidations_
Definition: AmendmentTable.cpp:103
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::AmendmentTableImpl::amendmentMap_
hash_map< uint256, AmendmentState > amendmentMap_
Definition: AmendmentTable.cpp:203
ripple::AmendmentTableImpl::lastVote_
std::unique_ptr< AmendmentSet > lastVote_
Definition: AmendmentTable.cpp:211
std::unordered_set::insert
T insert(T... args)
ripple::AmendmentTableImpl::majorityTime_
const std::chrono::seconds majorityTime_
Definition: AmendmentTable.cpp:207
ripple::AmendmentState::enabled
bool enabled
Indicates that the amendment has been enabled.
Definition: AmendmentTable.cpp:84
ripple::AmendmentSet::AmendmentSet
AmendmentSet(Rules const &rules, std::vector< std::shared_ptr< STValidation >> const &valSet)
Definition: AmendmentTable.cpp:108
ripple::AmendmentTableImpl::getJson
Json::Value getJson() const override
Definition: AmendmentTable.cpp:746
ripple::DatabaseCon
Definition: DatabaseCon.h:81
ripple::AmendmentState::name
std::string name
The name of this amendment, possibly empty.
Definition: AmendmentTable.cpp:90
std::unordered_set::count
T count(T... args)
std::string::empty
T empty(T... args)
ripple::Rules
Rules controlling protocol behavior.
Definition: ReadView.h:131
std::optional
mutex
beast::Journal::debug
Stream debug() const
Definition: Journal.h:315
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:39
std::make_pair
T make_pair(T... args)
std::map::end
T end(T... args)
ripple::AmendmentSet::trustedValidations
int trustedValidations() const
Definition: AmendmentTable.cpp:178
ripple::AmendmentTableImpl::isEnabled
bool isEnabled(uint256 const &amendment) const override
Definition: AmendmentTable.cpp:536
std::max
T max(T... args)
ripple::base_uint::parseHex
constexpr bool parseHex(std::string_view sv)
Parse a hex string into a base_uint.
Definition: base_uint.h:472
ripple::AmendmentTableImpl::injectJson
void injectJson(Json::Value &v, uint256 const &amendment, AmendmentState const &state, std::lock_guard< std::mutex > const &sl) const
Definition: AmendmentTable.cpp:718
ripple::AmendmentTableImpl::j_
const beast::Journal j_
Definition: AmendmentTable.cpp:221
ripple::AmendmentTableImpl::add
AmendmentState * add(uint256 const &amendment, std::lock_guard< std::mutex > const &sl)
Definition: AmendmentTable.cpp:432
ripple::AmendmentTable
The amendment table stores the list of enabled and potential amendments.
Definition: AmendmentTable.h:36
ripple::AmendmentTableImpl::needValidatedLedger
bool needValidatedLedger(LedgerIndex seq) const override
Called to determine whether the amendment logic needs to process a new validated ledger.
Definition: AmendmentTable.cpp:670
ripple::AmendmentSet::votes
int votes(uint256 const &amendment) const
Definition: AmendmentTable.cpp:167
std::unique_ptr
STL class.
std::unordered_map
STL class.
std::set
STL class.
ripple::postFixAmendmentMajorityCalcThreshold
constexpr std::ratio< 80, 100 > postFixAmendmentMajorityCalcThreshold
Definition: SystemParameters.h:73
ripple::AmendmentTableImpl::doValidatedLedger
void doValidatedLedger(LedgerIndex seq, std::set< uint256 > const &enabled, majorityAmendments_t const &majority) override
Definition: AmendmentTable.cpp:681
ripple::AmendmentTableImpl::enable
bool enable(uint256 const &amendment) override
Definition: AmendmentTable.cpp:515
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::sfAmendments
const SF_VECTOR256 sfAmendments
ripple::AmendmentTableImpl::get
AmendmentState * get(uint256 const &amendment, std::lock_guard< std::mutex > const &sl)
Definition: AmendmentTable.cpp:441
ripple::AmendmentTableImpl::hasUnsupportedEnabled
bool hasUnsupportedEnabled() const override
returns true if one or more amendments on the network have been enabled that this server does not sup...
Definition: AmendmentTable.cpp:552