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/protocol/HashPrefix.h>
25 #include <ripple/protocol/PublicKey.h>
26 #include <ripple/protocol/SecretKey.h>
27 #include <ripple/protocol/Sign.h>
28 #include <ripple/protocol/digest.h>
29 #include <ripple/protocol/jss.h>
135 for (
auto const& val : validators)
137 data +=
"{\"validation_public_key\":\"" +
strHex(val.masterPublic) +
138 "\",\"manifest\":\"" + val.manifest +
"\"},";
160 for (
auto const& pk : pks)
168 testcase(
"Genesis Quorum");
172 auto& app = env.
app();
174 auto trustedKeys = std::make_unique<ValidatorList>(
178 app.config().legacy(
"database_path"),
180 BEAST_EXPECT(trustedKeys->quorum() == 1);
184 auto trustedKeys = std::make_unique<ValidatorList>(
188 app.config().legacy(
"database_path"),
191 BEAST_EXPECT(trustedKeys->quorum() == minQuorum);
198 testcase(
"Config Load");
201 auto& app = env.
app();
207 auto const localSigningPublicOuter = localSigningKeys.first;
208 auto const localSigningSecret = localSigningKeys.second;
210 auto const localMasterPublic =
216 localSigningPublicOuter,
220 auto format = [](
PublicKey const& publicKey,
221 char const* comment =
nullptr) {
233 while (configList.
size() != 8)
238 {format(configList[0]),
239 format(configList[1],
" Comment"),
240 format(configList[2],
" Multi Word Comment"),
241 format(configList[3],
" Leading Whitespace"),
242 format(configList[4],
" Trailing Whitespace "),
243 format(configList[5],
" Leading & Trailing Whitespace "),
246 " Leading, Trailing & Internal Whitespace "),
247 format(configList[7],
" ")});
251 auto trustedKeys = std::make_unique<ValidatorList>(
255 app.config().legacy(
"database_path"),
259 BEAST_EXPECT(trustedKeys->load(
260 emptyLocalKey, emptyCfgKeys, emptyCfgPublishers));
263 BEAST_EXPECT(trustedKeys->load(
264 localSigningPublicOuter, emptyCfgKeys, emptyCfgPublishers));
265 BEAST_EXPECT(trustedKeys->listed(localSigningPublicOuter));
268 BEAST_EXPECT(trustedKeys->load(
269 localSigningPublicOuter, emptyCfgKeys, emptyCfgPublishers));
271 BEAST_EXPECT(trustedKeys->listed(localMasterPublic));
272 BEAST_EXPECT(trustedKeys->listed(localSigningPublicOuter));
277 auto trustedKeys = std::make_unique<ValidatorList>(
281 app.config().legacy(
"database_path"),
285 trustedKeys->load(emptyLocalKey, cfgKeys, emptyCfgPublishers));
287 for (
auto const& n : configList)
288 BEAST_EXPECT(trustedKeys->listed(n));
295 {format(masterNode1), format(masterNode2,
" Comment")});
296 BEAST_EXPECT(trustedKeys->load(
297 emptyLocalKey, cfgMasterKeys, emptyCfgPublishers));
298 BEAST_EXPECT(trustedKeys->listed(masterNode1));
299 BEAST_EXPECT(trustedKeys->listed(masterNode2));
302 BEAST_EXPECT(!trustedKeys->load(
303 emptyLocalKey, {
"NotAPublicKey"}, emptyCfgPublishers));
304 BEAST_EXPECT(!trustedKeys->load(
306 {format(randomNode(),
"!")},
307 emptyCfgPublishers));
311 BEAST_EXPECT(!trustedKeys->load(
313 {format(randomNode(),
"!"), format(goodKey)},
314 emptyCfgPublishers));
315 BEAST_EXPECT(!trustedKeys->listed(goodKey));
320 auto trustedKeys = std::make_unique<ValidatorList>(
324 app.config().legacy(
"database_path"),
327 auto const localSigningPublic =
330 BEAST_EXPECT(trustedKeys->load(
331 *localSigningPublic, cfgKeys, emptyCfgPublishers));
333 BEAST_EXPECT(trustedKeys->localPublicKey() == localSigningPublic);
334 BEAST_EXPECT(trustedKeys->listed(*localSigningPublic));
335 for (
auto const& n : configList)
336 BEAST_EXPECT(trustedKeys->listed(n));
341 auto trustedKeys = std::make_unique<ValidatorList>(
345 app.config().legacy(
"database_path"),
349 BEAST_EXPECT(trustedKeys->load(
350 localSigningPublic, cfgKeys, emptyCfgPublishers));
352 BEAST_EXPECT(trustedKeys->localPublicKey() == localSigningPublic);
353 BEAST_EXPECT(trustedKeys->listed(localSigningPublic));
354 for (
auto const& n : configList)
355 BEAST_EXPECT(trustedKeys->listed(n));
360 auto trustedKeys = std::make_unique<ValidatorList>(
364 app.config().legacy(
"database_path"),
369 BEAST_EXPECT(trustedKeys->load(
370 localSigningPublicOuter, cfgKeys, emptyCfgPublishers));
372 BEAST_EXPECT(trustedKeys->localPublicKey() == localMasterPublic);
373 BEAST_EXPECT(trustedKeys->listed(localSigningPublicOuter));
374 BEAST_EXPECT(trustedKeys->listed(localMasterPublic));
375 for (
auto const& n : configList)
376 BEAST_EXPECT(trustedKeys->listed(n));
380 auto trustedKeys = std::make_unique<ValidatorList>(
384 app.config().legacy(
"database_path"),
390 !trustedKeys->load(emptyLocalKey, emptyCfgKeys, badPublishers));
396 badPublishers.
clear();
397 for (
auto const& key : keys)
401 !trustedKeys->load(emptyLocalKey, emptyCfgKeys, badPublishers));
402 for (
auto const& key : keys)
403 BEAST_EXPECT(!trustedKeys->trustedPublisher(key));
407 for (
auto const& key : keys)
411 trustedKeys->load(emptyLocalKey, emptyCfgKeys, cfgPublishers));
412 for (
auto const& key : keys)
413 BEAST_EXPECT(trustedKeys->trustedPublisher(key));
420 auto trustedKeys = std::make_unique<ValidatorList>(
424 app.config().legacy(
"database_path"),
428 auto const pubRevokedPublic =
436 pubRevokedSigning.first,
437 pubRevokedSigning.second,
446 trustedKeys->load(emptyLocalKey, emptyCfgKeys, cfgPublishers));
448 BEAST_EXPECT(!trustedKeys->trustedPublisher(pubRevokedPublic));
449 BEAST_EXPECT(trustedKeys->trustedPublisher(legitKey));
456 testcase(
"Apply list");
462 auto& app = env.
app();
463 auto trustedKeys = std::make_unique<ValidatorList>(
467 app.config().legacy(
"database_path"),
471 auto const publisherPublic =
477 pubSigningKeys1.first,
478 pubSigningKeys1.second,
485 BEAST_EXPECT(trustedKeys->load(emptyLocalKey, emptyCfgKeys, cfgKeys1));
487 auto constexpr listSize = 20;
490 while (list1.
size() < listSize)
495 while (list2.
size() < listSize)
499 auto const version = 1;
500 auto const sequence = 1;
503 auto const expiredSig =
signList(expiredblob, pubSigningKeys1);
509 manifest1, expiredblob, expiredSig, version, siteUri)
513 using namespace std::chrono_literals;
517 auto const sig1 =
signList(blob1, pubSigningKeys1);
521 trustedKeys->applyList(manifest1, blob1, sig1, version, siteUri)
524 for (
auto const& val : list1)
526 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
527 BEAST_EXPECT(trustedKeys->listed(val.signingPublic));
534 pubSigningKeys1.first,
535 pubSigningKeys1.second,
541 ->applyList(untrustedManifest, blob1, sig1, version, siteUri)
545 auto const badVersion = 666;
548 trustedKeys->applyList(manifest1, blob1, sig1, badVersion, siteUri)
552 auto const sequence2 = 2;
555 auto const sig2 =
signList(blob2, pubSigningKeys1);
559 trustedKeys->applyList(manifest1, blob2, sig2, version, siteUri)
562 for (
auto const& val : list1)
564 BEAST_EXPECT(!trustedKeys->listed(val.masterPublic));
565 BEAST_EXPECT(!trustedKeys->listed(val.signingPublic));
568 for (
auto const& val : list2)
570 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
571 BEAST_EXPECT(trustedKeys->listed(val.signingPublic));
574 const auto hexPublic =
575 strHex(publisherPublic.begin(), publisherPublic.end());
577 const auto available = trustedKeys->getAvailable(hexPublic);
579 if (BEAST_EXPECT(available))
581 auto const& a = *available;
582 BEAST_EXPECT(a[jss::public_key] == hexPublic);
583 BEAST_EXPECT(a[jss::blob] == blob2);
584 BEAST_EXPECT(a[jss::manifest] == manifest1);
585 BEAST_EXPECT(a[jss::version] == version);
586 BEAST_EXPECT(a[jss::signature] == sig2);
592 trustedKeys->applyList(manifest1, blob1, sig1, version, siteUri)
597 trustedKeys->applyList(manifest1, blob2, sig2, version, siteUri)
605 pubSigningKeys2.first,
606 pubSigningKeys2.second,
609 auto const sequence3 = 3;
612 auto const sig3 =
signList(blob3, pubSigningKeys2);
616 trustedKeys->applyList(manifest2, blob3, sig3, version, siteUri)
619 auto const sequence4 = 4;
622 auto const badSig =
signList(blob4, pubSigningKeys1);
625 trustedKeys->applyList(manifest1, blob4, badSig, version, siteUri)
634 auto const sequence5 = 5;
637 auto const sig5 =
signList(blob5, signingKeysMax);
641 trustedKeys->applyList(maxManifest, blob5, sig5, version, siteUri)
644 BEAST_EXPECT(!trustedKeys->trustedPublisher(publisherPublic));
645 for (
auto const& val : list1)
647 BEAST_EXPECT(!trustedKeys->listed(val.masterPublic));
648 BEAST_EXPECT(!trustedKeys->listed(val.signingPublic));
655 testcase(
"Update trusted");
657 std::string const siteUri =
"testUpdateTrusted.test";
662 auto& app = env.
app();
663 auto trustedKeysOuter = std::make_unique<ValidatorList>(
667 app.config().legacy(
"database_path"),
679 while (cfgKeys.
size() != maxKeys)
683 if (cfgKeys.
size() <= maxKeys - 5)
689 BEAST_EXPECT(trustedKeysOuter->load(
690 emptyLocalKeyOuter, cfgKeys, cfgPublishersOuter));
695 trustedKeysOuter->updateTrusted(activeValidatorsOuter);
697 for (
auto const& val : unseenValidators)
698 activeValidatorsOuter.
emplace(val);
700 BEAST_EXPECT(changes.
added == activeValidatorsOuter);
701 BEAST_EXPECT(changes.
removed.empty());
703 trustedKeysOuter->quorum() ==
std::ceil(cfgKeys.
size() * 0.8f));
704 for (
auto const& val : cfgKeys)
706 if (
auto const valKey =
709 BEAST_EXPECT(trustedKeysOuter->listed(*valKey));
710 BEAST_EXPECT(trustedKeysOuter->trusted(*valKey));
716 changes = trustedKeysOuter->updateTrusted(activeValidatorsOuter);
717 BEAST_EXPECT(changes.
added.empty());
718 BEAST_EXPECT(changes.
removed.empty());
720 trustedKeysOuter->quorum() ==
std::ceil(cfgKeys.size() * 0.8f));
725 auto const masterPublic =
731 BEAST_EXPECT(trustedKeysOuter->load(
732 emptyLocalKeyOuter, cfgKeys, cfgPublishersOuter));
735 auto const signingPublic1 = signingKeys1.first;
740 trustedKeysOuter->updateTrusted(activeValidatorsOuter);
742 BEAST_EXPECT(changes.
removed.empty());
744 trustedKeysOuter->quorum() ==
std::ceil((maxKeys + 1) * 0.8f));
745 BEAST_EXPECT(trustedKeysOuter->listed(masterPublic));
746 BEAST_EXPECT(trustedKeysOuter->trusted(masterPublic));
747 BEAST_EXPECT(!trustedKeysOuter->listed(signingPublic1));
748 BEAST_EXPECT(!trustedKeysOuter->trusted(signingPublic1));
761 BEAST_EXPECT(trustedKeysOuter->listed(masterPublic));
762 BEAST_EXPECT(trustedKeysOuter->trusted(masterPublic));
763 BEAST_EXPECT(trustedKeysOuter->listed(signingPublic1));
764 BEAST_EXPECT(trustedKeysOuter->trusted(signingPublic1));
769 auto const signingPublic2 = signingKeys2.first;
779 BEAST_EXPECT(trustedKeysOuter->listed(masterPublic));
780 BEAST_EXPECT(trustedKeysOuter->trusted(masterPublic));
781 BEAST_EXPECT(trustedKeysOuter->listed(signingPublic2));
782 BEAST_EXPECT(trustedKeysOuter->trusted(signingPublic2));
783 BEAST_EXPECT(!trustedKeysOuter->listed(signingPublic1));
784 BEAST_EXPECT(!trustedKeysOuter->trusted(signingPublic1));
788 auto const signingPublicMax = signingKeysMax.first;
793 BEAST_EXPECT(mMax->revoked());
799 BEAST_EXPECT(manifestsOuter.
revoked(masterPublic));
802 BEAST_EXPECT(trustedKeysOuter->listed(masterPublic));
803 BEAST_EXPECT(trustedKeysOuter->trusted(masterPublic));
805 changes = trustedKeysOuter->updateTrusted(activeValidatorsOuter);
807 BEAST_EXPECT(changes.
added.empty());
809 trustedKeysOuter->quorum() ==
std::ceil(maxKeys * 0.8f));
810 BEAST_EXPECT(trustedKeysOuter->listed(masterPublic));
811 BEAST_EXPECT(!trustedKeysOuter->trusted(masterPublic));
812 BEAST_EXPECT(!trustedKeysOuter->listed(signingPublicMax));
813 BEAST_EXPECT(!trustedKeysOuter->trusted(signingPublicMax));
814 BEAST_EXPECT(!trustedKeysOuter->listed(signingPublic2));
815 BEAST_EXPECT(!trustedKeysOuter->trusted(signingPublic2));
816 BEAST_EXPECT(!trustedKeysOuter->listed(signingPublic1));
817 BEAST_EXPECT(!trustedKeysOuter->trusted(signingPublic1));
822 auto trustedKeys = std::make_unique<ValidatorList>(
826 app.config().legacy(
"database_path"),
829 auto const publisherPublic =
835 BEAST_EXPECT(trustedKeys->load(
836 emptyLocalKeyOuter, emptyCfgKeys, cfgPublishers));
839 trustedKeys->updateTrusted(activeValidatorsOuter);
840 BEAST_EXPECT(changes.
removed.empty());
841 BEAST_EXPECT(changes.
added.empty());
843 trustedKeys->quorum() ==
850 auto trustedKeys = std::make_unique<ValidatorList>(
854 app.config().legacy(
"database_path"),
865 while (cfgKeys.
size() < n)
876 BEAST_EXPECT(trustedKeys->load(
877 emptyLocalKeyOuter, cfgKeys, cfgPublishersOuter));
879 TrustChanges changes = trustedKeys->updateTrusted(activeValidators);
880 BEAST_EXPECT(changes.
removed.empty());
881 BEAST_EXPECT(changes.
added == expectedTrusted);
882 BEAST_EXPECT(trustedKeys->quorum() == minQuorum);
885 activeValidators.
emplace(toBeSeen);
886 changes = trustedKeys->updateTrusted(activeValidators);
887 BEAST_EXPECT(changes.
removed.empty());
888 BEAST_EXPECT(changes.
added.empty());
889 BEAST_EXPECT(trustedKeys->quorum() ==
std::ceil(n * 0.8f));
893 auto trustedKeys = std::make_unique<ValidatorList>(
897 app.config().legacy(
"database_path"),
906 publisherKeys.second,
907 pubSigningKeys.first,
908 pubSigningKeys.second,
914 trustedKeys->load(emptyLocalKey, emptyCfgKeys, cfgKeys));
918 asNodeIDs({list[0].masterPublic, list[1].masterPublic}));
921 auto const version = 1;
922 auto const sequence = 1;
923 using namespace std::chrono_literals;
932 trustedKeys->applyList(
manifest, blob,
sig, version, siteUri)
935 TrustChanges changes = trustedKeys->updateTrusted(activeValidators);
936 BEAST_EXPECT(changes.
removed.empty());
937 BEAST_EXPECT(changes.
added == activeValidators);
940 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
941 BEAST_EXPECT(trustedKeys->trusted(val.signingPublic));
943 BEAST_EXPECT(trustedKeys->quorum() == 2);
946 changes = trustedKeys->updateTrusted(activeValidators);
947 BEAST_EXPECT(changes.
removed == activeValidators);
948 BEAST_EXPECT(changes.
added.empty());
949 BEAST_EXPECT(!trustedKeys->trusted(list[0].masterPublic));
950 BEAST_EXPECT(!trustedKeys->trusted(list[1].masterPublic));
952 trustedKeys->quorum() ==
958 auto const sequence2 = 2;
963 auto const sig2 =
signList(blob2, pubSigningKeys);
967 trustedKeys->applyList(
manifest, blob2, sig2, version, siteUri)
970 changes = trustedKeys->updateTrusted(activeValidators);
971 BEAST_EXPECT(changes.
removed.empty());
974 asNodeIDs({list2[0].masterPublic, list2[1].masterPublic}));
977 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
978 BEAST_EXPECT(trustedKeys->trusted(val.signingPublic));
980 BEAST_EXPECT(!trustedKeys->trusted(list[1].masterPublic));
981 BEAST_EXPECT(!trustedKeys->trusted(list[1].signingPublic));
982 BEAST_EXPECT(trustedKeys->quorum() == 2);
986 auto trustedKeys = std::make_unique<ValidatorList>(
990 app.config().legacy(
"database_path"),
1006 BEAST_EXPECT(trustedKeys->load(
1007 emptyLocalKeyOuter, cfgKeys, cfgPublishers));
1009 trustedKeys->updateTrusted(activeValidators);
1010 BEAST_EXPECT(changes.
removed.empty());
1014 for (
auto const& key : activeKeys)
1015 BEAST_EXPECT(trustedKeys->trusted(key));
1020 auto trustedKeys = std::make_unique<ValidatorList>(
1024 app.config().legacy(
"database_path"),
1035 while (cfgKeys.size() < cfgKeys.capacity())
1043 trustedKeys->load(localKey, cfgKeys, cfgPublishers));
1045 trustedKeys->updateTrusted(activeValidators);
1046 BEAST_EXPECT(changes.
removed.empty());
1047 if (cfgKeys.size() > 2)
1054 trustedKeys->quorum() ==
std::ceil(cfgKeys.size() * 0.8f));
1056 for (
auto const& key : activeKeys)
1057 BEAST_EXPECT(trustedKeys->trusted(key));
1063 auto trustedKeys = std::make_unique<ValidatorList>(
1067 app.config().legacy(
"database_path"),
1074 while (valKeys.
size() != maxKeys)
1081 auto addPublishedList = [
this,
1087 auto const publisherPublic =
1093 pubSigningKeys.first,
1094 pubSigningKeys.second,
1098 {
strHex(publisherPublic)});
1102 BEAST_EXPECT(trustedKeys->load(
1103 emptyLocalKey, emptyCfgKeys, cfgPublishers));
1105 auto const version = 1;
1106 auto const sequence = 1;
1107 using namespace std::chrono_literals;
1111 valKeys, sequence,
expiration.time_since_epoch().count());
1117 ->applyList(
manifest, blob,
sig, version, siteUri)
1122 for (
auto i = 0; i < 3; ++i)
1125 TrustChanges changes = trustedKeys->updateTrusted(activeValidators);
1128 trustedKeys->quorum() ==
std::ceil(valKeys.size() * 0.8f));
1131 for (
auto const& val : valKeys)
1133 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
1136 BEAST_EXPECT(changes.
added == added);
1137 BEAST_EXPECT(changes.
removed.empty());
1144 testcase(
"Expires");
1149 auto& app = env.
app();
1151 auto toStr = [](
PublicKey const& publicKey) {
1158 auto trustedKeys = std::make_unique<ValidatorList>(
1162 app.config().legacy(
"database_path"),
1166 BEAST_EXPECT(trustedKeys->expires() == boost::none);
1171 trustedKeys->load(emptyLocalKey, {toStr(localCfgListed)}, {});
1173 trustedKeys->expires() &&
1175 BEAST_EXPECT(trustedKeys->listed(localCfgListed));
1181 auto trustedKeys = std::make_unique<ValidatorList>(
1185 app.config().legacy(
"database_path"),
1202 using namespace std::chrono_literals;
1203 auto addPublishedList = [
this, &env, &trustedKeys, &validators]() {
1205 auto const publisherPublic =
1211 pubSigningKeys.first,
1212 pubSigningKeys.second,
1216 {
strHex(publisherPublic)});
1220 BEAST_EXPECT(trustedKeys->load(
1221 emptyLocalKey, emptyCfgKeys, cfgPublishers));
1223 auto const version = 1;
1224 auto const sequence = 1;
1237 PreparedList prep1 = addPublishedList();
1239 PreparedList prep2 = addPublishedList();
1242 BEAST_EXPECT(trustedKeys->expires() == boost::none);
1257 BEAST_EXPECT(trustedKeys->expires() == boost::none);
1273 trustedKeys->expires() &&
1274 trustedKeys->expires().get() == prep1.expiration);
1279 trustedKeys->updateTrusted(activeValidators);
1281 trustedKeys->expires() &&
1282 trustedKeys->expires().get() == prep1.expiration);
1289 testcase(
"NegativeUNL");
1294 auto createValidatorList =
1296 boost::optional<std::size_t> minimumQuorum = {})
1298 auto trustedKeys = std::make_shared<ValidatorList>(
1316 if (trustedKeys->load(emptyLocalKey, cfgKeys, cfgPublishers))
1318 trustedKeys->updateTrusted(activeValidators);
1319 if (trustedKeys->quorum() ==
std::ceil(cfgKeys.
size() * 0.8f))
1344 for (
auto us : unlSizes)
1346 for (
auto np : nUnlPercent)
1348 auto validators = createValidatorList(us);
1349 BEAST_EXPECT(validators);
1353 auto unl = validators->getTrustedMasterKeys();
1355 auto it = unl.
begin();
1361 validators->setNegativeUNL(nUnl);
1362 validators->updateTrusted(activeValidators);
1364 validators->quorum() ==
1366 std::max((us - nUnlSize) * 0.8f, us * 0.6f))));
1374 auto validators = createValidatorList(60);
1375 BEAST_EXPECT(validators);
1379 auto unl = validators->getTrustedMasterKeys();
1380 BEAST_EXPECT(unl.size() == 60);
1387 auto it = unl.
begin();
1393 validators->setNegativeUNL(nUnl);
1394 auto nUnl_temp = validators->getNegativeUNL();
1395 if (nUnl_temp.size() == nUnl.
size())
1397 for (
auto& n : nUnl_temp)
1399 if (nUnl.
find(n) == nUnl.
end())
1402 validators->updateTrusted(activeValidators);
1403 return validators->quorum() == quorum;
1407 BEAST_EXPECT(nUnlChange(0, 48));
1408 BEAST_EXPECT(nUnlChange(30, 36));
1409 BEAST_EXPECT(nUnlChange(18, 36));
1410 BEAST_EXPECT(nUnlChange(12, 39));
1415 auto nUnl = validators->getNegativeUNL();
1416 BEAST_EXPECT(nUnl.size() == 12);
1420 for (
int i = 0; i < 6; ++i)
1422 Slice s(data.data(), ss);
1426 validators->setNegativeUNL(nUnl);
1427 validators->updateTrusted(activeValidators);
1428 BEAST_EXPECT(validators->quorum() == 39);
1437 auto validators = createValidatorList(60, 30);
1438 BEAST_EXPECT(validators);
1443 auto it = unl.
begin();
1449 validators->updateTrusted(activeValidators);
1450 BEAST_EXPECT(validators->quorum() == 48);
1458 validators->setNegativeUNL(nUnl);
1459 validators->updateTrusted(activeValidators);
1460 BEAST_EXPECT(validators->quorum() == 30);