20 #include <ripple/app/misc/ValidatorList.h>
21 #include <ripple/basics/Slice.h>
22 #include <ripple/basics/base64.h>
23 #include <ripple/basics/strHex.h>
24 #include <ripple/overlay/impl/ProtocolMessage.h>
25 #include <ripple/protocol/HashPrefix.h>
26 #include <ripple/protocol/PublicKey.h>
27 #include <ripple/protocol/SecretKey.h>
28 #include <ripple/protocol/Sign.h>
29 #include <ripple/protocol/digest.h>
30 #include <ripple/protocol/jss.h>
31 #include <ripple/protocol/messages.h>
32 #include <boost/beast/core/multi_buffer.hpp>
139 data +=
",\"validators\":[";
141 for (
auto const& val : validators)
143 data +=
"{\"validation_public_key\":\"" +
strHex(val.masterPublic) +
144 "\",\"manifest\":\"" + val.manifest +
"\"},";
166 for (
auto const& pk : pks)
188 testcase(
"Genesis Quorum");
192 auto& app = env.
app();
194 auto trustedKeys = std::make_unique<ValidatorList>(
198 app.config().legacy(
"database_path"),
200 BEAST_EXPECT(trustedKeys->quorum() == 1);
204 auto trustedKeys = std::make_unique<ValidatorList>(
208 app.config().legacy(
"database_path"),
211 BEAST_EXPECT(trustedKeys->quorum() == minQuorum);
218 testcase(
"Config Load");
221 auto& app = env.
app();
227 auto const localSigningPublicOuter = localSigningKeys.first;
228 auto const localSigningSecret = localSigningKeys.second;
230 auto const localMasterPublic =
236 localSigningPublicOuter,
240 auto format = [](
PublicKey const& publicKey,
241 char const* comment =
nullptr) {
253 while (configList.
size() != 8)
258 {format(configList[0]),
259 format(configList[1],
" Comment"),
260 format(configList[2],
" Multi Word Comment"),
261 format(configList[3],
" Leading Whitespace"),
262 format(configList[4],
" Trailing Whitespace "),
263 format(configList[5],
" Leading & Trailing Whitespace "),
266 " Leading, Trailing & Internal Whitespace "),
267 format(configList[7],
" ")});
271 auto trustedKeys = std::make_unique<ValidatorList>(
275 app.config().legacy(
"database_path"),
279 BEAST_EXPECT(trustedKeys->load(
280 emptyLocalKey, emptyCfgKeys, emptyCfgPublishers));
283 BEAST_EXPECT(trustedKeys->load(
284 localSigningPublicOuter, emptyCfgKeys, emptyCfgPublishers));
285 BEAST_EXPECT(trustedKeys->listed(localSigningPublicOuter));
288 BEAST_EXPECT(trustedKeys->load(
289 localSigningPublicOuter, emptyCfgKeys, emptyCfgPublishers));
291 BEAST_EXPECT(trustedKeys->listed(localMasterPublic));
292 BEAST_EXPECT(trustedKeys->listed(localSigningPublicOuter));
297 auto trustedKeys = std::make_unique<ValidatorList>(
301 app.config().legacy(
"database_path"),
305 trustedKeys->load(emptyLocalKey, cfgKeys, emptyCfgPublishers));
307 for (
auto const& n : configList)
308 BEAST_EXPECT(trustedKeys->listed(n));
315 {format(masterNode1), format(masterNode2,
" Comment")});
316 BEAST_EXPECT(trustedKeys->load(
317 emptyLocalKey, cfgMasterKeys, emptyCfgPublishers));
318 BEAST_EXPECT(trustedKeys->listed(masterNode1));
319 BEAST_EXPECT(trustedKeys->listed(masterNode2));
322 BEAST_EXPECT(!trustedKeys->load(
323 emptyLocalKey, {
"NotAPublicKey"}, emptyCfgPublishers));
324 BEAST_EXPECT(!trustedKeys->load(
326 {format(randomNode(),
"!")},
327 emptyCfgPublishers));
331 BEAST_EXPECT(!trustedKeys->load(
333 {format(randomNode(),
"!"), format(goodKey)},
334 emptyCfgPublishers));
335 BEAST_EXPECT(!trustedKeys->listed(goodKey));
340 auto trustedKeys = std::make_unique<ValidatorList>(
344 app.config().legacy(
"database_path"),
347 auto const localSigningPublic =
350 BEAST_EXPECT(trustedKeys->load(
351 *localSigningPublic, cfgKeys, emptyCfgPublishers));
353 BEAST_EXPECT(trustedKeys->localPublicKey() == localSigningPublic);
354 BEAST_EXPECT(trustedKeys->listed(*localSigningPublic));
355 for (
auto const& n : configList)
356 BEAST_EXPECT(trustedKeys->listed(n));
361 auto trustedKeys = std::make_unique<ValidatorList>(
365 app.config().legacy(
"database_path"),
369 BEAST_EXPECT(trustedKeys->load(
370 localSigningPublic, cfgKeys, emptyCfgPublishers));
372 BEAST_EXPECT(trustedKeys->localPublicKey() == localSigningPublic);
373 BEAST_EXPECT(trustedKeys->listed(localSigningPublic));
374 for (
auto const& n : configList)
375 BEAST_EXPECT(trustedKeys->listed(n));
380 auto trustedKeys = std::make_unique<ValidatorList>(
384 app.config().legacy(
"database_path"),
389 BEAST_EXPECT(trustedKeys->load(
390 localSigningPublicOuter, cfgKeys, emptyCfgPublishers));
392 BEAST_EXPECT(trustedKeys->localPublicKey() == localMasterPublic);
393 BEAST_EXPECT(trustedKeys->listed(localSigningPublicOuter));
394 BEAST_EXPECT(trustedKeys->listed(localMasterPublic));
395 for (
auto const& n : configList)
396 BEAST_EXPECT(trustedKeys->listed(n));
400 auto trustedKeys = std::make_unique<ValidatorList>(
404 app.config().legacy(
"database_path"),
410 !trustedKeys->load(emptyLocalKey, emptyCfgKeys, badPublishers));
416 badPublishers.
clear();
417 for (
auto const& key : keys)
421 !trustedKeys->load(emptyLocalKey, emptyCfgKeys, badPublishers));
422 for (
auto const& key : keys)
423 BEAST_EXPECT(!trustedKeys->trustedPublisher(key));
427 for (
auto const& key : keys)
431 trustedKeys->load(emptyLocalKey, emptyCfgKeys, cfgPublishers));
432 for (
auto const& key : keys)
433 BEAST_EXPECT(trustedKeys->trustedPublisher(key));
440 auto trustedKeys = std::make_unique<ValidatorList>(
444 app.config().legacy(
"database_path"),
448 auto const pubRevokedPublic =
456 pubRevokedSigning.first,
457 pubRevokedSigning.second,
466 trustedKeys->load(emptyLocalKey, emptyCfgKeys, cfgPublishers));
468 BEAST_EXPECT(!trustedKeys->trustedPublisher(pubRevokedPublic));
469 BEAST_EXPECT(trustedKeys->trustedPublisher(legitKey));
476 testcase(
"Apply list");
477 using namespace std::chrono_literals;
481 auto checkAvailable =
483 auto const& trustedKeys,
484 auto const& hexPublic,
489 const auto available = trustedKeys->getAvailable(hexPublic);
495 BEAST_EXPECT(a[jss::public_key] == hexPublic);
496 BEAST_EXPECT(a[jss::manifest] ==
manifest);
499 BEAST_EXPECT(a[jss::version] == version);
502 BEAST_EXPECT(expected.size() == 1);
503 BEAST_EXPECT(a[jss::blob] == expected[0].first);
504 BEAST_EXPECT(a[jss::signature] == expected[0].second);
505 BEAST_EXPECT(!a.isMember(jss::blobs_v2));
507 else if (BEAST_EXPECT(a.isMember(jss::blobs_v2)))
509 BEAST_EXPECT(!a.isMember(jss::blob));
510 BEAST_EXPECT(!a.isMember(jss::signature));
511 auto const& blobs_v2 = a[jss::blobs_v2];
513 blobs_v2.isArray() &&
514 blobs_v2.size() == expected.size());
516 for (
unsigned int i = 0; i < expected.size(); ++i)
519 blobs_v2[i][jss::blob] == expected[i].first);
521 blobs_v2[i][jss::signature] ==
530 auto& app = env.
app();
531 auto trustedKeys = std::make_unique<ValidatorList>(
535 app.config().legacy(
"database_path"),
540 for (
auto const& val : list)
542 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
543 BEAST_EXPECT(trustedKeys->listed(val.signingPublic));
547 auto expectUntrusted =
549 for (
auto const& val : list)
551 BEAST_EXPECT(!trustedKeys->listed(val.masterPublic));
552 BEAST_EXPECT(!trustedKeys->listed(val.signingPublic));
557 auto const publisherPublic =
559 const auto hexPublic =
560 strHex(publisherPublic.begin(), publisherPublic.end());
565 pubSigningKeys1.first,
566 pubSigningKeys1.second,
573 BEAST_EXPECT(trustedKeys->load(emptyLocalKey, emptyCfgKeys, cfgKeys1));
576 auto constexpr listSize = 20;
577 auto constexpr numLists = 9;
580 for (
auto i = 1; i <= numLists; ++i)
582 auto& list = lists[i];
583 list.reserve(listSize);
584 while (list.size() < listSize)
592 auto const version = 1;
593 auto const sequence1 = 1;
598 auto const expiredSig =
signList(expiredblob, pubSigningKeys1);
601 auto const sequence2 = 2;
604 auto const sig2 =
signList(blob2, pubSigningKeys1);
607 trustedKeys->applyLists(
610 {{expiredblob, expiredSig, {}}, {blob2, sig2, {}}},
616 expectTrusted(lists.at(2));
619 trustedKeys, hexPublic, manifest1, version, {{blob2, sig2}});
622 auto const version2 = 2;
623 auto const sequence7 = 7;
624 auto const effective7 = validUntil - 60s;
625 auto const expiration7 = effective7 + 3600s;
629 expiration7.time_since_epoch().count(),
630 effective7.time_since_epoch().count());
631 auto const sig7 =
signList(blob7, pubSigningKeys1);
633 auto const sequence8 = 8;
634 auto const effective8 = expiration7 - 60s;
635 auto const expiration8 = effective8 + 3600s;
639 expiration8.time_since_epoch().count(),
640 effective8.time_since_epoch().count());
641 auto const sig8 =
signList(blob8, pubSigningKeys1);
644 trustedKeys->applyLists(
647 {{blob7, sig7, {}}, {blob8, sig8, {}}},
653 expectUntrusted(lists.at(7));
654 expectUntrusted(lists.at(8));
657 auto const sequence6 = 6;
658 auto const effective6 = effective7 - 60s;
659 auto const expiration6 = effective6 + 3600s;
660 auto const blob6 = makeList(
663 expiration6.time_since_epoch().count(),
664 effective6.time_since_epoch().count());
665 auto const sig6 = signList(blob6, pubSigningKeys1);
668 auto const sequence6a = 5;
669 auto const effective6a = effective6 + 60s;
670 auto const expiration6a = effective6a + 3600s;
671 auto const blob6a = makeList(
674 expiration6a.time_since_epoch().count(),
675 effective6a.time_since_epoch().count());
676 auto const sig6a = signList(blob6a, pubSigningKeys1);
679 trustedKeys->applyLists(
682 {{blob6a, sig6a, {}}, {blob6, sig6, {}}},
685 ListDisposition::pending,
686 ListDisposition::pending);
688 expectUntrusted(lists.at(6));
689 expectTrusted(lists.at(2));
694 trustedKeys->applyLists(
697 {{blob7, sig7, {}}, {blob6, sig6, {}}},
700 ListDisposition::known_sequence,
701 ListDisposition::known_sequence);
703 expectUntrusted(lists.at(6));
704 expectUntrusted(lists.at(7));
705 expectTrusted(lists.at(2));
708 auto const untrustedManifest =
base64_encode(makeManifestString(
711 pubSigningKeys1.first,
712 pubSigningKeys1.second,
716 trustedKeys->applyLists(
717 untrustedManifest, version, {{blob2, sig2, {}}}, siteUri),
719 ListDisposition::untrusted,
720 ListDisposition::untrusted);
723 auto const badVersion = 666;
725 trustedKeys->applyLists(
726 manifest1, badVersion, {{blob2, sig2, {}}}, siteUri),
728 ListDisposition::unsupported_version,
729 ListDisposition::unsupported_version);
732 auto const sequence3 = 3;
733 auto const blob3 = makeList(
734 lists.at(3), sequence3, validUntil.time_since_epoch().count());
735 auto const sig3 = signList(blob3, pubSigningKeys1);
738 trustedKeys->applyLists(
739 manifest1, version, {{blob3, sig3, {}}}, siteUri),
741 ListDisposition::accepted,
742 ListDisposition::accepted);
744 expectUntrusted(lists.at(1));
745 expectUntrusted(lists.at(2));
746 expectTrusted(lists.at(3));
755 {{blob3, sig3}, {blob6, sig6}, {blob7, sig7}, {blob8, sig8}});
759 trustedKeys->applyLists(
762 {{blob2, sig2, {}}, {blob3, sig3, {}}},
765 ListDisposition::stale,
766 ListDisposition::same_sequence);
770 auto const pubSigningKeys2 =
randomKeyPair(KeyType::secp256k1);
774 pubSigningKeys2.first,
775 pubSigningKeys2.second,
778 auto const sequence4 = 4;
779 auto const blob4 = makeList(
780 lists.at(4), sequence4, validUntil.time_since_epoch().count());
781 auto const sig4 = signList(blob4, pubSigningKeys2);
784 trustedKeys->applyLists(
787 {{blob2, sig2, manifest1},
788 {blob3, sig3, manifest1},
792 ListDisposition::stale,
793 ListDisposition::accepted);
795 expectUntrusted(lists.at(2));
796 expectUntrusted(lists.at(3));
797 expectTrusted(lists.at(4));
804 {{blob4, sig4}, {blob6, sig6}, {blob7, sig7}, {blob8, sig8}});
806 auto const sequence5 = 5;
807 auto const blob5 = makeList(
808 lists.at(5), sequence5, validUntil.time_since_epoch().count());
809 auto const badSig = signList(blob5, pubSigningKeys1);
811 trustedKeys->applyLists(
812 manifest1, version, {{blob5, badSig, {}}}, siteUri),
814 ListDisposition::invalid,
815 ListDisposition::invalid);
817 expectUntrusted(lists.at(2));
818 expectUntrusted(lists.at(3));
819 expectTrusted(lists.at(4));
820 expectUntrusted(lists.at(5));
824 trustedKeys->applyLists(
827 {{blob7, sig7, {}}, {blob8, sig8, {}}},
830 ListDisposition::invalid,
831 ListDisposition::invalid);
833 expectTrusted(lists.at(4));
834 expectUntrusted(lists.at(7));
835 expectUntrusted(lists.at(8));
840 trustedKeys->updateTrusted(
845 env.app().getHashRouter());
847 expectUntrusted(lists.at(3));
848 expectTrusted(lists.at(6));
855 {{blob6, sig6}, {blob7, sig7}, {blob8, sig8}});
861 env.timeKeeper().set(effective8);
862 trustedKeys->updateTrusted(
867 env.app().getHashRouter());
869 expectUntrusted(lists.at(6));
870 expectUntrusted(lists.at(7));
871 expectTrusted(lists.at(8));
873 checkAvailable(trustedKeys, hexPublic, manifest2, 2, {{blob8, sig8}});
879 auto const sig8_2 = signList(blob8, pubSigningKeys2);
882 trustedKeys->applyLists(
885 {{blob8, sig8, manifest1}, {blob8, sig8_2, {}}},
888 ListDisposition::invalid,
889 ListDisposition::same_sequence);
891 expectTrusted(lists.at(8));
893 checkAvailable(trustedKeys, hexPublic, manifest2, 2, {{blob8, sig8}});
897 auto const signingKeysMax =
randomKeyPair(KeyType::secp256k1);
899 makeRevocationString(publisherPublic, publisherSecret));
901 auto const sequence9 = 9;
902 auto const blob9 = makeList(
903 lists.at(9), sequence9, validUntil.time_since_epoch().count());
904 auto const sig9 = signList(blob9, signingKeysMax);
907 trustedKeys->applyLists(
908 maxManifest, version, {{blob9, sig9, {}}}, siteUri),
910 ListDisposition::untrusted,
911 ListDisposition::untrusted);
913 BEAST_EXPECT(!trustedKeys->trustedPublisher(publisherPublic));
914 for (
auto const& [num, list] : lists)
917 expectUntrusted(list);
920 checkAvailable(trustedKeys, hexPublic, manifest2, 0, {});
926 testcase(
"GetAvailable");
927 using namespace std::chrono_literals;
933 auto& app = env.
app();
934 auto trustedKeys = std::make_unique<ValidatorList>(
938 app.config().legacy(
"database_path"),
942 auto const publisherPublic =
944 const auto hexPublic =
945 strHex(publisherPublic.begin(), publisherPublic.end());
946 auto const pubSigningKeys1 =
randomKeyPair(KeyType::secp256k1);
950 pubSigningKeys1.first,
951 pubSigningKeys1.second,
958 BEAST_EXPECT(trustedKeys->load(emptyLocalKey, emptyCfgKeys, cfgKeys1));
961 auto constexpr listSize = 20;
964 while (list.
size() < listSize)
974 auto const sig = signList(blob, pubSigningKeys1);
978 auto const available = trustedKeys->getAvailable(hexPublic);
983 trustedKeys->applyLists(
manifest, 1, {{blob, sig, {}}}, siteUri)
984 .bestDisposition() == ListDisposition::accepted);
989 trustedKeys->getAvailable(hexPublic +
"invalid", 1);
990 BEAST_EXPECT(!available);
997 const auto hexBad =
strHex(badPublic.begin(), badPublic.end());
999 auto const available = trustedKeys->getAvailable(hexBad, 1);
1000 BEAST_EXPECT(!available);
1004 auto const available = trustedKeys->getAvailable(hexPublic, 0);
1005 if (BEAST_EXPECT(available))
1007 auto const& a = *available;
1013 auto const available = trustedKeys->getAvailable(hexPublic, 3);
1014 if (BEAST_EXPECT(available))
1022 auto const available = trustedKeys->getAvailable(hexPublic, 1);
1023 if (BEAST_EXPECT(available))
1026 BEAST_EXPECT(a[jss::public_key] == hexPublic);
1027 BEAST_EXPECT(a[jss::manifest] == manifest);
1028 BEAST_EXPECT(a[jss::version] == 1);
1030 BEAST_EXPECT(a[jss::blob] == blob);
1031 BEAST_EXPECT(a[jss::signature] == sig);
1032 BEAST_EXPECT(!a.isMember(jss::blobs_v2));
1038 auto const available = trustedKeys->getAvailable(hexPublic, 2);
1039 if (BEAST_EXPECT(available))
1042 BEAST_EXPECT(a[jss::public_key] == hexPublic);
1043 BEAST_EXPECT(a[jss::manifest] == manifest);
1044 BEAST_EXPECT(a[jss::version] == 2);
1046 if (BEAST_EXPECT(a.isMember(jss::blobs_v2)))
1048 BEAST_EXPECT(!a.isMember(jss::blob));
1049 BEAST_EXPECT(!a.isMember(jss::signature));
1050 auto const& blobs_v2 = a[jss::blobs_v2];
1051 BEAST_EXPECT(blobs_v2.isArray() && blobs_v2.size() == 1);
1053 BEAST_EXPECT(blobs_v2[0u][jss::blob] == blob);
1054 BEAST_EXPECT(blobs_v2[0u][jss::signature] == sig);
1063 testcase(
"Update trusted");
1065 std::string const siteUri =
"testUpdateTrusted.test";
1070 auto& app = env.
app();
1071 auto trustedKeysOuter = std::make_unique<ValidatorList>(
1075 app.config().legacy(
"database_path"),
1087 while (cfgKeys.
size() != maxKeys)
1089 auto const valKey = randomNode();
1091 if (cfgKeys.
size() <= maxKeys - 5)
1097 BEAST_EXPECT(trustedKeysOuter->load(
1098 emptyLocalKeyOuter, cfgKeys, cfgPublishersOuter));
1102 TrustChanges changes = trustedKeysOuter->updateTrusted(
1103 activeValidatorsOuter,
1109 for (
auto const& val : unseenValidators)
1110 activeValidatorsOuter.
emplace(val);
1112 BEAST_EXPECT(changes.
added == activeValidatorsOuter);
1113 BEAST_EXPECT(changes.
removed.empty());
1115 trustedKeysOuter->quorum() ==
std::ceil(cfgKeys.
size() * 0.8f));
1116 for (
auto const& val : cfgKeys)
1118 if (
auto const valKey =
1119 parseBase58<PublicKey>(TokenType::NodePublic, val))
1121 BEAST_EXPECT(trustedKeysOuter->listed(*valKey));
1122 BEAST_EXPECT(trustedKeysOuter->trusted(*valKey));
1128 changes = trustedKeysOuter->updateTrusted(
1129 activeValidatorsOuter,
1134 BEAST_EXPECT(changes.
added.empty());
1135 BEAST_EXPECT(changes.
removed.empty());
1137 trustedKeysOuter->quorum() ==
std::ceil(cfgKeys.size() * 0.8f));
1142 auto const masterPublic =
1146 {
toBase58(TokenType::NodePublic, masterPublic)});
1148 BEAST_EXPECT(trustedKeysOuter->load(
1149 emptyLocalKeyOuter, cfgKeys, cfgPublishersOuter));
1151 auto const signingKeys1 =
randomKeyPair(KeyType::secp256k1);
1152 auto const signingPublic1 = signingKeys1.first;
1156 TrustChanges changes = trustedKeysOuter->updateTrusted(
1157 activeValidatorsOuter,
1162 BEAST_EXPECT(changes.
added == asNodeIDs({masterPublic}));
1163 BEAST_EXPECT(changes.
removed.empty());
1165 trustedKeysOuter->quorum() ==
std::ceil((maxKeys + 1) * 0.8f));
1166 BEAST_EXPECT(trustedKeysOuter->listed(masterPublic));
1167 BEAST_EXPECT(trustedKeysOuter->trusted(masterPublic));
1168 BEAST_EXPECT(!trustedKeysOuter->listed(signingPublic1));
1169 BEAST_EXPECT(!trustedKeysOuter->trusted(signingPublic1));
1176 signingKeys1.second,
1181 ManifestDisposition::accepted);
1182 BEAST_EXPECT(trustedKeysOuter->listed(masterPublic));
1183 BEAST_EXPECT(trustedKeysOuter->trusted(masterPublic));
1184 BEAST_EXPECT(trustedKeysOuter->listed(signingPublic1));
1185 BEAST_EXPECT(trustedKeysOuter->trusted(signingPublic1));
1189 auto const signingKeys2 =
randomKeyPair(KeyType::secp256k1);
1190 auto const signingPublic2 = signingKeys2.first;
1195 signingKeys2.second,
1199 ManifestDisposition::accepted);
1200 BEAST_EXPECT(trustedKeysOuter->listed(masterPublic));
1201 BEAST_EXPECT(trustedKeysOuter->trusted(masterPublic));
1202 BEAST_EXPECT(trustedKeysOuter->listed(signingPublic2));
1203 BEAST_EXPECT(trustedKeysOuter->trusted(signingPublic2));
1204 BEAST_EXPECT(!trustedKeysOuter->listed(signingPublic1));
1205 BEAST_EXPECT(!trustedKeysOuter->trusted(signingPublic1));
1208 auto const signingKeysMax =
randomKeyPair(KeyType::secp256k1);
1209 auto const signingPublicMax = signingKeysMax.first;
1212 makeRevocationString(masterPublic, masterPrivate));
1214 BEAST_EXPECT(mMax->revoked());
1217 ManifestDisposition::accepted);
1219 manifestsOuter.
getSigningKey(masterPublic) == masterPublic);
1220 BEAST_EXPECT(manifestsOuter.
revoked(masterPublic));
1223 BEAST_EXPECT(trustedKeysOuter->listed(masterPublic));
1224 BEAST_EXPECT(trustedKeysOuter->trusted(masterPublic));
1226 changes = trustedKeysOuter->updateTrusted(
1227 activeValidatorsOuter,
1232 BEAST_EXPECT(changes.
removed == asNodeIDs({masterPublic}));
1233 BEAST_EXPECT(changes.
added.empty());
1235 trustedKeysOuter->quorum() ==
std::ceil(maxKeys * 0.8f));
1236 BEAST_EXPECT(trustedKeysOuter->listed(masterPublic));
1237 BEAST_EXPECT(!trustedKeysOuter->trusted(masterPublic));
1238 BEAST_EXPECT(!trustedKeysOuter->listed(signingPublicMax));
1239 BEAST_EXPECT(!trustedKeysOuter->trusted(signingPublicMax));
1240 BEAST_EXPECT(!trustedKeysOuter->listed(signingPublic2));
1241 BEAST_EXPECT(!trustedKeysOuter->trusted(signingPublic2));
1242 BEAST_EXPECT(!trustedKeysOuter->listed(signingPublic1));
1243 BEAST_EXPECT(!trustedKeysOuter->trusted(signingPublic1));
1248 auto trustedKeys = std::make_unique<ValidatorList>(
1252 app.config().legacy(
"database_path"),
1255 auto const publisherPublic =
1261 BEAST_EXPECT(trustedKeys->load(
1262 emptyLocalKeyOuter, emptyCfgKeys, cfgPublishers));
1265 activeValidatorsOuter,
1270 BEAST_EXPECT(changes.
removed.empty());
1271 BEAST_EXPECT(changes.
added.empty());
1273 trustedKeys->quorum() ==
1280 auto trustedKeys = std::make_unique<ValidatorList>(
1284 app.config().legacy(
"database_path"),
1295 while (cfgKeys.
size() < n)
1297 auto const valKey = randomNode();
1306 BEAST_EXPECT(trustedKeys->load(
1307 emptyLocalKeyOuter, cfgKeys, cfgPublishersOuter));
1315 BEAST_EXPECT(changes.
removed.empty());
1316 BEAST_EXPECT(changes.
added == expectedTrusted);
1317 BEAST_EXPECT(trustedKeys->quorum() == minQuorum);
1320 activeValidators.
emplace(toBeSeen);
1321 changes = trustedKeys->updateTrusted(
1327 BEAST_EXPECT(changes.
removed.empty());
1328 BEAST_EXPECT(changes.
added.empty());
1329 BEAST_EXPECT(trustedKeys->quorum() ==
std::ceil(n * 0.8f));
1333 auto trustedKeys = std::make_unique<ValidatorList>(
1337 app.config().legacy(
"database_path"),
1342 auto const publisherKeys =
randomKeyPair(KeyType::secp256k1);
1343 auto const pubSigningKeys =
randomKeyPair(KeyType::secp256k1);
1345 publisherKeys.first,
1346 publisherKeys.second,
1347 pubSigningKeys.first,
1348 pubSigningKeys.second,
1354 trustedKeys->load(emptyLocalKey, emptyCfgKeys, cfgKeys));
1358 asNodeIDs({list[0].masterPublic, list[1].masterPublic}));
1361 auto const version = 1;
1362 auto const sequence = 1;
1363 using namespace std::chrono_literals;
1368 auto const sig = signList(blob, pubSigningKeys);
1371 ListDisposition::accepted ==
1373 ->applyLists(
manifest, version, {{blob,
sig, {}}}, siteUri)
1374 .bestDisposition());
1382 BEAST_EXPECT(changes.
removed.empty());
1383 BEAST_EXPECT(changes.
added == activeValidators);
1386 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
1387 BEAST_EXPECT(trustedKeys->trusted(val.signingPublic));
1389 BEAST_EXPECT(trustedKeys->quorum() == 2);
1392 changes = trustedKeys->updateTrusted(
1398 BEAST_EXPECT(changes.
removed == activeValidators);
1399 BEAST_EXPECT(changes.
added.empty());
1400 BEAST_EXPECT(!trustedKeys->trusted(list[0].masterPublic));
1401 BEAST_EXPECT(!trustedKeys->trusted(list[1].masterPublic));
1403 trustedKeys->quorum() ==
1409 auto const sequence2 = 2;
1412 auto const blob2 = makeList(
1414 auto const sig2 = signList(blob2, pubSigningKeys);
1417 ListDisposition::accepted ==
1420 manifest, version, {{blob2, sig2, {}}}, siteUri)
1421 .bestDisposition());
1423 changes = trustedKeys->updateTrusted(
1429 BEAST_EXPECT(changes.
removed.empty());
1432 asNodeIDs({list2[0].masterPublic, list2[1].masterPublic}));
1435 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
1436 BEAST_EXPECT(trustedKeys->trusted(val.signingPublic));
1438 BEAST_EXPECT(!trustedKeys->trusted(list[1].masterPublic));
1439 BEAST_EXPECT(!trustedKeys->trusted(list[1].signingPublic));
1440 BEAST_EXPECT(trustedKeys->quorum() == 2);
1444 auto trustedKeys = std::make_unique<ValidatorList>(
1448 app.config().legacy(
"database_path"),
1460 auto const valKey = randomNode();
1464 BEAST_EXPECT(trustedKeys->load(
1465 emptyLocalKeyOuter, cfgKeys, cfgPublishers));
1472 BEAST_EXPECT(changes.
removed.empty());
1473 BEAST_EXPECT(changes.
added == asNodeIDs({valKey}));
1476 for (
auto const& key : activeKeys)
1477 BEAST_EXPECT(trustedKeys->trusted(key));
1482 auto trustedKeys = std::make_unique<ValidatorList>(
1486 app.config().legacy(
"database_path"),
1489 auto const localKey = randomNode();
1494 toBase58(TokenType::NodePublic, localKey)};
1497 while (cfgKeys.size() < cfgKeys.capacity())
1499 auto const valKey = randomNode();
1500 cfgKeys.push_back(
toBase58(TokenType::NodePublic, valKey));
1505 trustedKeys->load(localKey, cfgKeys, cfgPublishers));
1512 BEAST_EXPECT(changes.
removed.empty());
1513 if (cfgKeys.size() > 2)
1514 BEAST_EXPECT(changes.
added == asNodeIDs({valKey}));
1517 changes.
added == asNodeIDs({localKey, valKey}));
1520 trustedKeys->quorum() ==
std::ceil(cfgKeys.size() * 0.8f));
1522 for (
auto const& key : activeKeys)
1523 BEAST_EXPECT(trustedKeys->trusted(key));
1529 auto trustedKeys = std::make_unique<ValidatorList>(
1533 app.config().legacy(
"database_path"),
1540 while (valKeys.
size() != maxKeys)
1547 auto addPublishedList = [
this,
1553 auto const publisherPublic =
1555 auto const pubSigningKeys =
randomKeyPair(KeyType::secp256k1);
1559 pubSigningKeys.first,
1560 pubSigningKeys.second,
1564 {
strHex(publisherPublic)});
1568 BEAST_EXPECT(trustedKeys->load(
1569 emptyLocalKey, emptyCfgKeys, cfgPublishers));
1571 auto const version = 1;
1572 auto const sequence = 1;
1573 using namespace std::chrono_literals;
1576 auto const blob = makeList(
1578 auto const sig = signList(blob, pubSigningKeys);
1581 ListDisposition::accepted ==
1585 .bestDisposition());
1589 for (
auto i = 0; i < 3; ++i)
1600 trustedKeys->quorum() ==
std::ceil(valKeys.size() * 0.8f));
1603 for (
auto const& val : valKeys)
1605 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
1608 BEAST_EXPECT(changes.
added == added);
1609 BEAST_EXPECT(changes.
removed.empty());
1616 testcase(
"Expires");
1621 auto& app = env.
app();
1623 auto toStr = [](
PublicKey const& publicKey) {
1624 return toBase58(TokenType::NodePublic, publicKey);
1630 auto trustedKeys = std::make_unique<ValidatorList>(
1634 app.config().legacy(
"database_path"),
1638 BEAST_EXPECT(trustedKeys->expires() == std::nullopt);
1642 PublicKey localCfgListed = randomNode();
1643 trustedKeys->load(emptyLocalKey, {toStr(localCfgListed)}, {});
1645 trustedKeys->expires() &&
1646 trustedKeys->expires().value() == NetClock::time_point::max());
1647 BEAST_EXPECT(trustedKeys->listed(localCfgListed));
1653 auto trustedKeys = std::make_unique<ValidatorList>(
1657 app.config().legacy(
"database_path"),
1674 using namespace std::chrono_literals;
1675 auto addPublishedList = [
this, &env, &trustedKeys, &validators]() {
1677 auto const publisherPublic =
1679 auto const pubSigningKeys =
randomKeyPair(KeyType::secp256k1);
1683 pubSigningKeys.first,
1684 pubSigningKeys.second,
1688 {
strHex(publisherPublic)});
1692 BEAST_EXPECT(trustedKeys->load(
1693 emptyLocalKey, emptyCfgKeys, cfgPublishers));
1695 auto const version = 2;
1696 auto const sequence1 = 1;
1699 auto const blob1 = makeList(
1703 auto const sig1 = signList(blob1, pubSigningKeys);
1707 auto const sequence2 = 2;
1708 auto const blob2 = makeList(
1713 auto const sig2 = signList(blob2, pubSigningKeys);
1715 return PreparedList{
1718 {{blob1, sig1, {}}, {blob2, sig2, {}}},
1720 {expiration1, expiration2}};
1724 PreparedList prep1 = addPublishedList();
1726 PreparedList prep2 = addPublishedList();
1729 BEAST_EXPECT(trustedKeys->expires() == std::nullopt);
1733 trustedKeys->applyLists(
1734 prep1.manifest, prep1.version, prep1.blobs, siteUri),
1735 prep1.publisherPublic,
1736 ListDisposition::pending,
1737 ListDisposition::accepted);
1741 BEAST_EXPECT(trustedKeys->expires() == std::nullopt);
1745 trustedKeys->applyLists(
1746 prep2.manifest, prep2.version, prep2.blobs, siteUri),
1747 prep2.publisherPublic,
1748 ListDisposition::pending,
1749 ListDisposition::accepted);
1752 trustedKeys->expires() &&
1753 trustedKeys->expires().value() == prep1.expirations.back());
1759 auto changes = trustedKeys->updateTrusted(
1766 trustedKeys->expires() &&
1767 trustedKeys->expires().value() == prep1.expirations.back());
1768 BEAST_EXPECT(!changes.added.empty());
1769 BEAST_EXPECT(changes.removed.empty());
1776 auto changes = trustedKeys->updateTrusted(
1783 trustedKeys->expires() &&
1784 trustedKeys->expires().value() == prep1.expirations.back());
1785 BEAST_EXPECT(changes.added.empty());
1786 BEAST_EXPECT(changes.removed.empty());
1794 testcase(
"NegativeUNL");
1799 auto createValidatorList =
1803 auto trustedKeys = std::make_shared<ValidatorList>(
1817 auto const valKey = randomNode();
1821 if (trustedKeys->load(emptyLocalKey, cfgKeys, cfgPublishers))
1823 trustedKeys->updateTrusted(
1829 if (trustedKeys->quorum() ==
std::ceil(cfgKeys.
size() * 0.8f))
1854 for (
auto us : unlSizes)
1856 for (
auto np : nUnlPercent)
1858 auto validators = createValidatorList(us);
1859 BEAST_EXPECT(validators);
1863 auto unl = validators->getTrustedMasterKeys();
1865 auto it = unl.
begin();
1871 validators->setNegativeUNL(nUnl);
1872 validators->updateTrusted(
1879 validators->quorum() ==
1881 std::max((us - nUnlSize) * 0.8f, us * 0.6f))));
1889 auto validators = createValidatorList(60);
1890 BEAST_EXPECT(validators);
1894 auto unl = validators->getTrustedMasterKeys();
1895 BEAST_EXPECT(unl.size() == 60);
1902 auto it = unl.
begin();
1908 validators->setNegativeUNL(nUnl);
1909 auto nUnl_temp = validators->getNegativeUNL();
1910 if (nUnl_temp.size() == nUnl.
size())
1912 for (
auto& n : nUnl_temp)
1914 if (nUnl.
find(n) == nUnl.
end())
1917 validators->updateTrusted(
1923 return validators->quorum() == quorum;
1927 BEAST_EXPECT(nUnlChange(0, 48));
1928 BEAST_EXPECT(nUnlChange(30, 36));
1929 BEAST_EXPECT(nUnlChange(18, 36));
1930 BEAST_EXPECT(nUnlChange(12, 39));
1936 auto nUnl = validators->getNegativeUNL();
1937 BEAST_EXPECT(nUnl.size() == 12);
1941 for (
int i = 0; i < 6; ++i)
1943 Slice s(data.data(), ss);
1947 validators->setNegativeUNL(nUnl);
1948 validators->updateTrusted(
1954 BEAST_EXPECT(validators->quorum() == 39);
1963 auto validators = createValidatorList(60, 30);
1964 BEAST_EXPECT(validators);
1969 auto it = unl.
begin();
1975 validators->updateTrusted(
1981 BEAST_EXPECT(validators->quorum() == 48);
1989 validators->setNegativeUNL(nUnl);
1990 validators->updateTrusted(
1996 BEAST_EXPECT(validators->quorum() == 30);
2004 testcase(
"Sha512 hashing");
2009 std::string const blob =
"This is not really a blob";
2010 std::string const signature =
"This is not really a signature";
2014 BEAST_EXPECT(!!global);
2017 blobVector[0].blob = blob;
2018 blobVector[0].signature = signature;
2020 BEAST_EXPECT(global !=
sha512Half(signature, blobVector, version));
2024 {99, blobVector[0]}};
2026 BEAST_EXPECT(global !=
sha512Half(blob, blobMap, version));
2030 protocol::TMValidatorList msg1;
2032 msg1.set_blob(blob);
2033 msg1.set_signature(signature);
2034 msg1.set_version(version);
2036 msg1.set_signature(blob);
2041 protocol::TMValidatorListCollection msg2;
2043 msg2.set_version(version);
2044 auto& bi = *msg2.add_blobs();
2046 bi.set_signature(signature);
2056 testcase(
"Build and split messages");
2059 auto extractHeader = [
this](
Message& message) {
2060 auto const& buffer =
2061 message.getBuffer(compression::Compressed::Off);
2063 boost::beast::multi_buffer buffers;
2066 auto start = buffer.begin();
2067 auto end = buffer.end();
2069 buffers.commit(boost::asio::buffer_copy(
2070 buffers.prepare(slice.
size()), boost::asio::buffer(slice)));
2072 boost::system::error_code ec;
2074 detail::parseMessageHeader(ec, buffers.data(), buffers.size());
2078 auto extractProtocolMessage1 = [
this,
2079 &extractHeader](
Message& message) {
2080 auto [header, buffers] = extractHeader(message);
2081 if (BEAST_EXPECT(header) &&
2082 BEAST_EXPECT(header->message_type == protocol::mtVALIDATORLIST))
2085 detail::parseMessageContent<protocol::TMValidatorList>(
2086 *header, buffers.data());
2092 auto extractProtocolMessage2 = [
this,
2093 &extractHeader](
Message& message) {
2094 auto [header, buffers] = extractHeader(message);
2095 if (BEAST_EXPECT(header) &&
2097 header->message_type ==
2098 protocol::mtVALIDATORLISTCOLLECTION))
2100 auto const msg = detail::parseMessageContent<
2101 protocol::TMValidatorListCollection>(
2102 *header, buffers.data());
2108 auto verifyMessage =
2111 &extractProtocolMessage1,
2112 &extractProtocolMessage2](
2115 auto const& blobInfos,
2116 auto const& messages,
2119 BEAST_EXPECT(messages.size() == expectedInfo.size());
2120 auto msgIter = expectedInfo.begin();
2121 for (
auto const& messageWithHash : messages)
2123 if (!BEAST_EXPECT(msgIter != expectedInfo.end()))
2125 if (!BEAST_EXPECT(messageWithHash.message))
2127 auto const& expectedSeqs = msgIter->second;
2128 auto seqIter = expectedSeqs.begin();
2130 messageWithHash.message
2131 ->getBuffer(compression::Compressed::Off)
2134 BEAST_EXPECT(size == msgIter->first);
2135 if (expectedSeqs.size() == 1)
2138 extractProtocolMessage1(*messageWithHash.message);
2139 auto const expectedVersion = 1;
2140 if (BEAST_EXPECT(msg))
2142 BEAST_EXPECT(msg->version() == expectedVersion);
2143 if (!BEAST_EXPECT(seqIter != expectedSeqs.end()))
2145 auto const& expectedBlob = blobInfos.at(*seqIter);
2147 (*seqIter < manifestCutoff) ==
2148 !!expectedBlob.manifest);
2149 auto const expectedManifest =
2150 *seqIter < manifestCutoff &&
2151 expectedBlob.manifest
2152 ? *expectedBlob.manifest
2154 BEAST_EXPECT(msg->manifest() == expectedManifest);
2155 BEAST_EXPECT(msg->blob() == expectedBlob.blob);
2157 msg->signature() == expectedBlob.signature);
2159 BEAST_EXPECT(seqIter == expectedSeqs.end());
2162 messageWithHash.hash ==
2166 expectedBlob.signature,
2173 hashingBlobs.
reserve(msgIter->second.size());
2176 extractProtocolMessage2(*messageWithHash.message);
2177 if (BEAST_EXPECT(msg))
2179 BEAST_EXPECT(msg->version() == version);
2180 BEAST_EXPECT(msg->manifest() ==
manifest);
2181 for (
auto const& blobInfo : msg->blobs())
2184 seqIter != expectedSeqs.end()))
2186 auto const& expectedBlob =
2187 blobInfos.at(*seqIter);
2190 blobInfo.has_manifest() ==
2191 !!expectedBlob.manifest);
2193 blobInfo.has_manifest() ==
2194 (*seqIter < manifestCutoff));
2196 if (*seqIter < manifestCutoff)
2198 blobInfo.manifest() ==
2199 *expectedBlob.manifest);
2201 blobInfo.blob() == expectedBlob.blob);
2203 blobInfo.signature() ==
2204 expectedBlob.signature);
2207 BEAST_EXPECT(seqIter == expectedSeqs.end());
2210 messageWithHash.hash ==
2215 BEAST_EXPECT(msgIter == expectedInfo.end());
2217 auto verifyBuildMessages =
2222 BEAST_EXPECT(result.
first == expectedSequence);
2223 BEAST_EXPECT(result.
second == expectedSize);
2229 auto const blobInfos = [manifestCutoff = manifestCutoff]() {
2232 for (
auto seq : {5, 6, 7, 10, 12})
2236 s <<
"This is not a blob with sequence " <<
seq;
2239 s <<
"This is not a signature for sequence " <<
seq;
2240 b.signature = s.
str();
2241 if (
seq < manifestCutoff)
2245 s <<
"This is not manifest " <<
seq;
2246 b.manifest = s.
str();
2251 auto const maxSequence = blobInfos.
rbegin()->first;
2252 BEAST_EXPECT(maxSequence == 12);
2259 verifyBuildMessages(
2260 ValidatorList::buildValidatorListMessages(
2261 1, 8, maxSequence, version,
manifest, blobInfos, messages),
2264 BEAST_EXPECT(messages.
size() == 0);
2271 verifyBuildMessages(
2272 ValidatorList::buildValidatorListMessages(
2273 1, 3, maxSequence, version,
manifest, blobInfos, messages),
2276 BEAST_EXPECT(messages.
size() == 1 && !messages.
front().message);
2280 verifyBuildMessages(
2281 ValidatorList::buildValidatorListMessages(
2282 1, 3, maxSequence, version,
manifest, blobInfos, messages),
2285 if (BEAST_EXPECT(messages.
size() == 1) &&
2286 BEAST_EXPECT(messages.
front().message))
2288 auto const& messageWithHash = messages.
front();
2289 auto const msg = extractProtocolMessage1(*messageWithHash.message);
2291 messageWithHash.message->getBuffer(compression::Compressed::Off)
2294 BEAST_EXPECT(size == 108);
2295 auto const& expected = blobInfos.at(5);
2296 if (BEAST_EXPECT(msg))
2298 BEAST_EXPECT(msg->version() == 1);
2299 BEAST_EXPECT(msg->manifest() == *expected.manifest);
2300 BEAST_EXPECT(msg->blob() == expected.blob);
2301 BEAST_EXPECT(msg->signature() == expected.signature);
2304 messageWithHash.hash ==
2306 *expected.manifest, expected.blob, expected.signature, 1));
2314 verifyBuildMessages(
2315 ValidatorList::buildValidatorListMessages(
2325 BEAST_EXPECT(messages.
size() == 0);
2332 verifyBuildMessages(
2333 ValidatorList::buildValidatorListMessages(
2334 2, 3, maxSequence, version,
manifest, blobInfos, messages),
2337 BEAST_EXPECT(messages.
size() == 1 && !messages.
front().message);
2341 verifyBuildMessages(
2342 ValidatorList::buildValidatorListMessages(
2343 2, 5, maxSequence, version,
manifest, blobInfos, messages),
2347 version,
manifest, blobInfos, messages, {{372, {6, 7, 10, 12}}});
2353 verifyBuildMessages(
2354 ValidatorList::buildValidatorListMessages(
2355 2, 5, maxSequence, version,
manifest, blobInfos, messages, 300),
2363 {{212, {6, 7}}, {192, {10, 12}}});
2368 verifyBuildMessages(
2369 ValidatorList::buildValidatorListMessages(
2370 2, 5, maxSequence, version,
manifest, blobInfos, messages, 200),
2378 {{108, {6}}, {108, {7}}, {192, {10, 12}}});
2382 verifyBuildMessages(
2383 ValidatorList::buildValidatorListMessages(
2384 2, 5, maxSequence, version,
manifest, blobInfos, messages, 150),
2392 {{108, {6}}, {108, {7}}, {110, {10}}, {110, {12}}});
2397 verifyBuildMessages(
2398 ValidatorList::buildValidatorListMessages(
2399 2, 5, maxSequence, version,
manifest, blobInfos, messages, 108),
2407 {{108, {6}}, {108, {7}}, {110, {10}}, {110, {12}}});
2414 testGenesisQuorum();
2418 testUpdateTrusted();
2422 testBuildMessages();