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.SetHexExact(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  // Finds or creates state. Must be called with mutex_ locked.
225  add(uint256 const& amendment, std::lock_guard<std::mutex> const& sl);
226 
227  // Finds existing state. Must be called with mutex_ locked.
229  get(uint256 const& amendment, std::lock_guard<std::mutex> const& sl);
230 
231  AmendmentState const*
232  get(uint256 const& amendment, std::lock_guard<std::mutex> const& sl) const;
233 
234  // Injects amendment json into v. Must be called with mutex_ locked.
235  void
236  injectJson(
237  Json::Value& v,
238  uint256 const& amendment,
239  AmendmentState const& state,
240  std::lock_guard<std::mutex> const& sl) const;
241 
242 public:
244  std::chrono::seconds majorityTime,
245  Section const& supported,
246  Section const& enabled,
247  Section const& vetoed,
248  beast::Journal journal);
249 
250  uint256
251  find(std::string const& name) const override;
252 
253  bool
254  veto(uint256 const& amendment) override;
255  bool
256  unVeto(uint256 const& amendment) override;
257 
258  bool
259  enable(uint256 const& amendment) override;
260 
261  bool
262  isEnabled(uint256 const& amendment) const override;
263  bool
264  isSupported(uint256 const& amendment) const override;
265 
266  bool
267  hasUnsupportedEnabled() const override;
268 
269  boost::optional<NetClock::time_point>
270  firstUnsupportedExpected() const override;
271 
273  getJson() const override;
275  getJson(uint256 const&) const override;
276 
277  bool
278  needValidatedLedger(LedgerIndex seq) const override;
279 
280  void
282  LedgerIndex seq,
283  std::set<uint256> const& enabled,
284  majorityAmendments_t const& majority) override;
285 
287  doValidation(std::set<uint256> const& enabledAmendments) const override;
288 
290  getDesired() const override;
291 
293  doVoting(
294  Rules const& rules,
295  NetClock::time_point closeTime,
296  std::set<uint256> const& enabledAmendments,
297  majorityAmendments_t const& majorityAmendments,
298  std::vector<std::shared_ptr<STValidation>> const& validations) override;
299 };
300 
301 //------------------------------------------------------------------------------
302 
304  std::chrono::seconds majorityTime,
305  Section const& supported,
306  Section const& enabled,
307  Section const& vetoed,
308  beast::Journal journal)
309  : lastUpdateSeq_(0)
310  , majorityTime_(majorityTime)
311  , unsupportedEnabled_(false)
312  , j_(journal)
313 {
315 
316  for (auto const& a : parseSection(supported))
317  {
318  if (auto s = add(a.first, sl))
319  {
320  JLOG(j_.debug()) << "Amendment " << a.first << " is supported.";
321 
322  if (!a.second.empty())
323  s->name = a.second;
324 
325  s->supported = true;
326  }
327  }
328 
329  for (auto const& a : parseSection(enabled))
330  {
331  if (auto s = add(a.first, sl))
332  {
333  JLOG(j_.debug()) << "Amendment " << a.first << " is enabled.";
334 
335  if (!a.second.empty())
336  s->name = a.second;
337 
338  s->supported = true;
339  s->enabled = true;
340  }
341  }
342 
343  for (auto const& a : parseSection(vetoed))
344  {
345  // Unknown amendments are effectively vetoed already
346  if (auto s = get(a.first, sl))
347  {
348  JLOG(j_.info()) << "Amendment " << a.first << " is vetoed.";
349 
350  if (!a.second.empty())
351  s->name = a.second;
352 
353  s->vetoed = true;
354  }
355  }
356 }
357 
360  uint256 const& amendmentHash,
362 {
363  // call with the mutex held
364  return &amendmentMap_[amendmentHash];
365 }
366 
369  uint256 const& amendmentHash,
370  std::lock_guard<std::mutex> const& sl)
371 {
372  // Forward to the const version of get.
373  return const_cast<AmendmentState*>(
374  std::as_const(*this).get(amendmentHash, sl));
375 }
376 
377 AmendmentState const*
379  uint256 const& amendmentHash,
380  std::lock_guard<std::mutex> const&) const
381 {
382  // call with the mutex held
383  auto ret = amendmentMap_.find(amendmentHash);
384 
385  if (ret == amendmentMap_.end())
386  return nullptr;
387 
388  return &ret->second;
389 }
390 
391 uint256
393 {
395 
396  for (auto const& e : amendmentMap_)
397  {
398  if (name == e.second.name)
399  return e.first;
400  }
401 
402  return {};
403 }
404 
405 bool
407 {
409  auto s = add(amendment, sl);
410 
411  if (s->vetoed)
412  return false;
413  s->vetoed = true;
414  return true;
415 }
416 
417 bool
419 {
421  auto s = get(amendment, sl);
422 
423  if (!s || !s->vetoed)
424  return false;
425  s->vetoed = false;
426  return true;
427 }
428 
429 bool
431 {
433  auto s = add(amendment, sl);
434 
435  if (s->enabled)
436  return false;
437 
438  s->enabled = true;
439 
440  if (!s->supported)
441  {
442  JLOG(j_.error()) << "Unsupported amendment " << amendment
443  << " activated.";
444  unsupportedEnabled_ = true;
445  }
446 
447  return true;
448 }
449 
450 bool
451 AmendmentTableImpl::isEnabled(uint256 const& amendment) const
452 {
454  auto s = get(amendment, sl);
455  return s && s->enabled;
456 }
457 
458 bool
460 {
462  auto s = get(amendment, sl);
463  return s && s->supported;
464 }
465 
466 bool
468 {
470  return unsupportedEnabled_;
471 }
472 
473 boost::optional<NetClock::time_point>
475 {
478 }
479 
482 {
483  // Get the list of amendments we support and do not
484  // veto, but that are not already enabled
485  std::vector<uint256> amendments;
486 
487  {
489  amendments.reserve(amendmentMap_.size());
490  for (auto const& e : amendmentMap_)
491  {
492  if (e.second.supported && !e.second.vetoed &&
493  (enabled.count(e.first) == 0))
494  {
495  amendments.push_back(e.first);
496  }
497  }
498  }
499 
500  if (!amendments.empty())
501  std::sort(amendments.begin(), amendments.end());
502 
503  return amendments;
504 }
505 
508 {
509  // Get the list of amendments we support and do not veto
510  return doValidation({});
511 }
512 
515  Rules const& rules,
516  NetClock::time_point closeTime,
517  std::set<uint256> const& enabledAmendments,
518  majorityAmendments_t const& majorityAmendments,
520 {
521  JLOG(j_.trace()) << "voting at " << closeTime.time_since_epoch().count()
522  << ": " << enabledAmendments.size() << ", "
523  << majorityAmendments.size() << ", " << valSet.size();
524 
525  auto vote = std::make_unique<AmendmentSet>(rules, valSet);
526 
527  JLOG(j_.debug()) << "Received " << vote->trustedValidations()
528  << " trusted validations, threshold is: "
529  << vote->threshold();
530 
531  // Map of amendments to the action to be taken for each one. The action is
532  // the value of the flags in the pseudo-transaction
534 
536 
537  // process all amendments we know of
538  for (auto const& entry : amendmentMap_)
539  {
540  NetClock::time_point majorityTime = {};
541 
542  bool const hasValMajority = vote->passes(entry.first);
543 
544  {
545  auto const it = majorityAmendments.find(entry.first);
546  if (it != majorityAmendments.end())
547  majorityTime = it->second;
548  }
549 
550  if (enabledAmendments.count(entry.first) != 0)
551  {
552  JLOG(j_.debug()) << entry.first << ": amendment already enabled";
553  }
554  else if (
555  hasValMajority && (majorityTime == NetClock::time_point{}) &&
556  !entry.second.vetoed)
557  {
558  // Ledger says no majority, validators say yes
559  JLOG(j_.debug()) << entry.first << ": amendment got majority";
560  actions[entry.first] = tfGotMajority;
561  }
562  else if (!hasValMajority && (majorityTime != NetClock::time_point{}))
563  {
564  // Ledger says majority, validators say no
565  JLOG(j_.debug()) << entry.first << ": amendment lost majority";
566  actions[entry.first] = tfLostMajority;
567  }
568  else if (
569  (majorityTime != NetClock::time_point{}) &&
570  ((majorityTime + majorityTime_) <= closeTime) &&
571  !entry.second.vetoed)
572  {
573  // Ledger says majority held
574  JLOG(j_.debug()) << entry.first << ": amendment majority held";
575  actions[entry.first] = 0;
576  }
577  }
578 
579  // Stash for reporting
580  lastVote_ = std::move(vote);
581  return actions;
582 }
583 
584 bool
586 {
588 
589  // Is there a ledger in which an amendment could have been enabled
590  // between these two ledger sequences?
591 
592  return ((ledgerSeq - 1) / 256) != ((lastUpdateSeq_ - 1) / 256);
593 }
594 
595 void
597  LedgerIndex ledgerSeq,
598  std::set<uint256> const& enabled,
599  majorityAmendments_t const& majority)
600 {
601  for (auto& e : enabled)
602  enable(e);
603 
605 
606  // Remember the ledger sequence of this update.
607  lastUpdateSeq_ = ledgerSeq;
608 
609  // Since we have the whole list in `majority`, reset the time flag, even
610  // if it's currently set. If it's not set when the loop is done, then any
611  // prior unknown amendments have lost majority.
613  for (auto const& [hash, time] : majority)
614  {
615  auto s = add(hash, sl);
616 
617  if (s->enabled)
618  continue;
619 
620  if (!s->supported)
621  {
622  JLOG(j_.info()) << "Unsupported amendment " << hash
623  << " reached majority at " << to_string(time);
626  }
627  }
630 }
631 
632 void
634  Json::Value& v,
635  const uint256& id,
636  const AmendmentState& fs,
637  std::lock_guard<std::mutex> const&) const
638 {
639  if (!fs.name.empty())
640  v[jss::name] = fs.name;
641 
642  v[jss::supported] = fs.supported;
643  v[jss::vetoed] = fs.vetoed;
644  v[jss::enabled] = fs.enabled;
645 
646  if (!fs.enabled && lastVote_)
647  {
648  auto const votesTotal = lastVote_->trustedValidations();
649  auto const votesNeeded = lastVote_->threshold();
650  auto const votesFor = lastVote_->votes(id);
651 
652  v[jss::count] = votesFor;
653  v[jss::validations] = votesTotal;
654 
655  if (votesNeeded)
656  v[jss::threshold] = votesNeeded;
657  }
658 }
659 
662 {
664  {
666  for (auto const& e : amendmentMap_)
667  {
668  injectJson(
669  ret[to_string(e.first)] = Json::objectValue,
670  e.first,
671  e.second,
672  sl);
673  }
674  }
675  return ret;
676 }
677 
679 AmendmentTableImpl::getJson(uint256 const& amendmentID) const
680 {
682  Json::Value& jAmendment = (ret[to_string(amendmentID)] = Json::objectValue);
683 
684  {
686  auto a = get(amendmentID, sl);
687  if (a)
688  injectJson(jAmendment, amendmentID, *a, sl);
689  }
690 
691  return ret;
692 }
693 
696  std::chrono::seconds majorityTime,
697  Section const& supported,
698  Section const& enabled,
699  Section const& vetoed,
700  beast::Journal journal)
701 {
702  return std::make_unique<AmendmentTableImpl>(
703  majorityTime, supported, enabled, vetoed, journal);
704 }
705 
706 } // namespace ripple
ripple::Section
Holds a collection of configuration values.
Definition: BasicConfig.h:43
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
ripple::AmendmentTableImpl::getDesired
std::vector< uint256 > getDesired() const override
Definition: AmendmentTable.cpp:507
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:481
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:392
ripple::AmendmentState::vetoed
bool vetoed
If an amendment is vetoed, a server will not support it.
Definition: AmendmentTable.cpp:77
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:418
ripple::AmendmentTableImpl::firstUnsupportedExpected
boost::optional< NetClock::time_point > firstUnsupportedExpected() const override
Definition: AmendmentTable.cpp:474
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< 256 >
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::AmendmentSet::threshold
int threshold() const
Definition: AmendmentTable.cpp:184
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:188
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:514
ripple::AmendmentSet::rules_
Rules const & rules_
Definition: AmendmentTable.cpp:101
ripple::make_AmendmentTable
std::unique_ptr< AmendmentTable > make_AmendmentTable(std::chrono::seconds majorityTime, Section const &supported, Section const &enabled, Section const &vetoed, beast::Journal journal)
Definition: AmendmentTable.cpp:695
ripple::AmendmentTableImpl::isSupported
bool isSupported(uint256 const &amendment) const override
Definition: AmendmentTable.cpp:459
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: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:406
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::AmendmentTableImpl
AmendmentTableImpl(std::chrono::seconds majorityTime, Section const &supported, Section const &enabled, Section const &vetoed, beast::Journal journal)
Definition: AmendmentTable.cpp:303
ripple::AmendmentTableImpl::amendmentMap_
hash_map< uint256, AmendmentState > amendmentMap_
Definition: AmendmentTable.cpp:203
ripple::AmendmentTableImpl::lastVote_
std::unique_ptr< AmendmentSet > lastVote_
Definition: AmendmentTable.cpp:211
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:661
ripple::AmendmentState::name
std::string name
The name of this amendment, possibly empty.
Definition: AmendmentTable.cpp:90
std::set::count
T count(T... args)
std::string::empty
T empty(T... args)
ripple::Rules
Rules controlling protocol behavior.
Definition: ReadView.h:127
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::sfAmendments
const SF_Vec256 sfAmendments(access, STI_VECTOR256, 3, "Amendments")
Definition: SField.h:495
ripple::AmendmentTableImpl::isEnabled
bool isEnabled(uint256 const &amendment) const override
Definition: AmendmentTable.cpp:451
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:633
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:359
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:585
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:596
ripple::AmendmentTableImpl::enable
bool enable(uint256 const &amendment) override
Definition: AmendmentTable.cpp:430
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::AmendmentTableImpl::get
AmendmentState * get(uint256 const &amendment, std::lock_guard< std::mutex > const &sl)
Definition: AmendmentTable.cpp:368
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:467