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