rippled
AmendmentTable_test.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/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>
35 
36 namespace ripple {
37 
38 class AmendmentTable_test final : public beast::unit_test::suite
39 {
40 private:
41  static uint256
43  {
44  sha256_hasher h;
45  using beast::hash_append;
46  hash_append(h, in);
47  auto const d = static_cast<sha256_hasher::result_type>(h);
48  uint256 result;
49  std::memcpy(result.data(), d.data(), d.size());
50  return result;
51  }
52 
53  static Section
55  std::string const& name,
56  std::vector<std::string> const& amendments)
57  {
58  Section section(name);
59  for (auto const& a : amendments)
60  section.append(to_string(amendmentId(a)) + " " + a);
61  return section;
62  }
63 
64  static Section
66  {
67  return makeSection("Test", amendments);
68  }
69 
70  static Section
71  makeSection(uint256 const& amendment)
72  {
73  Section section("Test");
74  section.append(to_string(amendment) + " " + to_string(amendment));
75  return section;
76  }
77 
80  {
81  auto cfg = test::jtx::envconfig();
82  cfg->section(SECTION_AMENDMENTS) =
83  makeSection(SECTION_AMENDMENTS, enabled_);
84  cfg->section(SECTION_VETO_AMENDMENTS) =
85  makeSection(SECTION_VETO_AMENDMENTS, vetoed_);
86  return cfg;
87  }
88 
89  // All useful amendments are supported amendments.
90  // Enabled amendments are typically a subset of supported amendments.
91  // Vetoed amendments should be supported but not enabled.
92  // Unsupported amendments may be added to the AmendmentTable.
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"};
98  std::vector<std::string> const vetoed_{"a", "c", "e"};
99  std::vector<std::string> const unsupported_{"v", "w", "x"};
101 
103 
105 
106 public:
107  AmendmentTable_test() : journal("AmendmentTable_test", *this)
108  {
109  }
110 
113  Application& app,
114  std::chrono::seconds majorityTime,
115  Section const& supported,
116  Section const& enabled,
117  Section const& vetoed)
118  {
119  return make_AmendmentTable(
120  app, majorityTime, supported, enabled, vetoed, journal);
121  }
122 
125  test::jtx::Env& env,
126  std::chrono::seconds majorityTime,
127  Section const& supported,
128  Section const& enabled,
129  Section const& vetoed)
130  {
131  return makeTable(env.app(), majorityTime, supported, enabled, vetoed);
132  }
133 
136  {
137  return makeTable(
138  env.app(),
139  majorityTime,
143  }
144 
145  void
147  {
148  testcase("Construction");
149  test::jtx::Env env{*this, makeConfig()};
150  auto table = makeTable(env, weeks(1));
151 
152  for (auto const& a : supported_)
153  {
154  BEAST_EXPECT(table->isSupported(amendmentId(a)));
155  }
156 
157  for (auto const& a : enabled_)
158  {
159  BEAST_EXPECT(table->isSupported(amendmentId(a)));
160  }
161 
162  for (auto const& a : vetoed_)
163  {
164  BEAST_EXPECT(table->isSupported(amendmentId(a)));
165  BEAST_EXPECT(!table->isEnabled(amendmentId(a)));
166  }
167  }
168 
169  void
171  {
172  testcase("Name to ID mapping");
173 
174  test::jtx::Env env{*this, makeConfig()};
175  auto table = makeTable(env, weeks(1));
176 
177  for (auto const& a : supported_)
178  BEAST_EXPECT(table->find(a) == amendmentId(a));
179  for (auto const& a : enabled_)
180  BEAST_EXPECT(table->find(a) == amendmentId(a));
181 
182  for (auto const& a : vetoed_)
183  BEAST_EXPECT(table->find(a) == amendmentId(a));
184  for (auto const& a : unsupported_)
185  BEAST_EXPECT(!table->find(a));
186  for (auto const& a : unsupportedMajority_)
187  BEAST_EXPECT(!table->find(a));
188 
189  // Vetoing an unsupported amendment should add the amendment to table.
190  // Verify that unsupportedID is not in table.
191  uint256 const unsupportedID = amendmentId(unsupported_[0]);
192  {
193  Json::Value const unsupp =
194  table->getJson(unsupportedID)[to_string(unsupportedID)];
195  BEAST_EXPECT(unsupp.size() == 0);
196  }
197 
198  // After vetoing unsupportedID verify that it is in table.
199  table->veto(unsupportedID);
200  {
201  Json::Value const unsupp =
202  table->getJson(unsupportedID)[to_string(unsupportedID)];
203  BEAST_EXPECT(unsupp[jss::vetoed].asBool());
204  }
205  }
206 
207  void
209  {
210  auto const section = makeSection(supported_);
211  auto const id = to_string(amendmentId(enabled_[0]));
212 
213  testcase("Bad Config");
214 
215  { // Two arguments are required - we pass one
216  Section test = section;
217  test.append(id);
218 
219  try
220  {
221  test::jtx::Env env{*this, makeConfig()};
222  if (makeTable(env, weeks(2), test, emptySection, emptySection))
223  fail("Accepted only amendment ID");
224  }
225  catch (...)
226  {
227  pass();
228  }
229  }
230 
231  { // Two arguments are required - we pass three
232  Section test = section;
233  test.append(id + " Test Name");
234 
235  try
236  {
237  test::jtx::Env env{*this, makeConfig()};
238  if (makeTable(env, weeks(2), test, emptySection, emptySection))
239  fail("Accepted extra arguments");
240  }
241  catch (...)
242  {
243  pass();
244  }
245  }
246 
247  {
248  auto sid = id;
249  sid.resize(sid.length() - 1);
250 
251  Section test = section;
252  test.append(sid + " Name");
253 
254  try
255  {
256  test::jtx::Env env{*this, makeConfig()};
257  if (makeTable(env, weeks(2), test, emptySection, emptySection))
258  fail("Accepted short amendment ID");
259  }
260  catch (...)
261  {
262  pass();
263  }
264  }
265 
266  {
267  auto sid = id;
268  sid.resize(sid.length() + 1, '0');
269 
270  Section test = section;
271  test.append(sid + " Name");
272 
273  try
274  {
275  test::jtx::Env env{*this, makeConfig()};
276  if (makeTable(env, weeks(2), test, emptySection, emptySection))
277  fail("Accepted long amendment ID");
278  }
279  catch (...)
280  {
281  pass();
282  }
283  }
284 
285  {
286  auto sid = id;
287  sid.resize(sid.length() - 1);
288  sid.push_back('Q');
289 
290  Section test = section;
291  test.append(sid + " Name");
292 
293  try
294  {
295  test::jtx::Env env{*this, makeConfig()};
296  if (makeTable(env, weeks(2), test, emptySection, emptySection))
297  fail("Accepted non-hex amendment ID");
298  }
299  catch (...)
300  {
301  pass();
302  }
303  }
304  }
305 
306  void
308  {
309  testcase("enable and veto");
310 
311  test::jtx::Env env{*this, makeConfig()};
313 
314  // Note which entries are enabled.
315  std::set<uint256> allEnabled;
316 
317  // Subset of amendments to enable
318  allEnabled.insert(amendmentId(supported_[0]));
319  allEnabled.insert(amendmentId(enabled_[0]));
320  allEnabled.insert(amendmentId(vetoed_[0]));
321 
322  for (uint256 const& a : allEnabled)
323  table->enable(a);
324 
325  // So far all enabled amendments are supported.
326  BEAST_EXPECT(!table->hasUnsupportedEnabled());
327 
328  // Verify all enables are enabled and nothing else.
329  for (std::string const& a : supported_)
330  {
331  uint256 const supportedID = amendmentId(a);
332  BEAST_EXPECT(
333  table->isEnabled(supportedID) ==
334  (allEnabled.find(supportedID) != allEnabled.end()));
335  }
336 
337  // All supported and unVetoed amendments should be returned as desired.
338  {
339  std::set<uint256> vetoed;
340  for (std::string const& a : vetoed_)
341  vetoed.insert(amendmentId(a));
342 
343  std::vector<uint256> const desired = table->getDesired();
344  for (uint256 const& a : desired)
345  BEAST_EXPECT(vetoed.count(a) == 0);
346 
347  // Unveto an amendment that is already not vetoed. Shouldn't
348  // hurt anything, but the values returned by getDesired()
349  // shouldn't change.
350  table->unVeto(amendmentId(supported_[1]));
351  BEAST_EXPECT(desired == table->getDesired());
352  }
353 
354  // UnVeto one of the vetoed amendments. It should now be desired.
355  {
356  uint256 const unvetoedID = amendmentId(vetoed_[0]);
357  table->unVeto(unvetoedID);
358 
359  std::vector<uint256> const desired = table->getDesired();
360  BEAST_EXPECT(
361  std::find(desired.begin(), desired.end(), unvetoedID) !=
362  desired.end());
363  }
364 
365  // Veto all supported amendments. Now desired should be empty.
366  for (std::string const& a : supported_)
367  {
368  table->veto(amendmentId(a));
369  }
370  BEAST_EXPECT(table->getDesired().empty());
371 
372  // Enable an unsupported amendment.
373  {
374  BEAST_EXPECT(!table->hasUnsupportedEnabled());
375  table->enable(amendmentId(unsupported_[0]));
376  BEAST_EXPECT(table->hasUnsupportedEnabled());
377  }
378  }
379 
381  makeValidators(int num)
382  {
384  ret.reserve(num);
385  for (int i = 0; i < num; ++i)
386  {
388  }
389  return ret;
390  }
391 
392  static NetClock::time_point
394  {
395  return NetClock::time_point{w};
396  }
397 
398  // Execute a pretend consensus round for a flag ledger
399  void
401  uint256 const& feat,
402  AmendmentTable& table,
403  weeks week,
404  std::vector<std::pair<PublicKey, SecretKey>> const& validators,
405  std::vector<std::pair<uint256, int>> const& votes,
406  std::vector<uint256>& ourVotes,
407  std::set<uint256>& enabled,
408  majorityAmendments_t& majority)
409  {
410  // Do a round at the specified time
411  // Returns the amendments we voted for
412 
413  // Parameters:
414  // table: Our table of known and vetoed amendments
415  // validators: The addreses of validators we trust
416  // votes: Amendments and the number of validators who vote for them
417  // ourVotes: The amendments we vote for in our validation
418  // enabled: In/out enabled amendments
419  // majority: In/our majority amendments (and when they got a majority)
420 
421  auto const roundTime = weekTime(week);
422 
423  // Build validations
425  validations.reserve(validators.size());
426 
427  int i = 0;
428  for (auto const& [pub, sec] : validators)
429  {
430  ++i;
431  std::vector<uint256> field;
432 
433  for (auto const& [hash, nVotes] : votes)
434  {
435  if (feat == fixAmendmentMajorityCalc ? nVotes >= i : nVotes > i)
436  {
437  // We vote yes on this amendment
438  field.push_back(hash);
439  }
440  }
441 
442  auto v = std::make_shared<STValidation>(
444  pub,
445  sec,
446  calcNodeID(pub),
447  [&field](STValidation& v) {
448  if (!field.empty())
449  v.setFieldV256(
451  v.setFieldU32(sfLedgerSequence, 6180339);
452  });
453 
454  validations.emplace_back(v);
455  }
456 
457  ourVotes = table.doValidation(enabled);
458 
459  auto actions = table.doVoting(
460  Rules({feat}), roundTime, enabled, majority, validations);
461  for (auto const& [hash, action] : actions)
462  {
463  // This code assumes other validators do as we do
464 
465  switch (action)
466  {
467  case 0:
468  // amendment goes from majority to enabled
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");
473  enabled.insert(hash);
474  majority.erase(hash);
475  break;
476 
477  case tfGotMajority:
478  if (majority.find(hash) != majority.end())
479  Throw<std::runtime_error>(
480  "got majority while having majority");
481  majority[hash] = roundTime;
482  break;
483 
484  case tfLostMajority:
485  if (majority.find(hash) == majority.end())
486  Throw<std::runtime_error>(
487  "lost majority without majority");
488  majority.erase(hash);
489  break;
490 
491  default:
492  Throw<std::runtime_error>("unknown action");
493  }
494  }
495  }
496 
497  // No vote on unknown amendment
498  void
500  {
501  testcase("Vote NO on unknown");
502 
503  auto const testAmendment = amendmentId("TestAmendment");
504  auto const validators = makeValidators(10);
505 
506  test::jtx::Env env{*this};
507  auto table =
509 
511  std::vector<uint256> ourVotes;
512  std::set<uint256> enabled;
513  majorityAmendments_t majority;
514 
515  doRound(
516  feat,
517  *table,
518  weeks{1},
519  validators,
520  votes,
521  ourVotes,
522  enabled,
523  majority);
524  BEAST_EXPECT(ourVotes.empty());
525  BEAST_EXPECT(enabled.empty());
526  BEAST_EXPECT(majority.empty());
527 
528  votes.emplace_back(testAmendment, validators.size());
529 
530  doRound(
531  feat,
532  *table,
533  weeks{2},
534  validators,
535  votes,
536  ourVotes,
537  enabled,
538  majority);
539  BEAST_EXPECT(ourVotes.empty());
540  BEAST_EXPECT(enabled.empty());
541 
542  majority[testAmendment] = weekTime(weeks{1});
543 
544  // Note that the simulation code assumes others behave as we do,
545  // so the amendment won't get enabled
546  doRound(
547  feat,
548  *table,
549  weeks{5},
550  validators,
551  votes,
552  ourVotes,
553  enabled,
554  majority);
555  BEAST_EXPECT(ourVotes.empty());
556  BEAST_EXPECT(enabled.empty());
557  }
558 
559  // No vote on vetoed amendment
560  void
561  testNoOnVetoed(uint256 const& feat)
562  {
563  testcase("Vote NO on vetoed");
564 
565  auto const testAmendment = amendmentId("vetoedAmendment");
566 
567  test::jtx::Env env{*this};
568  auto table = makeTable(
569  env,
570  weeks(2),
571  emptySection,
572  emptySection,
573  makeSection(testAmendment));
574 
575  auto const validators = makeValidators(10);
576 
578  std::vector<uint256> ourVotes;
579  std::set<uint256> enabled;
580  majorityAmendments_t majority;
581 
582  doRound(
583  feat,
584  *table,
585  weeks{1},
586  validators,
587  votes,
588  ourVotes,
589  enabled,
590  majority);
591  BEAST_EXPECT(ourVotes.empty());
592  BEAST_EXPECT(enabled.empty());
593  BEAST_EXPECT(majority.empty());
594 
595  votes.emplace_back(testAmendment, validators.size());
596 
597  doRound(
598  feat,
599  *table,
600  weeks{2},
601  validators,
602  votes,
603  ourVotes,
604  enabled,
605  majority);
606  BEAST_EXPECT(ourVotes.empty());
607  BEAST_EXPECT(enabled.empty());
608 
609  majority[testAmendment] = weekTime(weeks{1});
610 
611  doRound(
612  feat,
613  *table,
614  weeks{5},
615  validators,
616  votes,
617  ourVotes,
618  enabled,
619  majority);
620  BEAST_EXPECT(ourVotes.empty());
621  BEAST_EXPECT(enabled.empty());
622  }
623 
624  // Vote on and enable known, not-enabled amendment
625  void
626  testVoteEnable(uint256 const& feat)
627  {
628  testcase("voteEnable");
629 
630  test::jtx::Env env{*this};
631  auto table = makeTable(
633 
634  auto const validators = makeValidators(10);
636  std::vector<uint256> ourVotes;
637  std::set<uint256> enabled;
638  majorityAmendments_t majority;
639 
640  // Week 1: We should vote for all known amendments not enabled
641  doRound(
642  feat,
643  *table,
644  weeks{1},
645  validators,
646  votes,
647  ourVotes,
648  enabled,
649  majority);
650  BEAST_EXPECT(ourVotes.size() == supported_.size());
651  BEAST_EXPECT(enabled.empty());
652  for (auto const& i : supported_)
653  BEAST_EXPECT(majority.find(amendmentId(i)) == majority.end());
654 
655  // Now, everyone votes for this feature
656  for (auto const& i : supported_)
657  votes.emplace_back(amendmentId(i), validators.size());
658 
659  // Week 2: We should recognize a majority
660  doRound(
661  feat,
662  *table,
663  weeks{2},
664  validators,
665  votes,
666  ourVotes,
667  enabled,
668  majority);
669  BEAST_EXPECT(ourVotes.size() == supported_.size());
670  BEAST_EXPECT(enabled.empty());
671 
672  for (auto const& i : supported_)
673  BEAST_EXPECT(majority[amendmentId(i)] == weekTime(weeks{2}));
674 
675  // Week 5: We should enable the amendment
676  doRound(
677  feat,
678  *table,
679  weeks{5},
680  validators,
681  votes,
682  ourVotes,
683  enabled,
684  majority);
685  BEAST_EXPECT(enabled.size() == supported_.size());
686 
687  // Week 6: We should remove it from our votes and from having a majority
688  doRound(
689  feat,
690  *table,
691  weeks{6},
692  validators,
693  votes,
694  ourVotes,
695  enabled,
696  majority);
697  BEAST_EXPECT(enabled.size() == supported_.size());
698  BEAST_EXPECT(ourVotes.empty());
699  for (auto const& i : supported_)
700  BEAST_EXPECT(majority.find(amendmentId(i)) == majority.end());
701  }
702 
703  // Detect majority at 80%, enable later
704  void
706  {
707  testcase("detectMajority");
708 
709  auto const testAmendment = amendmentId("detectMajority");
710  test::jtx::Env env{*this};
711  auto table = makeTable(
712  env,
713  weeks(2),
714  makeSection(testAmendment),
715  emptySection,
716  emptySection);
717 
718  auto const validators = makeValidators(16);
719 
720  std::set<uint256> enabled;
721  majorityAmendments_t majority;
722 
723  for (int i = 0; i <= 17; ++i)
724  {
726  std::vector<uint256> ourVotes;
727 
728  if ((i > 0) && (i < 17))
729  votes.emplace_back(testAmendment, i);
730 
731  doRound(
732  feat,
733  *table,
734  weeks{i},
735  validators,
736  votes,
737  ourVotes,
738  enabled,
739  majority);
740 
741  if (i < 13) // 13 => 13/16 = 0.8125 => > 80%
742  {
743  // We are voting yes, not enabled, no majority
744  BEAST_EXPECT(!ourVotes.empty());
745  BEAST_EXPECT(enabled.empty());
746  BEAST_EXPECT(majority.empty());
747  }
748  else if (i < 15)
749  {
750  // We have a majority, not enabled, keep voting
751  BEAST_EXPECT(!ourVotes.empty());
752  BEAST_EXPECT(!majority.empty());
753  BEAST_EXPECT(enabled.empty());
754  }
755  else if (i == 15)
756  {
757  // enable, keep voting, remove from majority
758  BEAST_EXPECT(!ourVotes.empty());
759  BEAST_EXPECT(majority.empty());
760  BEAST_EXPECT(!enabled.empty());
761  }
762  else
763  {
764  // Done, we should be enabled and not voting
765  BEAST_EXPECT(ourVotes.empty());
766  BEAST_EXPECT(majority.empty());
767  BEAST_EXPECT(!enabled.empty());
768  }
769  }
770  }
771 
772  // Detect loss of majority
773  void
775  {
776  testcase("lostMajority");
777 
778  auto const testAmendment = amendmentId("lostMajority");
779  auto const validators = makeValidators(16);
780 
781  test::jtx::Env env{*this};
782  auto table = makeTable(
783  env,
784  weeks(8),
785  makeSection(testAmendment),
786  emptySection,
787  emptySection);
788 
789  std::set<uint256> enabled;
790  majorityAmendments_t majority;
791 
792  {
793  // establish majority
795  std::vector<uint256> ourVotes;
796 
797  votes.emplace_back(testAmendment, validators.size());
798 
799  doRound(
800  feat,
801  *table,
802  weeks{1},
803  validators,
804  votes,
805  ourVotes,
806  enabled,
807  majority);
808 
809  BEAST_EXPECT(enabled.empty());
810  BEAST_EXPECT(!majority.empty());
811  }
812 
813  for (int i = 1; i < 8; ++i)
814  {
816  std::vector<uint256> ourVotes;
817 
818  // Gradually reduce support
819  votes.emplace_back(testAmendment, validators.size() - i);
820 
821  doRound(
822  feat,
823  *table,
824  weeks{i + 1},
825  validators,
826  votes,
827  ourVotes,
828  enabled,
829  majority);
830 
831  if (i < 4) // 16 - 3 = 13 => 13/16 = 0.8125 => > 80%
832  { // 16 - 4 = 12 => 12/16 = 0.75 => < 80%
833  // We are voting yes, not enabled, majority
834  BEAST_EXPECT(!ourVotes.empty());
835  BEAST_EXPECT(enabled.empty());
836  BEAST_EXPECT(!majority.empty());
837  }
838  else
839  {
840  // No majority, not enabled, keep voting
841  BEAST_EXPECT(!ourVotes.empty());
842  BEAST_EXPECT(majority.empty());
843  BEAST_EXPECT(enabled.empty());
844  }
845  }
846  }
847 
848  void
850  {
851  testcase("hasUnsupportedEnabled");
852 
853  using namespace std::chrono_literals;
854  weeks constexpr w(1);
855  test::jtx::Env env{*this, makeConfig()};
856  auto table = makeTable(env, w);
857  BEAST_EXPECT(!table->hasUnsupportedEnabled());
858  BEAST_EXPECT(!table->firstUnsupportedExpected());
859  BEAST_EXPECT(table->needValidatedLedger(1));
860 
861  std::set<uint256> enabled;
864  unsupported_.end(),
865  [&enabled](auto const& s) { enabled.insert(amendmentId(s)); });
866 
867  majorityAmendments_t majority;
868  table->doValidatedLedger(1, enabled, majority);
869  BEAST_EXPECT(table->hasUnsupportedEnabled());
870  BEAST_EXPECT(!table->firstUnsupportedExpected());
871 
872  NetClock::duration t{1000s};
876  [&majority, &t](auto const& s) {
877  majority[amendmentId(s)] = NetClock::time_point{--t};
878  });
879 
880  table->doValidatedLedger(1, enabled, majority);
881  BEAST_EXPECT(table->hasUnsupportedEnabled());
882  BEAST_EXPECT(
883  table->firstUnsupportedExpected() &&
884  *table->firstUnsupportedExpected() == NetClock::time_point{t} + w);
885 
886  // Make sure the table knows when it needs an update.
887  BEAST_EXPECT(!table->needValidatedLedger(256));
888  BEAST_EXPECT(table->needValidatedLedger(257));
889  }
890 
891  void
892  testFeature(uint256 const& feat)
893  {
894  testNoOnUnknown(feat);
895  testNoOnVetoed(feat);
896  testVoteEnable(feat);
897  testDetectMajority(feat);
898  testLostMajority(feat);
899  }
900 
901  void
902  run() override
903  {
904  testConstruct();
905  testGet();
906  testBadConfig();
907  testEnableVeto();
909  testFeature({});
911  }
912 };
913 
914 BEAST_DEFINE_TESTSUITE(AmendmentTable, app, ripple);
915 
916 } // namespace ripple
ripple::Section
Holds a collection of configuration values.
Definition: BasicConfig.h:43
ripple::Application
Definition: Application.h:102
std::for_each
T for_each(T... args)
ripple::AmendmentTable_test::journal
test::SuiteJournal journal
Definition: AmendmentTable_test.cpp:104
ripple::AmendmentTable_test::testVoteEnable
void testVoteEnable(uint256 const &feat)
Definition: AmendmentTable_test.cpp:626
ripple::AmendmentTable_test::unsupported_
const std::vector< std::string > unsupported_
Definition: AmendmentTable_test.cpp:99
ripple::openssl_sha256_hasher
SHA-256 digest.
Definition: digest.h:90
ripple::AmendmentTable::doVoting
virtual 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 &valSet)=0
std::string
STL class.
ripple::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(AccountTxPaging, app, ripple)
ripple::calcNodeID
NodeID calcNodeID(PublicKey const &pk)
Calculate the 160-bit node ID from a node public key.
Definition: PublicKey.cpp:299
ripple::AmendmentTable_test::makeValidators
std::vector< std::pair< PublicKey, SecretKey > > makeValidators(int num)
Definition: AmendmentTable_test.cpp:381
ripple::AmendmentTable_test::makeSection
static Section makeSection(uint256 const &amendment)
Definition: AmendmentTable_test.cpp:71
ripple::sfLedgerSequence
const SF_UINT32 sfLedgerSequence
std::pair
std::vector::reserve
T reserve(T... args)
ripple::AmendmentTable_test::testConstruct
void testConstruct()
Definition: AmendmentTable_test.cpp:146
std::vector< std::string >
std::find
T find(T... args)
std::vector::size
T size(T... args)
std::chrono::seconds
ripple::QualityDirection::in
@ in
ripple::AmendmentTable_test::testNoOnUnknown
void testNoOnUnknown(uint256 const &feat)
Definition: AmendmentTable_test.cpp:499
ripple::test::jtx::Env::app
Application & app()
Definition: Env.h:240
ripple::AmendmentTable_test::testHasUnsupported
void testHasUnsupported()
Definition: AmendmentTable_test.cpp:849
ripple::to_string
std::string to_string(ListDisposition disposition)
Definition: ValidatorList.cpp:45
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:49
ripple::tfLostMajority
const std::uint32_t tfLostMajority
Definition: TxFlags.h:102
ripple::tfGotMajority
const std::uint32_t tfGotMajority
Definition: TxFlags.h:101
ripple::base_uint::data
pointer data()
Definition: base_uint.h:113
ripple::AmendmentTable_test::weekTime
static NetClock::time_point weekTime(weeks w)
Definition: AmendmentTable_test.cpp:393
ripple::STValidation
Definition: STValidation.h:43
ripple::base_uint::size
constexpr static std::size_t size()
Definition: base_uint.h:426
ripple::Section::append
void append(std::vector< std::string > const &lines)
Append a set of lines to this section.
Definition: BasicConfig.cpp:40
ripple::AmendmentTable_test::unsupportedMajority_
const std::vector< std::string > unsupportedMajority_
Definition: AmendmentTable_test.cpp:100
ripple::base_uint< 256 >
ripple::AmendmentTable::doValidation
virtual std::vector< uint256 > doValidation(std::set< uint256 > const &enabled) const =0
ripple::AmendmentTable_test::testEnableVeto
void testEnableVeto()
Definition: AmendmentTable_test.cpp:307
ripple::weeks
std::chrono::duration< int, std::ratio_multiply< days::period, std::ratio< 7 > >> weeks
Definition: chrono.h:39
ripple::AmendmentTable_test::makeTable
std::unique_ptr< AmendmentTable > makeTable(test::jtx::Env &env, std::chrono::seconds majorityTime)
Definition: AmendmentTable_test.cpp:135
ripple::fixAmendmentMajorityCalc
const uint256 fixAmendmentMajorityCalc
Definition: Feature.cpp:189
std::array
STL class.
ripple::AmendmentTable_test::supported_
const std::vector< std::string > supported_
Definition: AmendmentTable_test.cpp:93
std::chrono::time_point
Json::Value::size
UInt size() const
Number of values in array or object.
Definition: json_value.cpp:706
std::map::erase
T erase(T... args)
ripple::make_AmendmentTable
std::unique_ptr< AmendmentTable > make_AmendmentTable(Application &app, std::chrono::seconds majorityTime, Section const &supported, Section const &enabled, Section const &vetoed, beast::Journal journal)
Definition: AmendmentTable.cpp:813
std::map
STL class.
ripple::AmendmentTable_test::vetoed_
const std::vector< std::string > vetoed_
Definition: AmendmentTable_test.cpp:98
ripple::AmendmentTable_test::emptySection
const Section emptySection
Definition: AmendmentTable_test.cpp:102
ripple::test::SuiteJournal
Definition: SuiteJournal.h:88
ripple::KeyType::secp256k1
@ secp256k1
ripple::AmendmentTable_test::testDetectMajority
void testDetectMajority(uint256 const &feat)
Definition: AmendmentTable_test.cpp:705
ripple::AmendmentTable_test::makeTable
std::unique_ptr< AmendmentTable > makeTable(test::jtx::Env &env, std::chrono::seconds majorityTime, Section const &supported, Section const &enabled, Section const &vetoed)
Definition: AmendmentTable_test.cpp:124
ripple::randomKeyPair
std::pair< PublicKey, SecretKey > randomKeyPair(KeyType type)
Create a key pair using secure random numbers.
Definition: SecretKey.cpp:260
std::vector::emplace_back
T emplace_back(T... args)
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::AmendmentTable_test::makeTable
std::unique_ptr< AmendmentTable > makeTable(Application &app, std::chrono::seconds majorityTime, Section const &supported, Section const &enabled, Section const &vetoed)
Definition: AmendmentTable_test.cpp:112
ripple::AmendmentTable_test::doRound
void doRound(uint256 const &feat, AmendmentTable &table, weeks week, std::vector< std::pair< PublicKey, SecretKey >> const &validators, std::vector< std::pair< uint256, int >> const &votes, std::vector< uint256 > &ourVotes, std::set< uint256 > &enabled, majorityAmendments_t &majority)
Definition: AmendmentTable_test.cpp:400
ripple::AmendmentTable_test::testGet
void testGet()
Definition: AmendmentTable_test.cpp:170
std::vector::begin
T begin(T... args)
std::set::insert
T insert(T... args)
beast::hash_append
std::enable_if_t< is_contiguously_hashable< T, Hasher >::value > hash_append(Hasher &h, T const &t) noexcept
Logically concatenate input data to a Hasher.
Definition: hash_append.h:236
ripple::AmendmentTable_test::makeSection
static Section makeSection(std::vector< std::string > const &amendments)
Definition: AmendmentTable_test.cpp:65
ripple::AmendmentTable_test::makeConfig
std::unique_ptr< Config > makeConfig()
Definition: AmendmentTable_test.cpp:79
std::set::count
T count(T... args)
ripple::STVector256
Definition: STVector256.h:29
ripple::AmendmentTable_test::makeSection
static Section makeSection(std::string const &name, std::vector< std::string > const &amendments)
Definition: AmendmentTable_test.cpp:54
std::map::empty
T empty(T... args)
ripple::Rules
Rules controlling protocol behavior.
Definition: ReadView.h:131
ripple::AmendmentTable_test::testFeature
void testFeature(uint256 const &feat)
Definition: AmendmentTable_test.cpp:892
std::memcpy
T memcpy(T... args)
std::vector::end
T end(T... args)
ripple::AmendmentTable_test
Definition: AmendmentTable_test.cpp:38
ripple::hash_append
void hash_append(Hasher &h, ValidatorBlobInfo const &blobInfo)
Definition: ValidatorList.h:897
ripple::AmendmentTable
The amendment table stores the list of enabled and potential amendments.
Definition: AmendmentTable.h:34
std::unique_ptr
STL class.
ripple::AmendmentTable_test::AmendmentTable_test
AmendmentTable_test()
Definition: AmendmentTable_test.cpp:107
ripple::AmendmentTable_test::testBadConfig
void testBadConfig()
Definition: AmendmentTable_test.cpp:208
std::set
STL class.
ripple::AmendmentTable_test::run
void run() override
Definition: AmendmentTable_test.cpp:902
ripple::AmendmentTable_test::amendmentId
static uint256 amendmentId(std::string in)
Definition: AmendmentTable_test.cpp:42
ripple::AmendmentTable_test::enabled_
const std::vector< std::string > enabled_
Definition: AmendmentTable_test.cpp:97
ripple::AmendmentTable_test::testNoOnVetoed
void testNoOnVetoed(uint256 const &feat)
Definition: AmendmentTable_test.cpp:561
ripple::test::jtx::Env
A transaction testing environment.
Definition: Env.h:115
ripple::AmendmentTable_test::testLostMajority
void testLostMajority(uint256 const &feat)
Definition: AmendmentTable_test.cpp:774
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::sfAmendments
const SF_VECTOR256 sfAmendments