20 #include <ripple/app/misc/AmendmentTable.h>
21 #include <ripple/basics/BasicConfig.h>
22 #include <ripple/basics/Log.h>
23 #include <ripple/basics/chrono.h>
24 #include <ripple/beast/unit_test.h>
25 #include <ripple/core/ConfigSections.h>
26 #include <ripple/protocol/Feature.h>
27 #include <ripple/protocol/PublicKey.h>
28 #include <ripple/protocol/STValidation.h>
29 #include <ripple/protocol/SecretKey.h>
30 #include <ripple/protocol/TxFlags.h>
31 #include <ripple/protocol/digest.h>
32 #include <ripple/protocol/jss.h>
33 #include <test/jtx/Env.h>
34 #include <test/unit_test/SuiteJournal.h>
59 for (
auto const& a : amendments)
82 cfg->section(SECTION_AMENDMENTS) =
84 cfg->section(SECTION_VETO_AMENDMENTS) =
94 "a",
"b",
"c",
"d",
"e",
"f",
"g",
"h",
"i",
"j",
"k",
95 "l",
"m",
"n",
"o",
"p",
"q",
"r",
"s",
"t",
"u"};
97 enabled_{
"b",
"d",
"f",
"h",
"j",
"l",
"n",
"p"};
120 app, majorityTime, supported, enabled, vetoed,
journal);
131 return makeTable(env.
app(), majorityTime, supported, enabled, vetoed);
148 testcase(
"Construction");
172 testcase(
"Name to ID mapping");
185 BEAST_EXPECT(!table->find(a));
187 BEAST_EXPECT(!table->find(a));
194 table->getJson(unsupportedID)[
to_string(unsupportedID)];
195 BEAST_EXPECT(unsupp.
size() == 0);
199 table->veto(unsupportedID);
202 table->getJson(unsupportedID)[
to_string(unsupportedID)];
203 BEAST_EXPECT(unsupp[jss::vetoed].asBool());
213 testcase(
"Bad Config");
223 fail(
"Accepted only amendment ID");
233 test.
append(
id +
" Test Name");
239 fail(
"Accepted extra arguments");
249 sid.resize(sid.length() - 1);
252 test.
append(sid +
" Name");
258 fail(
"Accepted short amendment ID");
268 sid.resize(sid.length() + 1,
'0');
271 test.
append(sid +
" Name");
277 fail(
"Accepted long amendment ID");
287 sid.resize(sid.length() - 1);
291 test.
append(sid +
" Name");
297 fail(
"Accepted non-hex amendment ID");
309 testcase(
"enable and veto");
322 for (
uint256 const& a : allEnabled)
326 BEAST_EXPECT(!table->hasUnsupportedEnabled());
333 table->isEnabled(supportedID) ==
334 (allEnabled.find(supportedID) != allEnabled.end()));
344 for (
uint256 const& a : desired)
345 BEAST_EXPECT(vetoed.
count(a) == 0);
351 BEAST_EXPECT(desired == table->getDesired());
357 table->unVeto(unvetoedID);
370 BEAST_EXPECT(table->getDesired().empty());
374 BEAST_EXPECT(!table->hasUnsupportedEnabled());
376 BEAST_EXPECT(table->hasUnsupportedEnabled());
385 for (
int i = 0; i < num; ++i)
421 auto const roundTime =
weekTime(week);
425 validations.
reserve(validators.size());
428 for (
auto const& [pub, sec] : validators)
433 for (
auto const& [hash, nVotes] : votes)
438 field.push_back(hash);
442 auto v = std::make_shared<STValidation>(
460 Rules({feat}), roundTime, enabled, majority, validations);
461 for (
auto const& [hash, action] : actions)
469 if (enabled.
find(hash) != enabled.
end())
470 Throw<std::runtime_error>(
"enabling already enabled");
471 if (majority.
find(hash) == majority.
end())
472 Throw<std::runtime_error>(
"enabling without majority");
474 majority.
erase(hash);
478 if (majority.
find(hash) != majority.
end())
479 Throw<std::runtime_error>(
480 "got majority while having majority");
481 majority[hash] = roundTime;
485 if (majority.
find(hash) == majority.
end())
486 Throw<std::runtime_error>(
487 "lost majority without majority");
488 majority.
erase(hash);
492 Throw<std::runtime_error>(
"unknown action");
501 testcase(
"Vote NO on unknown");
503 auto const testAmendment =
amendmentId(
"TestAmendment");
524 BEAST_EXPECT(ourVotes.empty());
525 BEAST_EXPECT(enabled.empty());
526 BEAST_EXPECT(majority.
empty());
528 votes.emplace_back(testAmendment, validators.size());
539 BEAST_EXPECT(ourVotes.empty());
540 BEAST_EXPECT(enabled.empty());
555 BEAST_EXPECT(ourVotes.empty());
556 BEAST_EXPECT(enabled.empty());
563 testcase(
"Vote NO on vetoed");
565 auto const testAmendment =
amendmentId(
"vetoedAmendment");
591 BEAST_EXPECT(ourVotes.empty());
592 BEAST_EXPECT(enabled.empty());
593 BEAST_EXPECT(majority.
empty());
595 votes.emplace_back(testAmendment, validators.size());
606 BEAST_EXPECT(ourVotes.empty());
607 BEAST_EXPECT(enabled.empty());
620 BEAST_EXPECT(ourVotes.empty());
621 BEAST_EXPECT(enabled.empty());
628 testcase(
"voteEnable");
651 BEAST_EXPECT(enabled.empty());
670 BEAST_EXPECT(enabled.empty());
698 BEAST_EXPECT(ourVotes.empty());
707 testcase(
"detectMajority");
709 auto const testAmendment =
amendmentId(
"detectMajority");
723 for (
int i = 0; i <= 17; ++i)
728 if ((i > 0) && (i < 17))
744 BEAST_EXPECT(!ourVotes.empty());
745 BEAST_EXPECT(enabled.empty());
746 BEAST_EXPECT(majority.
empty());
751 BEAST_EXPECT(!ourVotes.empty());
752 BEAST_EXPECT(!majority.
empty());
753 BEAST_EXPECT(enabled.empty());
758 BEAST_EXPECT(!ourVotes.empty());
759 BEAST_EXPECT(majority.
empty());
760 BEAST_EXPECT(!enabled.empty());
765 BEAST_EXPECT(ourVotes.empty());
766 BEAST_EXPECT(majority.
empty());
767 BEAST_EXPECT(!enabled.empty());
776 testcase(
"lostMajority");
778 auto const testAmendment =
amendmentId(
"lostMajority");
809 BEAST_EXPECT(enabled.empty());
810 BEAST_EXPECT(!majority.
empty());
813 for (
int i = 1; i < 8; ++i)
819 votes.
emplace_back(testAmendment, validators.size() - i);
834 BEAST_EXPECT(!ourVotes.empty());
835 BEAST_EXPECT(enabled.empty());
836 BEAST_EXPECT(!majority.
empty());
841 BEAST_EXPECT(!ourVotes.empty());
842 BEAST_EXPECT(majority.
empty());
843 BEAST_EXPECT(enabled.empty());
851 testcase(
"hasUnsupportedEnabled");
853 using namespace std::chrono_literals;
854 weeks constexpr w(1);
857 BEAST_EXPECT(!table->hasUnsupportedEnabled());
858 BEAST_EXPECT(!table->firstUnsupportedExpected());
859 BEAST_EXPECT(table->needValidatedLedger(1));
865 [&enabled](
auto const& s) { enabled.insert(amendmentId(s)); });
868 table->doValidatedLedger(1, enabled, majority);
869 BEAST_EXPECT(table->hasUnsupportedEnabled());
870 BEAST_EXPECT(!table->firstUnsupportedExpected());
876 [&majority, &t](
auto const& s) {
877 majority[amendmentId(s)] = NetClock::time_point{--t};
880 table->doValidatedLedger(1, enabled, majority);
881 BEAST_EXPECT(table->hasUnsupportedEnabled());
883 table->firstUnsupportedExpected() &&
887 BEAST_EXPECT(!table->needValidatedLedger(256));
888 BEAST_EXPECT(table->needValidatedLedger(257));