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) =
93 result.
reserve(amendments.size());
94 for (
auto const& a : amendments)
114 "a",
"b",
"c",
"d",
"e",
"f",
"g",
"h",
"i",
"j",
"k",
115 "l",
"m",
"n",
"o",
"p",
"q",
"r",
"s",
"t",
"u"};
141 app, majorityTime, supported, enabled, vetoed,
journal);
152 return makeTable(env.
app(), majorityTime, supported, enabled, vetoed);
169 testcase(
"Construction");
193 testcase(
"Name to ID mapping");
206 BEAST_EXPECT(!table->find(a));
208 BEAST_EXPECT(!table->find(a));
215 table->getJson(unsupportedID)[
to_string(unsupportedID)];
216 BEAST_EXPECT(unsupp.
size() == 0);
220 table->veto(unsupportedID);
223 table->getJson(unsupportedID)[
to_string(unsupportedID)];
224 BEAST_EXPECT(unsupp[jss::vetoed].asBool());
235 testcase(
"Bad Config");
245 fail(
"Accepted only amendment ID");
250 e.
what() ==
"Invalid entry '" +
id +
"' in [Test]");
256 test.
append(
id +
" Test Name");
262 fail(
"Accepted extra arguments");
268 "Invalid entry '" +
id +
" Test Name' in [Test]");
274 sid.resize(sid.length() - 1);
277 test.
append(sid +
" Name");
283 fail(
"Accepted short amendment ID");
288 e.
what() ==
"Invalid entry '" + sid +
" Name' in [Test]");
294 sid.resize(sid.length() + 1,
'0');
297 test.
append(sid +
" Name");
303 fail(
"Accepted long amendment ID");
308 e.
what() ==
"Invalid entry '" + sid +
" Name' in [Test]");
314 sid.resize(sid.length() - 1);
318 test.
append(sid +
" Name");
324 fail(
"Accepted non-hex amendment ID");
329 e.
what() ==
"Invalid entry '" + sid +
" Name' in [Test]");
337 testcase(
"enable and veto");
347 for (
uint256 const& a : allEnabled)
348 BEAST_EXPECT(table->enable(a));
351 BEAST_EXPECT(!table->hasUnsupportedEnabled());
357 bool const enabled = table->isEnabled(supportedID);
358 bool const found = allEnabled.find(supportedID) != allEnabled.end();
361 a + (enabled ?
" enabled " :
" disabled ") +
362 (found ?
" found" :
" not found"));
372 for (
uint256 const& a : desired)
373 BEAST_EXPECT(vetoed.
count(a) == 0);
379 BEAST_EXPECT(desired == table->getDesired());
385 BEAST_EXPECT(table->unVeto(unvetoedID));
398 BEAST_EXPECT(table->getDesired().empty());
402 BEAST_EXPECT(!table->hasUnsupportedEnabled());
404 BEAST_EXPECT(table->hasUnsupportedEnabled());
413 for (
int i = 0; i < num; ++i)
449 auto const roundTime =
weekTime(week);
453 validations.
reserve(validators.size());
456 for (
auto const& [pub, sec] : validators)
461 for (
auto const& [hash, nVotes] : votes)
466 field.push_back(hash);
470 auto v = std::make_shared<STValidation>(
488 Rules({feat}), roundTime, enabled, majority, validations);
489 for (
auto const& [hash, action] : actions)
497 if (enabled.
find(hash) != enabled.
end())
498 Throw<std::runtime_error>(
"enabling already enabled");
499 if (majority.
find(hash) == majority.
end())
500 Throw<std::runtime_error>(
"enabling without majority");
502 majority.
erase(hash);
506 if (majority.
find(hash) != majority.
end())
507 Throw<std::runtime_error>(
508 "got majority while having majority");
509 majority[hash] = roundTime;
513 if (majority.
find(hash) == majority.
end())
514 Throw<std::runtime_error>(
515 "lost majority without majority");
516 majority.
erase(hash);
520 Throw<std::runtime_error>(
"unknown action");
529 testcase(
"Vote NO on unknown");
531 auto const testAmendment =
amendmentId(
"TestAmendment");
552 BEAST_EXPECT(ourVotes.empty());
553 BEAST_EXPECT(enabled.empty());
554 BEAST_EXPECT(majority.
empty());
556 votes.emplace_back(testAmendment, validators.size());
567 BEAST_EXPECT(ourVotes.empty());
568 BEAST_EXPECT(enabled.empty());
583 BEAST_EXPECT(ourVotes.empty());
584 BEAST_EXPECT(enabled.empty());
591 testcase(
"Vote NO on vetoed");
593 auto const testAmendment =
amendmentId(
"vetoedAmendment");
615 BEAST_EXPECT(ourVotes.empty());
616 BEAST_EXPECT(enabled.empty());
617 BEAST_EXPECT(majority.
empty());
619 votes.emplace_back(testAmendment, validators.size());
630 BEAST_EXPECT(ourVotes.empty());
631 BEAST_EXPECT(enabled.empty());
644 BEAST_EXPECT(ourVotes.empty());
645 BEAST_EXPECT(enabled.empty());
652 testcase(
"voteEnable");
679 BEAST_EXPECT(enabled.empty());
698 BEAST_EXPECT(enabled.empty());
726 BEAST_EXPECT(ourVotes.empty());
735 testcase(
"detectMajority");
737 auto const testAmendment =
amendmentId(
"detectMajority");
751 for (
int i = 0; i <= 17; ++i)
756 if ((i > 0) && (i < 17))
772 BEAST_EXPECT(!ourVotes.empty());
773 BEAST_EXPECT(enabled.empty());
774 BEAST_EXPECT(majority.
empty());
779 BEAST_EXPECT(!ourVotes.empty());
780 BEAST_EXPECT(!majority.
empty());
781 BEAST_EXPECT(enabled.empty());
786 BEAST_EXPECT(!ourVotes.empty());
787 BEAST_EXPECT(majority.
empty());
788 BEAST_EXPECT(!enabled.empty());
793 BEAST_EXPECT(ourVotes.empty());
794 BEAST_EXPECT(majority.
empty());
795 BEAST_EXPECT(!enabled.empty());
804 testcase(
"lostMajority");
806 auto const testAmendment =
amendmentId(
"lostMajority");
837 BEAST_EXPECT(enabled.empty());
838 BEAST_EXPECT(!majority.
empty());
841 for (
int i = 1; i < 8; ++i)
847 votes.
emplace_back(testAmendment, validators.size() - i);
862 BEAST_EXPECT(!ourVotes.empty());
863 BEAST_EXPECT(enabled.empty());
864 BEAST_EXPECT(!majority.
empty());
869 BEAST_EXPECT(!ourVotes.empty());
870 BEAST_EXPECT(majority.
empty());
871 BEAST_EXPECT(enabled.empty());
879 testcase(
"hasUnsupportedEnabled");
881 using namespace std::chrono_literals;
882 weeks constexpr w(1);
885 BEAST_EXPECT(!table->hasUnsupportedEnabled());
886 BEAST_EXPECT(!table->firstUnsupportedExpected());
887 BEAST_EXPECT(table->needValidatedLedger(1));
893 [&enabled](
auto const& s) { enabled.insert(amendmentId(s)); });
896 table->doValidatedLedger(1, enabled, majority);
897 BEAST_EXPECT(table->hasUnsupportedEnabled());
898 BEAST_EXPECT(!table->firstUnsupportedExpected());
904 [&majority, &t](
auto const& s) {
905 majority[amendmentId(s)] = NetClock::time_point{--t};
908 table->doValidatedLedger(1, enabled, majority);
909 BEAST_EXPECT(table->hasUnsupportedEnabled());
911 table->firstUnsupportedExpected() &&
915 BEAST_EXPECT(!table->needValidatedLedger(256));
916 BEAST_EXPECT(table->needValidatedLedger(257));