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 {
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& lock);
229 
230  // Finds existing state. Must be called with mutex_ locked.
232  get(uint256 const& amendment, std::lock_guard<std::mutex> const& lock);
233 
234  AmendmentState const*
235  get(uint256 const& amendment,
236  std::lock_guard<std::mutex> const& lock) const;
237 
238  // Injects amendment json into v. Must be called with mutex_ locked.
239  void
240  injectJson(
241  Json::Value& v,
242  uint256 const& amendment,
243  AmendmentState const& state,
244  std::lock_guard<std::mutex> const& lock) const;
245 
246  void
247  persistVote(
248  uint256 const& amendment,
249  std::string const& name,
250  AmendmentVote vote) const;
251 
252 public:
254  Application& app,
255  std::chrono::seconds majorityTime,
256  std::vector<FeatureInfo> const& supported,
257  Section const& enabled,
258  Section const& vetoed,
259  beast::Journal journal);
260 
261  uint256
262  find(std::string const& name) const override;
263 
264  bool
265  veto(uint256 const& amendment) override;
266  bool
267  unVeto(uint256 const& amendment) override;
268 
269  bool
270  enable(uint256 const& amendment) override;
271 
272  bool
273  isEnabled(uint256 const& amendment) const override;
274  bool
275  isSupported(uint256 const& amendment) const override;
276 
277  bool
278  hasUnsupportedEnabled() const override;
279 
281  firstUnsupportedExpected() const override;
282 
284  getJson() const override;
286  getJson(uint256 const&) const override;
287 
288  bool
289  needValidatedLedger(LedgerIndex seq) const override;
290 
291  void
293  LedgerIndex seq,
294  std::set<uint256> const& enabled,
295  majorityAmendments_t const& majority) override;
296 
298  doValidation(std::set<uint256> const& enabledAmendments) const override;
299 
301  getDesired() const override;
302 
304  doVoting(
305  Rules const& rules,
306  NetClock::time_point closeTime,
307  std::set<uint256> const& enabledAmendments,
308  majorityAmendments_t const& majorityAmendments,
309  std::vector<std::shared_ptr<STValidation>> const& validations) override;
310 };
311 
312 //------------------------------------------------------------------------------
313 
315  Application& app,
316  std::chrono::seconds majorityTime,
317  std::vector<FeatureInfo> const& supported,
318  Section const& enabled,
319  Section const& vetoed,
320  beast::Journal journal)
321  : lastUpdateSeq_(0)
322  , majorityTime_(majorityTime)
323  , unsupportedEnabled_(false)
324  , j_(journal)
325  , db_(app.getWalletDB())
326 {
327  std::lock_guard lock(mutex_);
328 
329  // Find out if the FeatureVotes table exists in WalletDB
330  bool const featureVotesExist = [this]() {
331  auto db = db_.checkoutDb();
332  return createFeatureVotes(*db);
333  }();
334 
335  // Parse supported amendments
336  for (auto const& [name, amendment, defaultVote] : supported)
337  {
338  AmendmentState& s = add(amendment, lock);
339 
340  s.name = name;
341  s.supported = true;
342  s.vote = defaultVote == DefaultVote::yes ? AmendmentVote::up
344 
345  JLOG(j_.debug()) << "Amendment " << amendment << " (" << s.name
346  << ") is supported and will be "
347  << (s.vote == AmendmentVote::up ? "up" : "down")
348  << " voted if not enabled on the ledger.";
349  }
350 
351  hash_set<uint256> detect_conflict;
352  // Parse enabled amendments from config
353  for (std::pair<uint256, std::string> const& a : parseSection(enabled))
354  {
355  if (featureVotesExist)
356  { // If the table existed, warn about duplicate config info
357  JLOG(j_.warn()) << "[amendments] section in config file ignored"
358  " in favor of data in db/wallet.db.";
359  break;
360  }
361  else
362  { // Otherwise transfer config data into the table
363  detect_conflict.insert(a.first);
364  persistVote(a.first, a.second, AmendmentVote::up);
365  }
366  }
367 
368  // Parse vetoed amendments from config
369  for (auto const& a : parseSection(vetoed))
370  {
371  if (featureVotesExist)
372  { // If the table existed, warn about duplicate config info
373  JLOG(j_.warn())
374  << "[veto_amendments] section in config file ignored"
375  " in favor of data in db/wallet.db.";
376  break;
377  }
378  else
379  { // Otherwise transfer config data into the table
380  if (detect_conflict.count(a.first) == 0)
381  {
382  persistVote(a.first, a.second, AmendmentVote::down);
383  }
384  else
385  {
386  JLOG(j_.warn())
387  << "[veto_amendments] section in config has amendment "
388  << '(' << a.first << ", " << a.second
389  << ") both [veto_amendments] and [amendments].";
390  }
391  }
392  }
393 
394  // Read amendment votes from wallet.db
395  auto db = db_.checkoutDb();
397  *db,
398  [&](boost::optional<std::string> amendment_hash,
399  boost::optional<std::string> amendment_name,
400  boost::optional<AmendmentVote> vote) {
401  uint256 amend_hash;
402  if (!amendment_hash || !amendment_name || !vote)
403  {
404  // These fields should never have nulls, but check
405  Throw<std::runtime_error>(
406  "Invalid FeatureVotes row in wallet.db");
407  }
408  if (!amend_hash.parseHex(*amendment_hash))
409  {
410  Throw<std::runtime_error>(
411  "Invalid amendment ID '" + *amendment_hash +
412  " in wallet.db");
413  }
414  if (*vote == AmendmentVote::down)
415  {
416  // Unknown amendments are effectively vetoed already
417  if (auto s = get(amend_hash, lock))
418  {
419  JLOG(j_.info()) << "Amendment {" << *amendment_name << ", "
420  << amend_hash << "} is downvoted.";
421  if (!amendment_name->empty())
422  s->name = *amendment_name;
423  s->vote = *vote;
424  }
425  }
426  else // up-vote
427  {
428  auto s = add(amend_hash, lock);
429 
430  JLOG(j_.debug()) << "Amendment {" << *amendment_name << ", "
431  << amend_hash << "} is upvoted.";
432  if (!amendment_name->empty())
433  s.name = *amendment_name;
434  s.vote = *vote;
435  }
436  });
437 }
438 
441  uint256 const& amendmentHash,
443 {
444  // call with the mutex held
445  return amendmentMap_[amendmentHash];
446 }
447 
450  uint256 const& amendmentHash,
451  std::lock_guard<std::mutex> const& lock)
452 {
453  // Forward to the const version of get.
454  return const_cast<AmendmentState*>(
455  std::as_const(*this).get(amendmentHash, lock));
456 }
457 
458 AmendmentState const*
460  uint256 const& amendmentHash,
461  std::lock_guard<std::mutex> const&) const
462 {
463  // call with the mutex held
464  auto ret = amendmentMap_.find(amendmentHash);
465 
466  if (ret == amendmentMap_.end())
467  return nullptr;
468 
469  return &ret->second;
470 }
471 
472 uint256
474 {
475  std::lock_guard lock(mutex_);
476 
477  for (auto const& e : amendmentMap_)
478  {
479  if (name == e.second.name)
480  return e.first;
481  }
482 
483  return {};
484 }
485 
486 void
488  uint256 const& amendment,
489  std::string const& name,
490  AmendmentVote vote) const
491 {
492  auto db = db_.checkoutDb();
493  voteAmendment(*db, amendment, name, vote);
494 }
495 
496 bool
498 {
499  std::lock_guard lock(mutex_);
500  AmendmentState& s = add(amendment, lock);
501 
502  if (s.vote == AmendmentVote::down)
503  return false;
505  persistVote(amendment, s.name, s.vote);
506  return true;
507 }
508 
509 bool
511 {
512  std::lock_guard lock(mutex_);
513  AmendmentState* const s = get(amendment, lock);
514 
515  if (!s || s->vote == AmendmentVote::up)
516  return false;
517  s->vote = AmendmentVote::up;
518  persistVote(amendment, s->name, s->vote);
519  return true;
520 }
521 
522 bool
524 {
525  std::lock_guard lock(mutex_);
526  AmendmentState& s = add(amendment, lock);
527 
528  if (s.enabled)
529  return false;
530 
531  s.enabled = true;
532 
533  if (!s.supported)
534  {
535  JLOG(j_.error()) << "Unsupported amendment " << amendment
536  << " activated.";
537  unsupportedEnabled_ = true;
538  }
539 
540  return true;
541 }
542 
543 bool
544 AmendmentTableImpl::isEnabled(uint256 const& amendment) const
545 {
546  std::lock_guard lock(mutex_);
547  AmendmentState const* s = get(amendment, lock);
548  return s && s->enabled;
549 }
550 
551 bool
553 {
554  std::lock_guard lock(mutex_);
555  AmendmentState const* s = get(amendment, lock);
556  return s && s->supported;
557 }
558 
559 bool
561 {
562  std::lock_guard lock(mutex_);
563  return unsupportedEnabled_;
564 }
565 
568 {
569  std::lock_guard lock(mutex_);
571 }
572 
575 {
576  // Get the list of amendments we support and do not
577  // veto, but that are not already enabled
578  std::vector<uint256> amendments;
579 
580  {
581  std::lock_guard lock(mutex_);
582  amendments.reserve(amendmentMap_.size());
583  for (auto const& e : amendmentMap_)
584  {
585  if (e.second.supported && e.second.vote == AmendmentVote::up &&
586  (enabled.count(e.first) == 0))
587  {
588  amendments.push_back(e.first);
589  JLOG(j_.info()) << "Voting for amendment " << e.second.name;
590  }
591  }
592  }
593 
594  if (!amendments.empty())
595  std::sort(amendments.begin(), amendments.end());
596 
597  return amendments;
598 }
599 
602 {
603  // Get the list of amendments we support and do not veto
604  return doValidation({});
605 }
606 
609  Rules const& rules,
610  NetClock::time_point closeTime,
611  std::set<uint256> const& enabledAmendments,
612  majorityAmendments_t const& majorityAmendments,
614 {
615  JLOG(j_.trace()) << "voting at " << closeTime.time_since_epoch().count()
616  << ": " << enabledAmendments.size() << ", "
617  << majorityAmendments.size() << ", " << valSet.size();
618 
619  auto vote = std::make_unique<AmendmentSet>(rules, valSet);
620 
621  JLOG(j_.debug()) << "Received " << vote->trustedValidations()
622  << " trusted validations, threshold is: "
623  << vote->threshold();
624 
625  // Map of amendments to the action to be taken for each one. The action is
626  // the value of the flags in the pseudo-transaction
628 
629  std::lock_guard lock(mutex_);
630 
631  // process all amendments we know of
632  for (auto const& entry : amendmentMap_)
633  {
634  NetClock::time_point majorityTime = {};
635 
636  bool const hasValMajority = vote->passes(entry.first);
637 
638  {
639  auto const it = majorityAmendments.find(entry.first);
640  if (it != majorityAmendments.end())
641  majorityTime = it->second;
642  }
643 
644  if (enabledAmendments.count(entry.first) != 0)
645  {
646  JLOG(j_.debug()) << entry.first << ": amendment already enabled";
647  }
648  else if (
649  hasValMajority && (majorityTime == NetClock::time_point{}) &&
650  entry.second.vote == AmendmentVote::up)
651  {
652  // Ledger says no majority, validators say yes
653  JLOG(j_.debug()) << entry.first << ": amendment got majority";
654  actions[entry.first] = tfGotMajority;
655  }
656  else if (!hasValMajority && (majorityTime != NetClock::time_point{}))
657  {
658  // Ledger says majority, validators say no
659  JLOG(j_.debug()) << entry.first << ": amendment lost majority";
660  actions[entry.first] = tfLostMajority;
661  }
662  else if (
663  (majorityTime != NetClock::time_point{}) &&
664  ((majorityTime + majorityTime_) <= closeTime) &&
665  entry.second.vote == AmendmentVote::up)
666  {
667  // Ledger says majority held
668  JLOG(j_.debug()) << entry.first << ": amendment majority held";
669  actions[entry.first] = 0;
670  }
671  }
672 
673  // Stash for reporting
674  lastVote_ = std::move(vote);
675  return actions;
676 }
677 
678 bool
680 {
681  std::lock_guard lock(mutex_);
682 
683  // Is there a ledger in which an amendment could have been enabled
684  // between these two ledger sequences?
685 
686  return ((ledgerSeq - 1) / 256) != ((lastUpdateSeq_ - 1) / 256);
687 }
688 
689 void
691  LedgerIndex ledgerSeq,
692  std::set<uint256> const& enabled,
693  majorityAmendments_t const& majority)
694 {
695  for (auto& e : enabled)
696  enable(e);
697 
698  std::lock_guard lock(mutex_);
699 
700  // Remember the ledger sequence of this update.
701  lastUpdateSeq_ = ledgerSeq;
702 
703  // Since we have the whole list in `majority`, reset the time flag, even
704  // if it's currently set. If it's not set when the loop is done, then any
705  // prior unknown amendments have lost majority.
707  for (auto const& [hash, time] : majority)
708  {
709  AmendmentState& s = add(hash, lock);
710 
711  if (s.enabled)
712  continue;
713 
714  if (!s.supported)
715  {
716  JLOG(j_.info()) << "Unsupported amendment " << hash
717  << " reached majority at " << to_string(time);
720  }
721  }
724 }
725 
726 void
728  Json::Value& v,
729  const uint256& id,
730  const AmendmentState& fs,
731  std::lock_guard<std::mutex> const&) const
732 {
733  if (!fs.name.empty())
734  v[jss::name] = fs.name;
735 
736  v[jss::supported] = fs.supported;
737  v[jss::vetoed] = fs.vote == AmendmentVote::down;
738  v[jss::enabled] = fs.enabled;
739 
740  if (!fs.enabled && lastVote_)
741  {
742  auto const votesTotal = lastVote_->trustedValidations();
743  auto const votesNeeded = lastVote_->threshold();
744  auto const votesFor = lastVote_->votes(id);
745 
746  v[jss::count] = votesFor;
747  v[jss::validations] = votesTotal;
748 
749  if (votesNeeded)
750  v[jss::threshold] = votesNeeded;
751  }
752 }
753 
756 {
758  {
759  std::lock_guard lock(mutex_);
760  for (auto const& e : amendmentMap_)
761  {
762  injectJson(
763  ret[to_string(e.first)] = Json::objectValue,
764  e.first,
765  e.second,
766  lock);
767  }
768  }
769  return ret;
770 }
771 
773 AmendmentTableImpl::getJson(uint256 const& amendmentID) const
774 {
776  Json::Value& jAmendment = (ret[to_string(amendmentID)] = Json::objectValue);
777 
778  {
779  std::lock_guard lock(mutex_);
780  AmendmentState const* a = get(amendmentID, lock);
781  if (a)
782  injectJson(jAmendment, amendmentID, *a, lock);
783  }
784 
785  return ret;
786 }
787 
790  Application& app,
791  std::chrono::seconds majorityTime,
793  Section const& enabled,
794  Section const& vetoed,
795  beast::Journal journal)
796 {
797  return std::make_unique<AmendmentTableImpl>(
798  app, majorityTime, supported, enabled, vetoed, journal);
799 }
800 
801 } // namespace ripple
ripple::Section
Holds a collection of configuration values.
Definition: BasicConfig.h:42
ripple::Application
Definition: Application.h:115
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::AmendmentVote::up
@ up
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:601
std::pair
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:574
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:473
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:510
ripple::AmendmentState::vote
AmendmentVote vote
If an amendment is down-voted, a server will not vote to enable it.
Definition: AmendmentTable.cpp:77
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::AmendmentVote::down
@ down
ripple::base_uint
Integers of any length that is a multiple of 32-bits.
Definition: base_uint.h:75
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::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:567
ripple::DefaultVote::yes
@ yes
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
ripple::AmendmentTableImpl::AmendmentTableImpl
AmendmentTableImpl(Application &app, std::chrono::seconds majorityTime, std::vector< FeatureInfo > const &supported, Section const &enabled, Section const &vetoed, beast::Journal journal)
Definition: AmendmentTable.cpp:314
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:608
ripple::readAmendments
void readAmendments(soci::session &session, std::function< void(boost::optional< std::string > amendment_hash, boost::optional< std::string > amendment_name, boost::optional< AmendmentVote > vote)> const &callback)
readAmendments Read all amendments from FeatureVotes table.
Definition: RelationalDBInterface_global.cpp:256
ripple::AmendmentSet::rules_
Rules const & rules_
Definition: AmendmentTable.cpp:101
ripple::AmendmentTableImpl::get
AmendmentState * get(uint256 const &amendment, std::lock_guard< std::mutex > const &lock)
Definition: AmendmentTable.cpp:449
ripple::AmendmentTableImpl::isSupported
bool isSupported(uint256 const &amendment) const override
Definition: AmendmentTable.cpp:552
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::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:497
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::injectJson
void injectJson(Json::Value &v, uint256 const &amendment, AmendmentState const &state, std::lock_guard< std::mutex > const &lock) const
Definition: AmendmentTable.cpp:727
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::voteAmendment
void voteAmendment(soci::session &session, uint256 const &amendment, std::string const &name, AmendmentVote vote)
voteAmendment Set veto value for particular amendment.
Definition: RelationalDBInterface_global.cpp:289
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:755
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
ripple::AmendmentVote
AmendmentVote
Definition: RelationalDBInterface_global.h:137
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
ripple::make_AmendmentTable
std::unique_ptr< AmendmentTable > make_AmendmentTable(Application &app, std::chrono::seconds majorityTime, std::vector< AmendmentTable::FeatureInfo > const &supported, Section const &enabled, Section const &vetoed, beast::Journal journal)
Definition: AmendmentTable.cpp:789
std::make_pair
T make_pair(T... args)
std::map::end
T end(T... args)
ripple::AmendmentTableImpl::add
AmendmentState & add(uint256 const &amendment, std::lock_guard< std::mutex > const &lock)
Definition: AmendmentTable.cpp:440
ripple::AmendmentSet::trustedValidations
int trustedValidations() const
Definition: AmendmentTable.cpp:178
ripple::AmendmentTableImpl::isEnabled
bool isEnabled(uint256 const &amendment) const override
Definition: AmendmentTable.cpp:544
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:475
ripple::AmendmentTableImpl::j_
const beast::Journal j_
Definition: AmendmentTable.cpp:221
ripple::AmendmentTable
The amendment table stores the list of enabled and potential amendments.
Definition: AmendmentTable.h:37
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:679
ripple::AmendmentSet::votes
int votes(uint256 const &amendment) const
Definition: AmendmentTable.cpp:167
std::unique_ptr
STL class.
std::unordered_map
STL class.
ripple::AmendmentTableImpl::persistVote
void persistVote(uint256 const &amendment, std::string const &name, AmendmentVote vote) const
Definition: AmendmentTable.cpp:487
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:690
ripple::AmendmentTableImpl::enable
bool enable(uint256 const &amendment) override
Definition: AmendmentTable.cpp:523
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::sfAmendments
const SF_VECTOR256 sfAmendments
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:560