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>
34 #include <boost/beast/core/multi_buffer.hpp>
140 data +=
",\"validators\":[";
142 for (
auto const& val : validators)
144 data +=
"{\"validation_public_key\":\"" +
strHex(val.masterPublic) +
145 "\",\"manifest\":\"" + val.manifest +
"\"},";
167 for (
auto const& pk : pks)
189 testcase(
"Genesis Quorum");
193 auto& app = env.
app();
195 auto trustedKeys = std::make_unique<ValidatorList>(
199 app.config().legacy(
"database_path"),
201 BEAST_EXPECT(trustedKeys->quorum() == 1);
205 auto trustedKeys = std::make_unique<ValidatorList>(
209 app.config().legacy(
"database_path"),
212 BEAST_EXPECT(trustedKeys->quorum() == minQuorum);
219 testcase(
"Config Load");
223 auto& app = env.
app();
229 auto const localSigningPublicOuter = localSigningKeys.first;
230 auto const localSigningSecret = localSigningKeys.second;
232 auto const localMasterPublic =
238 localSigningPublicOuter,
242 auto format = [](
PublicKey const& publicKey,
243 char const* comment =
nullptr) {
255 while (configList.
size() != 8)
260 {format(configList[0]),
261 format(configList[1],
" Comment"),
262 format(configList[2],
" Multi Word Comment"),
263 format(configList[3],
" Leading Whitespace"),
264 format(configList[4],
" Trailing Whitespace "),
265 format(configList[5],
" Leading & Trailing Whitespace "),
268 " Leading, Trailing & Internal Whitespace "),
269 format(configList[7],
" ")});
273 auto trustedKeys = std::make_unique<ValidatorList>(
277 app.config().legacy(
"database_path"),
281 BEAST_EXPECT(trustedKeys->load(
282 emptyLocalKey, emptyCfgKeys, emptyCfgPublishers));
285 BEAST_EXPECT(trustedKeys->load(
286 localSigningPublicOuter, emptyCfgKeys, emptyCfgPublishers));
287 BEAST_EXPECT(trustedKeys->listed(localSigningPublicOuter));
290 BEAST_EXPECT(trustedKeys->load(
291 localSigningPublicOuter, emptyCfgKeys, emptyCfgPublishers));
293 BEAST_EXPECT(trustedKeys->listed(localMasterPublic));
294 BEAST_EXPECT(trustedKeys->listed(localSigningPublicOuter));
299 auto trustedKeys = std::make_unique<ValidatorList>(
303 app.config().legacy(
"database_path"),
307 trustedKeys->load(emptyLocalKey, cfgKeys, emptyCfgPublishers));
309 for (
auto const& n : configList)
310 BEAST_EXPECT(trustedKeys->listed(n));
317 {format(masterNode1), format(masterNode2,
" Comment")});
318 BEAST_EXPECT(trustedKeys->load(
319 emptyLocalKey, cfgMasterKeys, emptyCfgPublishers));
320 BEAST_EXPECT(trustedKeys->listed(masterNode1));
321 BEAST_EXPECT(trustedKeys->listed(masterNode2));
324 BEAST_EXPECT(!trustedKeys->load(
325 emptyLocalKey, {
"NotAPublicKey"}, emptyCfgPublishers));
326 BEAST_EXPECT(!trustedKeys->load(
328 {format(randomNode(),
"!")},
329 emptyCfgPublishers));
333 BEAST_EXPECT(!trustedKeys->load(
335 {format(randomNode(),
"!"), format(goodKey)},
336 emptyCfgPublishers));
337 BEAST_EXPECT(!trustedKeys->listed(goodKey));
342 auto trustedKeys = std::make_unique<ValidatorList>(
346 app.config().legacy(
"database_path"),
349 auto const localSigningPublic =
352 BEAST_EXPECT(trustedKeys->load(
353 *localSigningPublic, cfgKeys, emptyCfgPublishers));
355 BEAST_EXPECT(trustedKeys->localPublicKey() == localSigningPublic);
356 BEAST_EXPECT(trustedKeys->listed(*localSigningPublic));
357 for (
auto const& n : configList)
358 BEAST_EXPECT(trustedKeys->listed(n));
363 auto trustedKeys = std::make_unique<ValidatorList>(
367 app.config().legacy(
"database_path"),
371 BEAST_EXPECT(trustedKeys->load(
372 localSigningPublic, cfgKeys, emptyCfgPublishers));
374 BEAST_EXPECT(trustedKeys->localPublicKey() == localSigningPublic);
375 BEAST_EXPECT(trustedKeys->listed(localSigningPublic));
376 for (
auto const& n : configList)
377 BEAST_EXPECT(trustedKeys->listed(n));
382 auto trustedKeys = std::make_unique<ValidatorList>(
386 app.config().legacy(
"database_path"),
391 BEAST_EXPECT(trustedKeys->load(
392 localSigningPublicOuter, cfgKeys, emptyCfgPublishers));
394 BEAST_EXPECT(trustedKeys->localPublicKey() == localMasterPublic);
395 BEAST_EXPECT(trustedKeys->listed(localSigningPublicOuter));
396 BEAST_EXPECT(trustedKeys->listed(localMasterPublic));
397 for (
auto const& n : configList)
398 BEAST_EXPECT(trustedKeys->listed(n));
402 auto trustedKeys = std::make_unique<ValidatorList>(
406 app.config().legacy(
"database_path"),
412 !trustedKeys->load(emptyLocalKey, emptyCfgKeys, badPublishers));
418 badPublishers.
clear();
419 for (
auto const& key : keys)
423 !trustedKeys->load(emptyLocalKey, emptyCfgKeys, badPublishers));
424 for (
auto const& key : keys)
425 BEAST_EXPECT(!trustedKeys->trustedPublisher(key));
429 for (
auto const& key : keys)
433 trustedKeys->load(emptyLocalKey, emptyCfgKeys, cfgPublishers));
434 for (
auto const& key : keys)
435 BEAST_EXPECT(trustedKeys->trustedPublisher(key));
442 auto trustedKeys = std::make_unique<ValidatorList>(
446 app.config().legacy(
"database_path"),
450 auto const pubRevokedPublic =
458 pubRevokedSigning.first,
459 pubRevokedSigning.second,
468 trustedKeys->load(emptyLocalKey, emptyCfgKeys, cfgPublishers));
470 BEAST_EXPECT(!trustedKeys->trustedPublisher(pubRevokedPublic));
471 BEAST_EXPECT(trustedKeys->trustedPublisher(legitKey));
478 testcase(
"Apply list");
479 using namespace std::chrono_literals;
483 auto checkAvailable =
485 auto const& trustedKeys,
486 auto const& hexPublic,
491 const auto available = trustedKeys->getAvailable(hexPublic);
497 BEAST_EXPECT(a[jss::public_key] == hexPublic);
498 BEAST_EXPECT(a[jss::manifest] ==
manifest);
501 BEAST_EXPECT(a[jss::version] == version);
504 BEAST_EXPECT(expected.size() == 1);
505 BEAST_EXPECT(a[jss::blob] == expected[0].first);
506 BEAST_EXPECT(a[jss::signature] == expected[0].second);
507 BEAST_EXPECT(!a.isMember(jss::blobs_v2));
509 else if (BEAST_EXPECT(a.isMember(jss::blobs_v2)))
511 BEAST_EXPECT(!a.isMember(jss::blob));
512 BEAST_EXPECT(!a.isMember(jss::signature));
513 auto const& blobs_v2 = a[jss::blobs_v2];
515 blobs_v2.isArray() &&
516 blobs_v2.size() == expected.size());
518 for (
unsigned int i = 0; i < expected.size(); ++i)
521 blobs_v2[i][jss::blob] == expected[i].first);
523 blobs_v2[i][jss::signature] ==
532 auto& app = env.
app();
533 auto trustedKeys = std::make_unique<ValidatorList>(
537 app.config().legacy(
"database_path"),
542 for (
auto const& val : list)
544 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
545 BEAST_EXPECT(trustedKeys->listed(val.signingPublic));
549 auto expectUntrusted =
551 for (
auto const& val : list)
553 BEAST_EXPECT(!trustedKeys->listed(val.masterPublic));
554 BEAST_EXPECT(!trustedKeys->listed(val.signingPublic));
559 auto const publisherPublic =
561 const auto hexPublic =
562 strHex(publisherPublic.begin(), publisherPublic.end());
567 pubSigningKeys1.first,
568 pubSigningKeys1.second,
575 BEAST_EXPECT(trustedKeys->load(emptyLocalKey, emptyCfgKeys, cfgKeys1));
578 auto constexpr listSize = 20;
579 auto constexpr numLists = 9;
582 for (
auto i = 1; i <= numLists; ++i)
584 auto& list = lists[i];
585 list.reserve(listSize);
586 while (list.size() < listSize)
594 auto const version = 1;
595 auto const sequence1 = 1;
600 auto const expiredSig =
signList(expiredblob, pubSigningKeys1);
603 auto const sequence2 = 2;
606 auto const sig2 =
signList(blob2, pubSigningKeys1);
609 trustedKeys->applyLists(
612 {{expiredblob, expiredSig, {}}, {blob2, sig2, {}}},
618 expectTrusted(lists.at(2));
621 trustedKeys, hexPublic, manifest1, version, {{blob2, sig2}});
624 auto const version2 = 2;
625 auto const sequence7 = 7;
626 auto const effective7 = validUntil - 60s;
627 auto const expiration7 = effective7 + 3600s;
631 expiration7.time_since_epoch().count(),
632 effective7.time_since_epoch().count());
633 auto const sig7 =
signList(blob7, pubSigningKeys1);
635 auto const sequence8 = 8;
636 auto const effective8 = expiration7 - 60s;
637 auto const expiration8 = effective8 + 3600s;
641 expiration8.time_since_epoch().count(),
642 effective8.time_since_epoch().count());
643 auto const sig8 =
signList(blob8, pubSigningKeys1);
646 trustedKeys->applyLists(
649 {{blob7, sig7, {}}, {blob8, sig8, {}}},
655 expectUntrusted(lists.at(7));
656 expectUntrusted(lists.at(8));
659 auto const sequence6 = 6;
660 auto const effective6 = effective7 - 60s;
661 auto const expiration6 = effective6 + 3600s;
662 auto const blob6 = makeList(
665 expiration6.time_since_epoch().count(),
666 effective6.time_since_epoch().count());
667 auto const sig6 = signList(blob6, pubSigningKeys1);
670 auto const sequence6a = 5;
671 auto const effective6a = effective6 + 60s;
672 auto const expiration6a = effective6a + 3600s;
673 auto const blob6a = makeList(
676 expiration6a.time_since_epoch().count(),
677 effective6a.time_since_epoch().count());
678 auto const sig6a = signList(blob6a, pubSigningKeys1);
681 trustedKeys->applyLists(
684 {{blob6a, sig6a, {}}, {blob6, sig6, {}}},
687 ListDisposition::pending,
688 ListDisposition::pending);
690 expectUntrusted(lists.at(6));
691 expectTrusted(lists.at(2));
696 trustedKeys->applyLists(
699 {{blob7, sig7, {}}, {blob6, sig6, {}}},
702 ListDisposition::known_sequence,
703 ListDisposition::known_sequence);
705 expectUntrusted(lists.at(6));
706 expectUntrusted(lists.at(7));
707 expectTrusted(lists.at(2));
710 auto const untrustedManifest =
base64_encode(makeManifestString(
713 pubSigningKeys1.first,
714 pubSigningKeys1.second,
718 trustedKeys->applyLists(
719 untrustedManifest, version, {{blob2, sig2, {}}}, siteUri),
721 ListDisposition::untrusted,
722 ListDisposition::untrusted);
725 auto const badVersion = 666;
727 trustedKeys->applyLists(
728 manifest1, badVersion, {{blob2, sig2, {}}}, siteUri),
730 ListDisposition::unsupported_version,
731 ListDisposition::unsupported_version);
734 auto const sequence3 = 3;
735 auto const blob3 = makeList(
736 lists.at(3), sequence3, validUntil.time_since_epoch().count());
737 auto const sig3 = signList(blob3, pubSigningKeys1);
740 trustedKeys->applyLists(
741 manifest1, version, {{blob3, sig3, {}}}, siteUri),
743 ListDisposition::accepted,
744 ListDisposition::accepted);
746 expectUntrusted(lists.at(1));
747 expectUntrusted(lists.at(2));
748 expectTrusted(lists.at(3));
757 {{blob3, sig3}, {blob6, sig6}, {blob7, sig7}, {blob8, sig8}});
761 trustedKeys->applyLists(
764 {{blob2, sig2, {}}, {blob3, sig3, {}}},
767 ListDisposition::stale,
768 ListDisposition::same_sequence);
772 auto const pubSigningKeys2 =
randomKeyPair(KeyType::secp256k1);
776 pubSigningKeys2.first,
777 pubSigningKeys2.second,
780 auto const sequence4 = 4;
781 auto const blob4 = makeList(
782 lists.at(4), sequence4, validUntil.time_since_epoch().count());
783 auto const sig4 = signList(blob4, pubSigningKeys2);
786 trustedKeys->applyLists(
789 {{blob2, sig2, manifest1},
790 {blob3, sig3, manifest1},
794 ListDisposition::stale,
795 ListDisposition::accepted);
797 expectUntrusted(lists.at(2));
798 expectUntrusted(lists.at(3));
799 expectTrusted(lists.at(4));
806 {{blob4, sig4}, {blob6, sig6}, {blob7, sig7}, {blob8, sig8}});
808 auto const sequence5 = 5;
809 auto const blob5 = makeList(
810 lists.at(5), sequence5, validUntil.time_since_epoch().count());
811 auto const badSig = signList(blob5, pubSigningKeys1);
813 trustedKeys->applyLists(
814 manifest1, version, {{blob5, badSig, {}}}, siteUri),
816 ListDisposition::invalid,
817 ListDisposition::invalid);
819 expectUntrusted(lists.at(2));
820 expectUntrusted(lists.at(3));
821 expectTrusted(lists.at(4));
822 expectUntrusted(lists.at(5));
826 trustedKeys->applyLists(
829 {{blob7, sig7, {}}, {blob8, sig8, {}}},
832 ListDisposition::invalid,
833 ListDisposition::invalid);
835 expectTrusted(lists.at(4));
836 expectUntrusted(lists.at(7));
837 expectUntrusted(lists.at(8));
842 trustedKeys->updateTrusted(
847 env.app().getHashRouter());
849 expectUntrusted(lists.at(3));
850 expectTrusted(lists.at(6));
857 {{blob6, sig6}, {blob7, sig7}, {blob8, sig8}});
863 env.timeKeeper().set(effective8);
864 trustedKeys->updateTrusted(
869 env.app().getHashRouter());
871 expectUntrusted(lists.at(6));
872 expectUntrusted(lists.at(7));
873 expectTrusted(lists.at(8));
875 checkAvailable(trustedKeys, hexPublic, manifest2, 2, {{blob8, sig8}});
881 auto const sig8_2 = signList(blob8, pubSigningKeys2);
884 trustedKeys->applyLists(
887 {{blob8, sig8, manifest1}, {blob8, sig8_2, {}}},
890 ListDisposition::invalid,
891 ListDisposition::same_sequence);
893 expectTrusted(lists.at(8));
895 checkAvailable(trustedKeys, hexPublic, manifest2, 2, {{blob8, sig8}});
899 auto const signingKeysMax =
randomKeyPair(KeyType::secp256k1);
901 makeRevocationString(publisherPublic, publisherSecret));
903 auto const sequence9 = 9;
904 auto const blob9 = makeList(
905 lists.at(9), sequence9, validUntil.time_since_epoch().count());
906 auto const sig9 = signList(blob9, signingKeysMax);
909 trustedKeys->applyLists(
910 maxManifest, version, {{blob9, sig9, {}}}, siteUri),
912 ListDisposition::untrusted,
913 ListDisposition::untrusted);
915 BEAST_EXPECT(!trustedKeys->trustedPublisher(publisherPublic));
916 for (
auto const& [num, list] : lists)
919 expectUntrusted(list);
922 checkAvailable(trustedKeys, hexPublic, manifest2, 0, {});
928 testcase(
"GetAvailable");
929 using namespace std::chrono_literals;
935 auto& app = env.
app();
936 auto trustedKeys = std::make_unique<ValidatorList>(
940 app.config().legacy(
"database_path"),
944 auto const publisherPublic =
946 const auto hexPublic =
947 strHex(publisherPublic.begin(), publisherPublic.end());
948 auto const pubSigningKeys1 =
randomKeyPair(KeyType::secp256k1);
952 pubSigningKeys1.first,
953 pubSigningKeys1.second,
960 BEAST_EXPECT(trustedKeys->load(emptyLocalKey, emptyCfgKeys, cfgKeys1));
963 auto constexpr listSize = 20;
966 while (list.
size() < listSize)
976 auto const sig = signList(blob, pubSigningKeys1);
980 auto const available = trustedKeys->getAvailable(hexPublic);
985 trustedKeys->applyLists(
manifest, 1, {{blob, sig, {}}}, siteUri)
986 .bestDisposition() == ListDisposition::accepted);
991 trustedKeys->getAvailable(hexPublic +
"invalid", 1);
992 BEAST_EXPECT(!available);
999 const auto hexBad =
strHex(badPublic.begin(), badPublic.end());
1001 auto const available = trustedKeys->getAvailable(hexBad, 1);
1002 BEAST_EXPECT(!available);
1006 auto const available = trustedKeys->getAvailable(hexPublic, 0);
1007 if (BEAST_EXPECT(available))
1009 auto const& a = *available;
1015 auto const available = trustedKeys->getAvailable(hexPublic, 3);
1016 if (BEAST_EXPECT(available))
1024 auto const available = trustedKeys->getAvailable(hexPublic, 1);
1025 if (BEAST_EXPECT(available))
1028 BEAST_EXPECT(a[jss::public_key] == hexPublic);
1029 BEAST_EXPECT(a[jss::manifest] == manifest);
1030 BEAST_EXPECT(a[jss::version] == 1);
1032 BEAST_EXPECT(a[jss::blob] == blob);
1033 BEAST_EXPECT(a[jss::signature] == sig);
1034 BEAST_EXPECT(!a.isMember(jss::blobs_v2));
1040 auto const available = trustedKeys->getAvailable(hexPublic, 2);
1041 if (BEAST_EXPECT(available))
1044 BEAST_EXPECT(a[jss::public_key] == hexPublic);
1045 BEAST_EXPECT(a[jss::manifest] == manifest);
1046 BEAST_EXPECT(a[jss::version] == 2);
1048 if (BEAST_EXPECT(a.isMember(jss::blobs_v2)))
1050 BEAST_EXPECT(!a.isMember(jss::blob));
1051 BEAST_EXPECT(!a.isMember(jss::signature));
1052 auto const& blobs_v2 = a[jss::blobs_v2];
1053 BEAST_EXPECT(blobs_v2.isArray() && blobs_v2.size() == 1);
1055 BEAST_EXPECT(blobs_v2[0u][jss::blob] == blob);
1056 BEAST_EXPECT(blobs_v2[0u][jss::signature] == sig);
1065 testcase(
"Update trusted");
1067 std::string const siteUri =
"testUpdateTrusted.test";
1072 auto& app = env.
app();
1073 auto trustedKeysOuter = std::make_unique<ValidatorList>(
1077 app.config().legacy(
"database_path"),
1089 while (cfgKeys.
size() != maxKeys)
1091 auto const valKey = randomNode();
1093 if (cfgKeys.
size() <= maxKeys - 5)
1099 BEAST_EXPECT(trustedKeysOuter->load(
1100 emptyLocalKeyOuter, cfgKeys, cfgPublishersOuter));
1104 TrustChanges changes = trustedKeysOuter->updateTrusted(
1105 activeValidatorsOuter,
1111 for (
auto const& val : unseenValidators)
1112 activeValidatorsOuter.
emplace(val);
1114 BEAST_EXPECT(changes.
added == activeValidatorsOuter);
1115 BEAST_EXPECT(changes.
removed.empty());
1117 trustedKeysOuter->quorum() ==
std::ceil(cfgKeys.
size() * 0.8f));
1118 for (
auto const& val : cfgKeys)
1120 if (
auto const valKey =
1121 parseBase58<PublicKey>(TokenType::NodePublic, val))
1123 BEAST_EXPECT(trustedKeysOuter->listed(*valKey));
1124 BEAST_EXPECT(trustedKeysOuter->trusted(*valKey));
1130 changes = trustedKeysOuter->updateTrusted(
1131 activeValidatorsOuter,
1136 BEAST_EXPECT(changes.
added.empty());
1137 BEAST_EXPECT(changes.
removed.empty());
1139 trustedKeysOuter->quorum() ==
std::ceil(cfgKeys.size() * 0.8f));
1144 auto const masterPublic =
1148 {
toBase58(TokenType::NodePublic, masterPublic)});
1150 BEAST_EXPECT(trustedKeysOuter->load(
1151 emptyLocalKeyOuter, cfgKeys, cfgPublishersOuter));
1153 auto const signingKeys1 =
randomKeyPair(KeyType::secp256k1);
1154 auto const signingPublic1 = signingKeys1.first;
1158 TrustChanges changes = trustedKeysOuter->updateTrusted(
1159 activeValidatorsOuter,
1164 BEAST_EXPECT(changes.
added == asNodeIDs({masterPublic}));
1165 BEAST_EXPECT(changes.
removed.empty());
1167 trustedKeysOuter->quorum() ==
std::ceil((maxKeys + 1) * 0.8f));
1168 BEAST_EXPECT(trustedKeysOuter->listed(masterPublic));
1169 BEAST_EXPECT(trustedKeysOuter->trusted(masterPublic));
1170 BEAST_EXPECT(!trustedKeysOuter->listed(signingPublic1));
1171 BEAST_EXPECT(!trustedKeysOuter->trusted(signingPublic1));
1178 signingKeys1.second,
1183 ManifestDisposition::accepted);
1184 BEAST_EXPECT(trustedKeysOuter->listed(masterPublic));
1185 BEAST_EXPECT(trustedKeysOuter->trusted(masterPublic));
1186 BEAST_EXPECT(trustedKeysOuter->listed(signingPublic1));
1187 BEAST_EXPECT(trustedKeysOuter->trusted(signingPublic1));
1191 auto const signingKeys2 =
randomKeyPair(KeyType::secp256k1);
1192 auto const signingPublic2 = signingKeys2.first;
1197 signingKeys2.second,
1201 ManifestDisposition::accepted);
1202 BEAST_EXPECT(trustedKeysOuter->listed(masterPublic));
1203 BEAST_EXPECT(trustedKeysOuter->trusted(masterPublic));
1204 BEAST_EXPECT(trustedKeysOuter->listed(signingPublic2));
1205 BEAST_EXPECT(trustedKeysOuter->trusted(signingPublic2));
1206 BEAST_EXPECT(!trustedKeysOuter->listed(signingPublic1));
1207 BEAST_EXPECT(!trustedKeysOuter->trusted(signingPublic1));
1210 auto const signingKeysMax =
randomKeyPair(KeyType::secp256k1);
1211 auto const signingPublicMax = signingKeysMax.first;
1214 makeRevocationString(masterPublic, masterPrivate));
1216 BEAST_EXPECT(mMax->revoked());
1219 ManifestDisposition::accepted);
1221 manifestsOuter.
getSigningKey(masterPublic) == masterPublic);
1222 BEAST_EXPECT(manifestsOuter.
revoked(masterPublic));
1225 BEAST_EXPECT(trustedKeysOuter->listed(masterPublic));
1226 BEAST_EXPECT(trustedKeysOuter->trusted(masterPublic));
1228 changes = trustedKeysOuter->updateTrusted(
1229 activeValidatorsOuter,
1234 BEAST_EXPECT(changes.
removed == asNodeIDs({masterPublic}));
1235 BEAST_EXPECT(changes.
added.empty());
1237 trustedKeysOuter->quorum() ==
std::ceil(maxKeys * 0.8f));
1238 BEAST_EXPECT(trustedKeysOuter->listed(masterPublic));
1239 BEAST_EXPECT(!trustedKeysOuter->trusted(masterPublic));
1240 BEAST_EXPECT(!trustedKeysOuter->listed(signingPublicMax));
1241 BEAST_EXPECT(!trustedKeysOuter->trusted(signingPublicMax));
1242 BEAST_EXPECT(!trustedKeysOuter->listed(signingPublic2));
1243 BEAST_EXPECT(!trustedKeysOuter->trusted(signingPublic2));
1244 BEAST_EXPECT(!trustedKeysOuter->listed(signingPublic1));
1245 BEAST_EXPECT(!trustedKeysOuter->trusted(signingPublic1));
1250 auto trustedKeys = std::make_unique<ValidatorList>(
1254 app.config().legacy(
"database_path"),
1257 auto const publisherPublic =
1263 BEAST_EXPECT(trustedKeys->load(
1264 emptyLocalKeyOuter, emptyCfgKeys, cfgPublishers));
1267 activeValidatorsOuter,
1272 BEAST_EXPECT(changes.
removed.empty());
1273 BEAST_EXPECT(changes.
added.empty());
1275 trustedKeys->quorum() ==
1282 auto trustedKeys = std::make_unique<ValidatorList>(
1286 app.config().legacy(
"database_path"),
1297 while (cfgKeys.
size() < n)
1299 auto const valKey = randomNode();
1308 BEAST_EXPECT(trustedKeys->load(
1309 emptyLocalKeyOuter, cfgKeys, cfgPublishersOuter));
1317 BEAST_EXPECT(changes.
removed.empty());
1318 BEAST_EXPECT(changes.
added == expectedTrusted);
1319 BEAST_EXPECT(trustedKeys->quorum() == minQuorum);
1322 activeValidators.
emplace(toBeSeen);
1323 changes = trustedKeys->updateTrusted(
1329 BEAST_EXPECT(changes.
removed.empty());
1330 BEAST_EXPECT(changes.
added.empty());
1331 BEAST_EXPECT(trustedKeys->quorum() == minQuorum);
1335 auto trustedKeys = std::make_unique<ValidatorList>(
1339 app.config().legacy(
"database_path"),
1344 auto const publisherKeys =
randomKeyPair(KeyType::secp256k1);
1345 auto const pubSigningKeys =
randomKeyPair(KeyType::secp256k1);
1347 publisherKeys.first,
1348 publisherKeys.second,
1349 pubSigningKeys.first,
1350 pubSigningKeys.second,
1356 trustedKeys->load(emptyLocalKey, emptyCfgKeys, cfgKeys));
1360 asNodeIDs({list[0].masterPublic, list[1].masterPublic}));
1363 auto const version = 1;
1364 auto const sequence = 1;
1365 using namespace std::chrono_literals;
1370 auto const sig = signList(blob, pubSigningKeys);
1373 ListDisposition::accepted ==
1375 ->applyLists(
manifest, version, {{blob,
sig, {}}}, siteUri)
1376 .bestDisposition());
1384 BEAST_EXPECT(changes.
removed.empty());
1385 BEAST_EXPECT(changes.
added == activeValidators);
1388 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
1389 BEAST_EXPECT(trustedKeys->trusted(val.signingPublic));
1391 BEAST_EXPECT(trustedKeys->quorum() == 2);
1394 changes = trustedKeys->updateTrusted(
1400 BEAST_EXPECT(changes.
removed == activeValidators);
1401 BEAST_EXPECT(changes.
added.empty());
1402 BEAST_EXPECT(!trustedKeys->trusted(list[0].masterPublic));
1403 BEAST_EXPECT(!trustedKeys->trusted(list[1].masterPublic));
1405 trustedKeys->quorum() ==
1411 auto const sequence2 = 2;
1414 auto const blob2 = makeList(
1416 auto const sig2 = signList(blob2, pubSigningKeys);
1419 ListDisposition::accepted ==
1422 manifest, version, {{blob2, sig2, {}}}, siteUri)
1423 .bestDisposition());
1425 changes = trustedKeys->updateTrusted(
1431 BEAST_EXPECT(changes.
removed.empty());
1434 asNodeIDs({list2[0].masterPublic, list2[1].masterPublic}));
1437 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
1438 BEAST_EXPECT(trustedKeys->trusted(val.signingPublic));
1440 BEAST_EXPECT(!trustedKeys->trusted(list[1].masterPublic));
1441 BEAST_EXPECT(!trustedKeys->trusted(list[1].signingPublic));
1442 BEAST_EXPECT(trustedKeys->quorum() == 2);
1446 auto trustedKeys = std::make_unique<ValidatorList>(
1450 app.config().legacy(
"database_path"),
1462 auto const valKey = randomNode();
1466 BEAST_EXPECT(trustedKeys->load(
1467 emptyLocalKeyOuter, cfgKeys, cfgPublishers));
1474 BEAST_EXPECT(changes.
removed.empty());
1475 BEAST_EXPECT(changes.
added == asNodeIDs({valKey}));
1478 for (
auto const& key : activeKeys)
1479 BEAST_EXPECT(trustedKeys->trusted(key));
1484 auto trustedKeys = std::make_unique<ValidatorList>(
1488 app.config().legacy(
"database_path"),
1491 auto const localKey = randomNode();
1496 toBase58(TokenType::NodePublic, localKey)};
1499 while (cfgKeys.size() < cfgKeys.capacity())
1501 auto const valKey = randomNode();
1502 cfgKeys.push_back(
toBase58(TokenType::NodePublic, valKey));
1507 trustedKeys->load(localKey, cfgKeys, cfgPublishers));
1514 BEAST_EXPECT(changes.
removed.empty());
1515 if (cfgKeys.size() > 2)
1516 BEAST_EXPECT(changes.
added == asNodeIDs({valKey}));
1519 changes.
added == asNodeIDs({localKey, valKey}));
1522 trustedKeys->quorum() ==
std::ceil(cfgKeys.size() * 0.8f));
1524 for (
auto const& key : activeKeys)
1525 BEAST_EXPECT(trustedKeys->trusted(key));
1531 auto trustedKeys = std::make_unique<ValidatorList>(
1535 app.config().legacy(
"database_path"),
1542 while (valKeys.
size() != maxKeys)
1549 auto addPublishedList = [
this,
1555 auto const publisherPublic =
1557 auto const pubSigningKeys =
randomKeyPair(KeyType::secp256k1);
1561 pubSigningKeys.first,
1562 pubSigningKeys.second,
1566 {
strHex(publisherPublic)});
1570 BEAST_EXPECT(trustedKeys->load(
1571 emptyLocalKey, emptyCfgKeys, cfgPublishers));
1573 auto const version = 1;
1574 auto const sequence = 1;
1575 using namespace std::chrono_literals;
1578 auto const blob = makeList(
1580 auto const sig = signList(blob, pubSigningKeys);
1583 ListDisposition::accepted ==
1587 .bestDisposition());
1591 for (
auto i = 0; i < 3; ++i)
1602 trustedKeys->quorum() ==
std::ceil(valKeys.size() * 0.8f));
1605 for (
auto const& val : valKeys)
1607 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
1610 BEAST_EXPECT(changes.
added == added);
1611 BEAST_EXPECT(changes.
removed.empty());
1618 testcase(
"Expires");
1623 auto& app = env.
app();
1625 auto toStr = [](
PublicKey const& publicKey) {
1626 return toBase58(TokenType::NodePublic, publicKey);
1632 auto trustedKeys = std::make_unique<ValidatorList>(
1636 app.config().legacy(
"database_path"),
1640 BEAST_EXPECT(trustedKeys->expires() == std::nullopt);
1644 PublicKey localCfgListed = randomNode();
1645 trustedKeys->load(emptyLocalKey, {toStr(localCfgListed)}, {});
1647 trustedKeys->expires() &&
1648 trustedKeys->expires().value() == NetClock::time_point::max());
1649 BEAST_EXPECT(trustedKeys->listed(localCfgListed));
1655 auto trustedKeys = std::make_unique<ValidatorList>(
1659 app.config().legacy(
"database_path"),
1676 using namespace std::chrono_literals;
1677 auto addPublishedList = [
this, &env, &trustedKeys, &validators]() {
1679 auto const publisherPublic =
1681 auto const pubSigningKeys =
randomKeyPair(KeyType::secp256k1);
1685 pubSigningKeys.first,
1686 pubSigningKeys.second,
1690 {
strHex(publisherPublic)});
1694 BEAST_EXPECT(trustedKeys->load(
1695 emptyLocalKey, emptyCfgKeys, cfgPublishers));
1697 auto const version = 2;
1698 auto const sequence1 = 1;
1701 auto const blob1 = makeList(
1705 auto const sig1 = signList(blob1, pubSigningKeys);
1709 auto const sequence2 = 2;
1710 auto const blob2 = makeList(
1715 auto const sig2 = signList(blob2, pubSigningKeys);
1717 return PreparedList{
1720 {{blob1, sig1, {}}, {blob2, sig2, {}}},
1722 {expiration1, expiration2}};
1726 PreparedList prep1 = addPublishedList();
1728 PreparedList prep2 = addPublishedList();
1731 BEAST_EXPECT(trustedKeys->expires() == std::nullopt);
1735 trustedKeys->applyLists(
1736 prep1.manifest, prep1.version, prep1.blobs, siteUri),
1737 prep1.publisherPublic,
1738 ListDisposition::pending,
1739 ListDisposition::accepted);
1743 BEAST_EXPECT(trustedKeys->expires() == std::nullopt);
1747 trustedKeys->applyLists(
1748 prep2.manifest, prep2.version, prep2.blobs, siteUri),
1749 prep2.publisherPublic,
1750 ListDisposition::pending,
1751 ListDisposition::accepted);
1754 trustedKeys->expires() &&
1755 trustedKeys->expires().value() == prep1.expirations.back());
1761 auto changes = trustedKeys->updateTrusted(
1768 trustedKeys->expires() &&
1769 trustedKeys->expires().value() == prep1.expirations.back());
1770 BEAST_EXPECT(!changes.added.empty());
1771 BEAST_EXPECT(changes.removed.empty());
1778 auto changes = trustedKeys->updateTrusted(
1785 trustedKeys->expires() &&
1786 trustedKeys->expires().value() == prep1.expirations.back());
1787 BEAST_EXPECT(changes.added.empty());
1788 BEAST_EXPECT(changes.removed.empty());
1796 testcase(
"NegativeUNL");
1801 auto createValidatorList =
1805 auto trustedKeys = std::make_shared<ValidatorList>(
1819 auto const valKey = randomNode();
1823 if (trustedKeys->load(emptyLocalKey, cfgKeys, cfgPublishers))
1825 trustedKeys->updateTrusted(
1831 if (minimumQuorum == trustedKeys->quorum() ||
1857 for (
auto us : unlSizes)
1859 for (
auto np : nUnlPercent)
1861 auto validators = createValidatorList(us);
1862 BEAST_EXPECT(validators);
1866 auto unl = validators->getTrustedMasterKeys();
1868 auto it = unl.
begin();
1874 validators->setNegativeUNL(nUnl);
1875 validators->updateTrusted(
1882 validators->quorum() ==
1884 std::max((us - nUnlSize) * 0.8f, us * 0.6f))));
1892 auto validators = createValidatorList(60);
1893 BEAST_EXPECT(validators);
1897 auto unl = validators->getTrustedMasterKeys();
1898 BEAST_EXPECT(unl.size() == 60);
1905 auto it = unl.
begin();
1911 validators->setNegativeUNL(nUnl);
1912 auto nUnl_temp = validators->getNegativeUNL();
1913 if (nUnl_temp.size() == nUnl.
size())
1915 for (
auto& n : nUnl_temp)
1917 if (nUnl.
find(n) == nUnl.
end())
1920 validators->updateTrusted(
1926 return validators->quorum() == quorum;
1930 BEAST_EXPECT(nUnlChange(0, 48));
1931 BEAST_EXPECT(nUnlChange(30, 36));
1932 BEAST_EXPECT(nUnlChange(18, 36));
1933 BEAST_EXPECT(nUnlChange(12, 39));
1939 auto nUnl = validators->getNegativeUNL();
1940 BEAST_EXPECT(nUnl.size() == 12);
1944 for (
int i = 0; i < 6; ++i)
1946 Slice s(data.data(), ss);
1950 validators->setNegativeUNL(nUnl);
1951 validators->updateTrusted(
1957 BEAST_EXPECT(validators->quorum() == 39);
1966 auto validators = createValidatorList(60, 30);
1967 BEAST_EXPECT(validators);
1972 auto it = unl.
begin();
1978 validators->updateTrusted(
1984 BEAST_EXPECT(validators->quorum() == 30);
1992 validators->setNegativeUNL(nUnl);
1993 validators->updateTrusted(
1999 BEAST_EXPECT(validators->quorum() == 30);
2007 testcase(
"Sha512 hashing");
2012 std::string const blob =
"This is not really a blob";
2013 std::string const signature =
"This is not really a signature";
2017 BEAST_EXPECT(!!global);
2020 blobVector[0].blob = blob;
2021 blobVector[0].signature = signature;
2023 BEAST_EXPECT(global !=
sha512Half(signature, blobVector, version));
2027 {99, blobVector[0]}};
2029 BEAST_EXPECT(global !=
sha512Half(blob, blobMap, version));
2033 protocol::TMValidatorList msg1;
2035 msg1.set_blob(blob);
2036 msg1.set_signature(signature);
2037 msg1.set_version(version);
2039 msg1.set_signature(blob);
2044 protocol::TMValidatorListCollection msg2;
2046 msg2.set_version(version);
2047 auto& bi = *msg2.add_blobs();
2049 bi.set_signature(signature);
2059 testcase(
"Build and split messages");
2062 auto extractHeader = [
this](
Message& message) {
2063 auto const& buffer =
2064 message.getBuffer(compression::Compressed::Off);
2066 boost::beast::multi_buffer buffers;
2069 auto start = buffer.begin();
2070 auto end = buffer.end();
2072 buffers.commit(boost::asio::buffer_copy(
2073 buffers.prepare(slice.
size()), boost::asio::buffer(slice)));
2075 boost::system::error_code ec;
2077 detail::parseMessageHeader(ec, buffers.data(), buffers.size());
2081 auto extractProtocolMessage1 = [
this,
2082 &extractHeader](
Message& message) {
2083 auto [header, buffers] = extractHeader(message);
2084 if (BEAST_EXPECT(header) &&
2085 BEAST_EXPECT(header->message_type == protocol::mtVALIDATORLIST))
2088 detail::parseMessageContent<protocol::TMValidatorList>(
2089 *header, buffers.data());
2095 auto extractProtocolMessage2 = [
this,
2096 &extractHeader](
Message& message) {
2097 auto [header, buffers] = extractHeader(message);
2098 if (BEAST_EXPECT(header) &&
2100 header->message_type ==
2101 protocol::mtVALIDATORLISTCOLLECTION))
2103 auto const msg = detail::parseMessageContent<
2104 protocol::TMValidatorListCollection>(
2105 *header, buffers.data());
2111 auto verifyMessage =
2114 &extractProtocolMessage1,
2115 &extractProtocolMessage2](
2118 auto const& blobInfos,
2119 auto const& messages,
2122 BEAST_EXPECT(messages.size() == expectedInfo.size());
2123 auto msgIter = expectedInfo.begin();
2124 for (
auto const& messageWithHash : messages)
2126 if (!BEAST_EXPECT(msgIter != expectedInfo.end()))
2128 if (!BEAST_EXPECT(messageWithHash.message))
2130 auto const& expectedSeqs = msgIter->second;
2131 auto seqIter = expectedSeqs.begin();
2133 messageWithHash.message
2134 ->getBuffer(compression::Compressed::Off)
2137 BEAST_EXPECT(size == msgIter->first);
2138 if (expectedSeqs.size() == 1)
2141 extractProtocolMessage1(*messageWithHash.message);
2142 auto const expectedVersion = 1;
2143 if (BEAST_EXPECT(msg))
2145 BEAST_EXPECT(msg->version() == expectedVersion);
2146 if (!BEAST_EXPECT(seqIter != expectedSeqs.end()))
2148 auto const& expectedBlob = blobInfos.at(*seqIter);
2150 (*seqIter < manifestCutoff) ==
2151 !!expectedBlob.manifest);
2152 auto const expectedManifest =
2153 *seqIter < manifestCutoff &&
2154 expectedBlob.manifest
2155 ? *expectedBlob.manifest
2157 BEAST_EXPECT(msg->manifest() == expectedManifest);
2158 BEAST_EXPECT(msg->blob() == expectedBlob.blob);
2160 msg->signature() == expectedBlob.signature);
2162 BEAST_EXPECT(seqIter == expectedSeqs.end());
2165 messageWithHash.hash ==
2169 expectedBlob.signature,
2176 hashingBlobs.
reserve(msgIter->second.size());
2179 extractProtocolMessage2(*messageWithHash.message);
2180 if (BEAST_EXPECT(msg))
2182 BEAST_EXPECT(msg->version() == version);
2183 BEAST_EXPECT(msg->manifest() ==
manifest);
2184 for (
auto const& blobInfo : msg->blobs())
2187 seqIter != expectedSeqs.end()))
2189 auto const& expectedBlob =
2190 blobInfos.at(*seqIter);
2193 blobInfo.has_manifest() ==
2194 !!expectedBlob.manifest);
2196 blobInfo.has_manifest() ==
2197 (*seqIter < manifestCutoff));
2199 if (*seqIter < manifestCutoff)
2201 blobInfo.manifest() ==
2202 *expectedBlob.manifest);
2204 blobInfo.blob() == expectedBlob.blob);
2206 blobInfo.signature() ==
2207 expectedBlob.signature);
2210 BEAST_EXPECT(seqIter == expectedSeqs.end());
2213 messageWithHash.hash ==
2218 BEAST_EXPECT(msgIter == expectedInfo.end());
2220 auto verifyBuildMessages =
2225 BEAST_EXPECT(result.
first == expectedSequence);
2226 BEAST_EXPECT(result.
second == expectedSize);
2232 auto const blobInfos = [manifestCutoff = manifestCutoff]() {
2235 for (
auto seq : {5, 6, 7, 10, 12})
2239 s <<
"This is not a blob with sequence " <<
seq;
2242 s <<
"This is not a signature for sequence " <<
seq;
2243 b.signature = s.
str();
2244 if (
seq < manifestCutoff)
2248 s <<
"This is not manifest " <<
seq;
2249 b.manifest = s.
str();
2254 auto const maxSequence = blobInfos.
rbegin()->first;
2255 BEAST_EXPECT(maxSequence == 12);
2262 verifyBuildMessages(
2263 ValidatorList::buildValidatorListMessages(
2264 1, 8, maxSequence, version,
manifest, blobInfos, messages),
2267 BEAST_EXPECT(messages.
size() == 0);
2274 verifyBuildMessages(
2275 ValidatorList::buildValidatorListMessages(
2276 1, 3, maxSequence, version,
manifest, blobInfos, messages),
2279 BEAST_EXPECT(messages.
size() == 1 && !messages.
front().message);
2283 verifyBuildMessages(
2284 ValidatorList::buildValidatorListMessages(
2285 1, 3, maxSequence, version,
manifest, blobInfos, messages),
2288 if (BEAST_EXPECT(messages.
size() == 1) &&
2289 BEAST_EXPECT(messages.
front().message))
2291 auto const& messageWithHash = messages.
front();
2292 auto const msg = extractProtocolMessage1(*messageWithHash.message);
2294 messageWithHash.message->getBuffer(compression::Compressed::Off)
2297 BEAST_EXPECT(size == 108);
2298 auto const& expected = blobInfos.at(5);
2299 if (BEAST_EXPECT(msg))
2301 BEAST_EXPECT(msg->version() == 1);
2302 BEAST_EXPECT(msg->manifest() == *expected.manifest);
2303 BEAST_EXPECT(msg->blob() == expected.blob);
2304 BEAST_EXPECT(msg->signature() == expected.signature);
2307 messageWithHash.hash ==
2309 *expected.manifest, expected.blob, expected.signature, 1));
2317 verifyBuildMessages(
2318 ValidatorList::buildValidatorListMessages(
2328 BEAST_EXPECT(messages.
size() == 0);
2335 verifyBuildMessages(
2336 ValidatorList::buildValidatorListMessages(
2337 2, 3, maxSequence, version,
manifest, blobInfos, messages),
2340 BEAST_EXPECT(messages.
size() == 1 && !messages.
front().message);
2344 verifyBuildMessages(
2345 ValidatorList::buildValidatorListMessages(
2346 2, 5, maxSequence, version,
manifest, blobInfos, messages),
2350 version,
manifest, blobInfos, messages, {{372, {6, 7, 10, 12}}});
2356 verifyBuildMessages(
2357 ValidatorList::buildValidatorListMessages(
2358 2, 5, maxSequence, version,
manifest, blobInfos, messages, 300),
2366 {{212, {6, 7}}, {192, {10, 12}}});
2371 verifyBuildMessages(
2372 ValidatorList::buildValidatorListMessages(
2373 2, 5, maxSequence, version,
manifest, blobInfos, messages, 200),
2381 {{108, {6}}, {108, {7}}, {192, {10, 12}}});
2385 verifyBuildMessages(
2386 ValidatorList::buildValidatorListMessages(
2387 2, 5, maxSequence, version,
manifest, blobInfos, messages, 150),
2395 {{108, {6}}, {108, {7}}, {110, {10}}, {110, {12}}});
2400 verifyBuildMessages(
2401 ValidatorList::buildValidatorListMessages(
2402 2, 5, maxSequence, version,
manifest, blobInfos, messages, 108),
2410 {{108, {6}}, {108, {7}}, {110, {10}}, {110, {12}}});
2417 testGenesisQuorum();
2421 testUpdateTrusted();
2425 testBuildMessages();