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/core/ConfigSections.h>
23 #include <ripple/core/DatabaseCon.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  soci::transaction tr(*db);
332  std::string sql =
333  "SELECT count(*) FROM sqlite_master "
334  "WHERE type='table' AND name='FeatureVotes'";
335  // SOCI requires boost::optional (not std::optional) as the parameter.
336  boost::optional<int> featureVotesCount;
337  *db << sql, soci::into(featureVotesCount);
338  bool exists = static_cast<bool>(*featureVotesCount);
339 
340  // Create FeatureVotes table in WalletDB if it doesn't exist
341  if (!exists)
342  {
343  *db << "CREATE TABLE FeatureVotes ( "
344  "AmendmentHash CHARACTER(64) NOT NULL, "
345  "AmendmentName TEXT, "
346  "Veto INTEGER NOT NULL );";
347  tr.commit();
348  }
349  return exists;
350  }();
351 
352  // Parse supported amendments
353  for (auto const& a : parseSection(supported))
354  {
355  if (auto s = add(a.first, sl))
356  {
357  JLOG(j_.debug()) << "Amendment " << a.first << " is supported.";
358 
359  if (!a.second.empty())
360  s->name = a.second;
361 
362  s->supported = true;
363  }
364  }
365 
366  hash_set<uint256> detect_conflict;
367  // Parse enabled amendments from config
368  for (auto const& a : parseSection(enabled))
369  {
370  if (featureVotesExist)
371  { // If the table existed, warn about duplicate config info
372  JLOG(j_.warn()) << "[amendments] section in config file ignored"
373  " in favor of data in db/wallet.db.";
374  break;
375  }
376  else
377  { // Otherwise transfer config data into the table
378  detect_conflict.insert(a.first);
379  persistVote(a.first, a.second, false); // un-veto
380  }
381  }
382 
383  // Parse vetoed amendments from config
384  for (auto const& a : parseSection(vetoed))
385  {
386  if (featureVotesExist)
387  { // If the table existed, warn about duplicate config info
388  JLOG(j_.warn())
389  << "[veto_amendments] section in config file ignored"
390  " in favor of data in db/wallet.db.";
391  break;
392  }
393  else
394  { // Otherwise transfer config data into the table
395  if (detect_conflict.count(a.first) == 0)
396  {
397  persistVote(a.first, a.second, true); // veto
398  }
399  else
400  {
401  JLOG(j_.warn())
402  << "[veto_amendments] section in config has amendment "
403  << '(' << a.first << ", " << a.second
404  << ") both [veto_amendments] and [amendments].";
405  }
406  }
407  }
408 
409  // Read amendment votes from wallet.db
410  auto db = db_.checkoutDb();
411  soci::transaction tr(*db);
412  std::string sql =
413  "SELECT AmendmentHash, AmendmentName, Veto FROM FeatureVotes";
414  // SOCI requires boost::optional (not std::optional) as parameters.
415  boost::optional<std::string> amendment_hash;
416  boost::optional<std::string> amendment_name;
417  boost::optional<int> vote_to_veto;
418  soci::statement st =
419  (db->prepare << sql,
420  soci::into(amendment_hash),
421  soci::into(amendment_name),
422  soci::into(vote_to_veto));
423  st.execute();
424  while (st.fetch())
425  {
426  uint256 amend_hash;
427  if (!amend_hash.parseHex(*amendment_hash))
428  {
429  Throw<std::runtime_error>(
430  "Invalid amendment ID '" + *amendment_hash + " in wallet.db");
431  }
432  if (*vote_to_veto)
433  {
434  // Unknown amendments are effectively vetoed already
435  if (auto s = get(amend_hash, sl))
436  {
437  JLOG(j_.info()) << "Amendment {" << *amendment_name << ", "
438  << amend_hash << "} is vetoed.";
439  if (!amendment_name->empty())
440  s->name = *amendment_name;
441  s->vetoed = true;
442  }
443  }
444  else // un-veto
445  {
446  if (auto s = add(amend_hash, sl))
447  {
448  JLOG(j_.debug()) << "Amendment {" << *amendment_name << ", "
449  << amend_hash << "} is un-vetoed.";
450  if (!amendment_name->empty())
451  s->name = *amendment_name;
452  s->vetoed = false;
453  }
454  }
455  }
456 }
457 
460  uint256 const& amendmentHash,
462 {
463  // call with the mutex held
464  return &amendmentMap_[amendmentHash];
465 }
466 
469  uint256 const& amendmentHash,
470  std::lock_guard<std::mutex> const& sl)
471 {
472  // Forward to the const version of get.
473  return const_cast<AmendmentState*>(
474  std::as_const(*this).get(amendmentHash, sl));
475 }
476 
477 AmendmentState const*
479  uint256 const& amendmentHash,
480  std::lock_guard<std::mutex> const&) const
481 {
482  // call with the mutex held
483  auto ret = amendmentMap_.find(amendmentHash);
484 
485  if (ret == amendmentMap_.end())
486  return nullptr;
487 
488  return &ret->second;
489 }
490 
491 uint256
493 {
495 
496  for (auto const& e : amendmentMap_)
497  {
498  if (name == e.second.name)
499  return e.first;
500  }
501 
502  return {};
503 }
504 
505 void
507  uint256 const& amendment,
508  std::string const& name,
509  bool vote_to_veto) const
510 {
511  auto db = db_.checkoutDb();
512  soci::transaction tr(*db);
513  std::string sql =
514  "INSERT INTO FeatureVotes (AmendmentHash, AmendmentName, Veto) VALUES "
515  "('";
516  sql += to_string(amendment);
517  sql += "', '" + name;
518  sql += "', '" + std::to_string(int{vote_to_veto}) + "');";
519  *db << sql;
520  tr.commit();
521 }
522 
523 bool
525 {
527  auto s = add(amendment, sl);
528 
529  if (s->vetoed)
530  return false;
531  s->vetoed = true;
532  persistVote(amendment, s->name, s->vetoed);
533  return true;
534 }
535 
536 bool
538 {
540  auto s = get(amendment, sl);
541 
542  if (!s || !s->vetoed)
543  return false;
544  s->vetoed = false;
545  persistVote(amendment, s->name, s->vetoed);
546  return true;
547 }
548 
549 bool
551 {
553  auto s = add(amendment, sl);
554 
555  if (s->enabled)
556  return false;
557 
558  s->enabled = true;
559 
560  if (!s->supported)
561  {
562  JLOG(j_.error()) << "Unsupported amendment " << amendment
563  << " activated.";
564  unsupportedEnabled_ = true;
565  }
566 
567  return true;
568 }
569 
570 bool
571 AmendmentTableImpl::isEnabled(uint256 const& amendment) const
572 {
574  auto s = get(amendment, sl);
575  return s && s->enabled;
576 }
577 
578 bool
580 {
582  auto s = get(amendment, sl);
583  return s && s->supported;
584 }
585 
586 bool
588 {
590  return unsupportedEnabled_;
591 }
592 
595 {
598 }
599 
602 {
603  // Get the list of amendments we support and do not
604  // veto, but that are not already enabled
605  std::vector<uint256> amendments;
606 
607  {
609  amendments.reserve(amendmentMap_.size());
610  for (auto const& e : amendmentMap_)
611  {
612  if (e.second.supported && !e.second.vetoed &&
613  (enabled.count(e.first) == 0))
614  {
615  amendments.push_back(e.first);
616  }
617  }
618  }
619 
620  if (!amendments.empty())
621  std::sort(amendments.begin(), amendments.end());
622 
623  return amendments;
624 }
625 
628 {
629  // Get the list of amendments we support and do not veto
630  return doValidation({});
631 }
632 
635  Rules const& rules,
636  NetClock::time_point closeTime,
637  std::set<uint256> const& enabledAmendments,
638  majorityAmendments_t const& majorityAmendments,
640 {
641  JLOG(j_.trace()) << "voting at " << closeTime.time_since_epoch().count()
642  << ": " << enabledAmendments.size() << ", "
643  << majorityAmendments.size() << ", " << valSet.size();
644 
645  auto vote = std::make_unique<AmendmentSet>(rules, valSet);
646 
647  JLOG(j_.debug()) << "Received " << vote->trustedValidations()
648  << " trusted validations, threshold is: "
649  << vote->threshold();
650 
651  // Map of amendments to the action to be taken for each one. The action is
652  // the value of the flags in the pseudo-transaction
654 
656 
657  // process all amendments we know of
658  for (auto const& entry : amendmentMap_)
659  {
660  NetClock::time_point majorityTime = {};
661 
662  bool const hasValMajority = vote->passes(entry.first);
663 
664  {
665  auto const it = majorityAmendments.find(entry.first);
666  if (it != majorityAmendments.end())
667  majorityTime = it->second;
668  }
669 
670  if (enabledAmendments.count(entry.first) != 0)
671  {
672  JLOG(j_.debug()) << entry.first << ": amendment already enabled";
673  }
674  else if (
675  hasValMajority && (majorityTime == NetClock::time_point{}) &&
676  !entry.second.vetoed)
677  {
678  // Ledger says no majority, validators say yes
679  JLOG(j_.debug()) << entry.first << ": amendment got majority";
680  actions[entry.first] = tfGotMajority;
681  }
682  else if (!hasValMajority && (majorityTime != NetClock::time_point{}))
683  {
684  // Ledger says majority, validators say no
685  JLOG(j_.debug()) << entry.first << ": amendment lost majority";
686  actions[entry.first] = tfLostMajority;
687  }
688  else if (
689  (majorityTime != NetClock::time_point{}) &&
690  ((majorityTime + majorityTime_) <= closeTime) &&
691  !entry.second.vetoed)
692  {
693  // Ledger says majority held
694  JLOG(j_.debug()) << entry.first << ": amendment majority held";
695  actions[entry.first] = 0;
696  }
697  }
698 
699  // Stash for reporting
700  lastVote_ = std::move(vote);
701  return actions;
702 }
703 
704 bool
706 {
708 
709  // Is there a ledger in which an amendment could have been enabled
710  // between these two ledger sequences?
711 
712  return ((ledgerSeq - 1) / 256) != ((lastUpdateSeq_ - 1) / 256);
713 }
714 
715 void
717  LedgerIndex ledgerSeq,
718  std::set<uint256> const& enabled,
719  majorityAmendments_t const& majority)
720 {
721  for (auto& e : enabled)
722  enable(e);
723 
725 
726  // Remember the ledger sequence of this update.
727  lastUpdateSeq_ = ledgerSeq;
728 
729  // Since we have the whole list in `majority`, reset the time flag, even
730  // if it's currently set. If it's not set when the loop is done, then any
731  // prior unknown amendments have lost majority.
733  for (auto const& [hash, time] : majority)
734  {
735  auto s = add(hash, sl);
736 
737  if (s->enabled)
738  continue;
739 
740  if (!s->supported)
741  {
742  JLOG(j_.info()) << "Unsupported amendment " << hash
743  << " reached majority at " << to_string(time);
746  }
747  }
750 }
751 
752 void
754  Json::Value& v,
755  const uint256& id,
756  const AmendmentState& fs,
757  std::lock_guard<std::mutex> const&) const
758 {
759  if (!fs.name.empty())
760  v[jss::name] = fs.name;
761 
762  v[jss::supported] = fs.supported;
763  v[jss::vetoed] = fs.vetoed;
764  v[jss::enabled] = fs.enabled;
765 
766  if (!fs.enabled && lastVote_)
767  {
768  auto const votesTotal = lastVote_->trustedValidations();
769  auto const votesNeeded = lastVote_->threshold();
770  auto const votesFor = lastVote_->votes(id);
771 
772  v[jss::count] = votesFor;
773  v[jss::validations] = votesTotal;
774 
775  if (votesNeeded)
776  v[jss::threshold] = votesNeeded;
777  }
778 }
779 
782 {
784  {
786  for (auto const& e : amendmentMap_)
787  {
788  injectJson(
789  ret[to_string(e.first)] = Json::objectValue,
790  e.first,
791  e.second,
792  sl);
793  }
794  }
795  return ret;
796 }
797 
799 AmendmentTableImpl::getJson(uint256 const& amendmentID) const
800 {
802  Json::Value& jAmendment = (ret[to_string(amendmentID)] = Json::objectValue);
803 
804  {
806  auto a = get(amendmentID, sl);
807  if (a)
808  injectJson(jAmendment, amendmentID, *a, sl);
809  }
810 
811  return ret;
812 }
813 
816  Application& app,
817  std::chrono::seconds majorityTime,
818  Section const& supported,
819  Section const& enabled,
820  Section const& vetoed,
821  beast::Journal journal)
822 {
823  return std::make_unique<AmendmentTableImpl>(
824  app, majorityTime, supported, enabled, vetoed, journal);
825 }
826 
827 } // namespace ripple
ripple::Section
Holds a collection of configuration values.
Definition: BasicConfig.h:43
ripple::Application
Definition: Application.h:102
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::AmendmentTableImpl::getDesired
std::vector< uint256 > getDesired() const override
Definition: AmendmentTable.cpp:627
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:601
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:492
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:537
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:58
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:506
ripple::AmendmentSet::threshold
int threshold() const
Definition: AmendmentTable.cpp:184
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:594
ripple::preFixAmendmentMajorityCalcThreshold
constexpr std::ratio< 204, 256 > preFixAmendmentMajorityCalcThreshold
The minimum amount of support an amendment should have.
Definition: SystemParameters.h:68
ripple::fixAmendmentMajorityCalc
const uint256 fixAmendmentMajorityCalc
Definition: Feature.cpp:189
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:634
std::to_string
T to_string(T... args)
ripple::AmendmentSet::rules_
Rules const & rules_
Definition: AmendmentTable.cpp:101
ripple::AmendmentTableImpl::isSupported
bool isSupported(uint256 const &amendment) const override
Definition: AmendmentTable.cpp:579
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:815
ripple::Section::lines
std::vector< std::string > const & lines() const
Returns all the lines in the section.
Definition: BasicConfig.h:67
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:524
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:781
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:38
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:571
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:753
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:459
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:705
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:70
ripple::AmendmentTableImpl::doValidatedLedger
void doValidatedLedger(LedgerIndex seq, std::set< uint256 > const &enabled, majorityAmendments_t const &majority) override
Definition: AmendmentTable.cpp:716
ripple::AmendmentTableImpl::enable
bool enable(uint256 const &amendment) override
Definition: AmendmentTable.cpp:550
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:468
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:587