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/STValidation.h>
25 #include <ripple/protocol/TxFlags.h>
26 #include <ripple/protocol/jss.h>
27 #include <boost/format.hpp>
28 #include <boost/regex.hpp>
37 static boost::regex
const re1(
40 "([abcdefABCDEF0-9]{64})"
44 boost::regex_constants::optimize);
48 for (
auto const& line : section.
lines())
52 if (!boost::regex_match(line, match, re1))
53 Throw<std::runtime_error>(
54 "Invalid entry '" + line +
"' in [" + section.
name() +
"]");
58 if (!
id.SetHexExact(match[1]))
59 Throw<std::runtime_error>(
60 "Invalid amendment ID '" + match[1] +
"' in [" +
61 section.
name() +
"]");
115 for (
auto const& amendment : amendments)
122 auto const& it =
votes_.find(amendment);
190 int majorityFraction,
215 boost::optional<NetClock::time_point>
250 int majorityFraction,
256 , majorityTime_(majorityTime)
257 , majorityFraction_(majorityFraction)
258 , unsupportedEnabled_(false)
267 if (
auto s =
add(a.first, sl))
269 JLOG(
j_.
debug()) <<
"Amendment " << a.first <<
" is supported.";
271 if (!a.second.empty())
280 if (
auto s =
add(a.first, sl))
282 JLOG(
j_.
debug()) <<
"Amendment " << a.first <<
" is enabled.";
284 if (!a.second.empty())
295 if (
auto s =
get(a.first, sl))
297 JLOG(
j_.
info()) <<
"Amendment " << a.first <<
" is vetoed.";
299 if (!a.second.empty())
347 if (name == e.second.name)
358 auto s =
add(amendment, sl);
370 auto s =
get(amendment, sl);
372 if (!s || !s->vetoed)
382 auto s =
add(amendment, sl);
391 JLOG(
j_.
error()) <<
"Unsupported amendment " << amendment
403 auto s =
get(amendment, sl);
404 return s && s->enabled;
411 auto s =
get(amendment, sl);
412 return s && s->supported;
422 boost::optional<NetClock::time_point>
441 if (e.second.supported && !e.second.vetoed &&
442 (enabled.
count(e.first) == 0))
444 amendments.push_back(e.first);
449 if (!amendments.empty())
450 std::sort(amendments.begin(), amendments.end());
470 <<
": " << enabledAmendments.
size() <<
", "
471 << majorityAmendments.
size() <<
", " << valSet.size();
473 auto vote = std::make_unique<AmendmentSet>();
476 for (
auto const& val : valSet)
478 if (val->isTrusted())
485 ballot.
insert(choices.begin(), choices.end());
495 JLOG(
j_.
debug()) <<
"Received " << vote->mTrustedValidations
496 <<
" trusted validations, threshold is: "
510 bool const hasValMajority =
511 (vote->votes(entry.first) >= vote->mThreshold);
514 auto const it = majorityAmendments.
find(entry.first);
515 if (it != majorityAmendments.
end())
516 majorityTime = it->second;
519 if (enabledAmendments.
count(entry.first) != 0)
521 JLOG(
j_.
debug()) << entry.first <<
": amendment already enabled";
525 !entry.second.vetoed)
528 JLOG(
j_.
debug()) << entry.first <<
": amendment got majority";
534 JLOG(
j_.
debug()) << entry.first <<
": amendment lost majority";
540 !entry.second.vetoed)
543 JLOG(
j_.
debug()) << entry.first <<
": amendment majority held";
544 actions[entry.first] = 0;
570 for (
auto& e : enabled)
582 for (
auto const& [hash, time] : majority)
584 auto s =
add(hash, sl);
591 JLOG(
j_.
info()) <<
"Unsupported amendment " << hash
592 <<
" reached majority at " <<
to_string(time);
609 v[jss::name] = fs.
name;
612 v[jss::vetoed] = fs.
vetoed;
617 auto const votesTotal =
lastVote_->mTrustedValidations;
618 auto const votesNeeded =
lastVote_->mThreshold;
619 auto const votesFor =
lastVote_->votes(
id);
621 v[jss::count] = votesFor;
622 v[jss::validations] = votesTotal;
626 v[jss::vote] = votesFor * 256 / votesNeeded;
627 v[jss::threshold] = votesNeeded;
658 auto a =
get(amendmentID, sl);
669 int majorityFraction,
675 return std::make_unique<AmendmentTableImpl>(
676 majorityTime, majorityFraction, supported, enabled, vetoed, journal);
Holds a collection of configuration values.
std::map< uint256, std::uint32_t > doVoting(NetClock::time_point closeTime, std::set< uint256 > const &enabledAmendments, majorityAmendments_t const &majorityAmendments, std::vector< std::shared_ptr< STValidation >> const &validations) override
bool supported
Indicates an amendment that this server has code support for.
std::uint32_t lastUpdateSeq_
Current state of an amendment.
boost::optional< NetClock::time_point > firstUnsupportedExpected_
Stream trace() const
Severity stream access functions.
std::vector< uint256 > getDesired() const override
std::vector< uint256 > doValidation(std::set< uint256 > const &enabledAmendments) const override
std::unique_ptr< AmendmentTable > make_AmendmentTable(std::chrono::seconds majorityTime, int majorityFraction, Section const &supported, Section const &enabled, Section const &vetoed, beast::Journal journal)
uint256 find(std::string const &name) const override
bool vetoed
If an amendment is vetoed, a server will not support it.
bool unVeto(uint256 const &amendment) override
boost::optional< NetClock::time_point > firstUnsupportedExpected() const override
void tally(std::set< uint256 > const &amendments)
std::string to_string(ListDisposition disposition)
const std::uint32_t tfLostMajority
const std::uint32_t tfGotMajority
Track the list of "amendments".
static std::vector< std::pair< uint256, std::string > > parseSection(Section const §ion)
hash_map< uint256, int > votes_
std::string const & name() const
Returns the name of this section.
T time_since_epoch(T... args)
const int majorityFraction_
@ objectValue
object value (collection of name/value pairs).
int votes(uint256 const &amendment) const
bool isSupported(uint256 const &amendment) const override
std::vector< std::string > const & lines() const
Returns all the lines in the section.
A generic endpoint for log messages.
AmendmentTableImpl(std::chrono::seconds majorityTime, int majorityFraction, Section const &supported, Section const &enabled, Section const &vetoed, beast::Journal journal)
bool veto(uint256 const &amendment) override
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
hash_map< uint256, AmendmentState > amendmentMap_
std::unique_ptr< AmendmentSet > lastVote_
const std::chrono::seconds majorityTime_
bool enabled
Indicates that the amendment has been enabled.
Json::Value getJson() const override
std::string name
The name of this amendment, possibly empty.
const SF_Vec256 sfAmendments(access, STI_VECTOR256, 3, "Amendments")
bool isEnabled(uint256 const &amendment) const override
void injectJson(Json::Value &v, uint256 const &amendment, AmendmentState const &state, std::lock_guard< std::mutex > const &sl) const
AmendmentState * add(uint256 const &amendment, std::lock_guard< std::mutex > const &sl)
The status of all amendments requested in a given window.
The amendment table stores the list of enabled and potential amendments.
bool needValidatedLedger(LedgerIndex seq) const override
Called to determine whether the amendment logic needs to process a new validated ledger.
void doValidatedLedger(LedgerIndex seq, std::set< uint256 > const &enabled, majorityAmendments_t const &majority) override
bool enable(uint256 const &amendment) override
AmendmentState * get(uint256 const &amendment, std::lock_guard< std::mutex > const &sl)
bool hasUnsupportedEnabled() const override
returns true if one or more amendments on the network have been enabled that this server does not sup...