From dd991c5e87541fee7cc9ddc658321e7cea6734e0 Mon Sep 17 00:00:00 2001 From: bthomee Date: Thu, 8 Jan 2026 07:37:55 -0800 Subject: [PATCH] deploy: 53aa5ca90314b6a6ba7ebb43e20a40c09b6ffe60 --- InvariantCheck_8cpp_source.html | 6 +- LedgerMaster_8cpp_source.html | 2 +- LedgerReplayMsgHandler_8cpp_source.html | 2 +- Message_8cpp_source.html | 4 +- NetworkOPs_8cpp_source.html | 8 +- OverlayImpl_8cpp_source.html | 6 +- PeerImp_8cpp_source.html | 4 +- Permissions_8cpp_source.html | 8 +- Permissions_8h_source.html | 6 +- ProtocolMessage_8h_source.html | 8 +- RCLValidations_8cpp_source.html | 4 +- TrafficCount_8cpp_source.html | 4 +- UnlList_8cpp_source.html | 2 +- ValidatorList_8cpp_source.html | 3141 +++++++-------- ValidatorList_8h_source.html | 60 +- ValidatorList__test_8cpp_source.html | 3555 +++++++++-------- ValidatorSite_8cpp_source.html | 4 +- Validators_8cpp_source.html | 2 +- classxrpl_1_1ValidatorList.html | 72 +- classxrpl_1_1test_1_1ValidatorList__test.html | 4 +- compression__test_8cpp_source.html | 4 +- namespacemembers_d.html | 2 +- namespacemembers_eval_d.html | 2 +- namespacemembers_eval_n.html | 2 +- namespacemembers_n.html | 2 +- namespacexrpl.html | 12 +- search/all_15.js | 2 +- search/all_b.js | 4 +- search/enumvalues_4.js | 2 +- search/enumvalues_e.js | 2 +- 30 files changed, 3469 insertions(+), 3467 deletions(-) diff --git a/InvariantCheck_8cpp_source.html b/InvariantCheck_8cpp_source.html index ae9b755cca..416fa2d812 100644 --- a/InvariantCheck_8cpp_source.html +++ b/InvariantCheck_8cpp_source.html @@ -171,9 +171,9 @@ $(document).ready(function() { init_codefold(0); });
84#pragma push_macro("TRANSACTION")
85#undef TRANSACTION
86
-
87#define TRANSACTION(tag, value, name, delegatable, amendment, privileges, ...) \
-
88 case tag: { \
-
89 return (privileges) & priv; \
+
87#define TRANSACTION(tag, value, name, delegable, amendment, privileges, ...) \
+
88 case tag: { \
+
89 return (privileges) & priv; \
90 }
91
92bool
diff --git a/LedgerMaster_8cpp_source.html b/LedgerMaster_8cpp_source.html index 9f83377442..d82c3f48c3 100644 --- a/LedgerMaster_8cpp_source.html +++ b/LedgerMaster_8cpp_source.html @@ -2657,7 +2657,7 @@ $(document).ready(function() { init_codefold(0); });
std::vector< std::uint32_t > fees(ID const &ledgerID, std::uint32_t baseFee)
Returns fees reported by trusted full validators in the given ledger.
QuorumKeys getQuorumKeys() const
Get the quorum and all of the trusted keys.
std::size_t quorum() const
Get quorum value for current trusted key set.
-
std::vector< std::shared_ptr< STValidation > > negativeUNLFilter(std::vector< std::shared_ptr< STValidation > > &&validations) const
Remove validations that are from validators on the negative UNL.
+
std::vector< std::shared_ptr< STValidation > > negativeUNLFilter(std::vector< std::shared_ptr< STValidation > > &&validations) const
Remove validations that are from validators on the negative UNL.
bool isNonZero() const
Definition base_uint.h:526
Automatically unlocks and re-locks a unique_lock object.
Definition scope.h:212
diff --git a/LedgerReplayMsgHandler_8cpp_source.html b/LedgerReplayMsgHandler_8cpp_source.html index 5c669b4100..f8ee759d65 100644 --- a/LedgerReplayMsgHandler_8cpp_source.html +++ b/LedgerReplayMsgHandler_8cpp_source.html @@ -139,7 +139,7 @@ $(document).ready(function() { init_codefold(0); });
53 {
54 case protocol::lmACCOUNT_STATE:
55 return ledger->stateMap().getProofPath(key);
-
56 case protocol::lmTRANASCTION:
+
56 case protocol::lmTRANSACTION:
57 return ledger->txMap().getProofPath(key);
58 default:
59 // should not be here
diff --git a/Message_8cpp_source.html b/Message_8cpp_source.html index 493ae077af..9a2adc0a75 100644 --- a/Message_8cpp_source.html +++ b/Message_8cpp_source.html @@ -158,8 +158,8 @@ $(document).ready(function() { init_codefold(0); });
68 case protocol::mtGET_LEDGER:
69 case protocol::mtLEDGER_DATA:
70 case protocol::mtGET_OBJECTS:
-
71 case protocol::mtVALIDATORLIST:
-
72 case protocol::mtVALIDATORLISTCOLLECTION:
+
71 case protocol::mtVALIDATOR_LIST:
+
72 case protocol::mtVALIDATOR_LIST_COLLECTION:
73 case protocol::mtREPLAY_DELTA_RESPONSE:
74 case protocol::mtTRANSACTIONS:
75 return true;
diff --git a/NetworkOPs_8cpp_source.html b/NetworkOPs_8cpp_source.html index 415f660bcd..3ea5b470df 100644 --- a/NetworkOPs_8cpp_source.html +++ b/NetworkOPs_8cpp_source.html @@ -5487,11 +5487,11 @@ $(document).ready(function() { init_codefold(0); });
Metrics getMetrics(OpenView const &view) const
Returns fee metrics in reference fee level units.
Definition TxQ.cpp:1756
static time_point now()
Validator keys and manifest as set in configuration file.
-
std::optional< PublicKey > localPublicKey() const
This function returns the local validator public key or a std::nullopt.
+
std::optional< PublicKey > localPublicKey() const
This function returns the local validator public key or a std::nullopt.
std::size_t quorum() const
Get quorum value for current trusted key set.
-
std::optional< TimeKeeper::time_point > expires() const
Return the time when the validator list will expire.
-
std::size_t count() const
Return the number of configured validator list sites.
-
std::optional< PublicKey > getTrustedKey(PublicKey const &identity) const
Returns master public key if public key is trusted.
+
std::optional< TimeKeeper::time_point > expires() const
Return the time when the validator list will expire.
+
std::size_t count() const
Return the number of configured validator list sites.
+
std::optional< PublicKey > getTrustedKey(PublicKey const &identity) const
Returns master public key if public key is trusted.
Definition XRPAmount.h:24
Json::Value jsonClipped() const
Definition XRPAmount.h:199
constexpr double decimalXRP() const
Definition XRPAmount.h:243
diff --git a/OverlayImpl_8cpp_source.html b/OverlayImpl_8cpp_source.html index eb590926be..6e6a86ca4e 100644 --- a/OverlayImpl_8cpp_source.html +++ b/OverlayImpl_8cpp_source.html @@ -1948,9 +1948,9 @@ $(document).ready(function() { init_codefold(0); });
auto const & getCounts() const
An up-to-date copy of all the counters.
category
@ squelch_ignored
-
Json::Value getJson() const
Return a JSON representation of the state of the validator list.
-
std::optional< Json::Value > getAvailable(std::string_view pubKey, std::optional< std::uint32_t > forceVersion={})
Returns the current valid list for the given publisher key, if available, as a Json object.
-
bool listed(PublicKey const &identity) const
Returns true if public key is included on any lists.
+
Json::Value getJson() const
Return a JSON representation of the state of the validator list.
+
std::optional< Json::Value > getAvailable(std::string_view pubKey, std::optional< std::uint32_t > forceVersion={})
Returns the current valid list for the given publisher key, if available, as a Json object.
+
bool listed(PublicKey const &identity) const
Returns true if public key is included on any lists.
Json::Value getJson() const
Return JSON representation of configured validator sites.
T count(T... args)
diff --git a/PeerImp_8cpp_source.html b/PeerImp_8cpp_source.html index 7a6e12c3f2..242489deaa 100644 --- a/PeerImp_8cpp_source.html +++ b/PeerImp_8cpp_source.html @@ -4100,8 +4100,8 @@ $(document).ready(function() { init_codefold(0); });
@ transaction_duplicate
@ gl_tsc_share
static category categorize(::google::protobuf::Message const &message, protocol::MessageType type, bool inbound)
Given a protocol message, determine which traffic category it belongs to.
-
static void sendValidatorList(Peer &peer, std::uint64_t peerSequence, PublicKey const &publisherKey, std::size_t maxSequence, std::uint32_t rawVersion, std::string const &rawManifest, std::map< std::size_t, ValidatorBlobInfo > const &blobInfos, HashRouter &hashRouter, beast::Journal j)
-
void for_each_available(std::function< void(std::string const &manifest, std::uint32_t version, std::map< std::size_t, ValidatorBlobInfo > const &blobInfos, PublicKey const &pubKey, std::size_t maxSequence, uint256 const &hash)> func) const
Invokes the callback once for every available publisher list's raw data members.
+
static void sendValidatorList(Peer &peer, std::uint64_t peerSequence, PublicKey const &publisherKey, std::size_t maxSequence, std::uint32_t rawVersion, std::string const &rawManifest, std::map< std::size_t, ValidatorBlobInfo > const &blobInfos, HashRouter &hashRouter, beast::Journal j)
+
void for_each_available(std::function< void(std::string const &manifest, std::uint32_t version, std::map< std::size_t, ValidatorBlobInfo > const &blobInfos, PublicKey const &pubKey, std::size_t maxSequence, uint256 const &hash)> func) const
Invokes the callback once for every available publisher list's raw data members.
void zero()
Definition base_uint.h:531
constexpr bool parseHex(std::string_view sv)
Parse a hex string into a base_uint.
Definition base_uint.h:484
diff --git a/Permissions_8cpp_source.html b/Permissions_8cpp_source.html index b985e47c49..7ebc983620 100644 --- a/Permissions_8cpp_source.html +++ b/Permissions_8cpp_source.html @@ -95,7 +95,7 @@ $(document).ready(function() { init_codefold(0); });
11#pragma push_macro("TRANSACTION")
12#undef TRANSACTION
13
-
14#define TRANSACTION(tag, value, name, delegatable, amendment, ...) \
+
14#define TRANSACTION(tag, value, name, delegable, amendment, ...) \
15 {value, amendment},
16
17#include <xrpl/protocol/detail/transactions.macro>
@@ -108,7 +108,7 @@ $(document).ready(function() { init_codefold(0); });
24#pragma push_macro("TRANSACTION")
25#undef TRANSACTION
26
-
27#define TRANSACTION(tag, value, name, delegatable, ...) {value, delegatable},
+
27#define TRANSACTION(tag, value, name, delegable, ...) {value, delegable},
28
29#include <xrpl/protocol/detail/transactions.macro>
30
@@ -268,7 +268,7 @@ $(document).ready(function() { init_codefold(0); });
170 !rules.enabled(txFeaturesIt->second))
171 return false;
172
-
173 if (it->second == Delegation::notDelegatable)
+
173 if (it->second == Delegation::notDelegable)
174 return false;
175
176 return true;
@@ -320,7 +320,7 @@ $(document).ready(function() { init_codefold(0); });
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
TxType
Transaction type identifiers.
Definition TxFormats.h:38
GranularPermissionType
We have both transaction type permissions and granular type permissions.
Definition Permissions.h:20
-
@ notDelegatable
Definition Permissions.h:32
+
@ notDelegable
Definition Permissions.h:32
diff --git a/Permissions_8h_source.html b/Permissions_8h_source.html index f38daf257f..a9afb87775 100644 --- a/Permissions_8h_source.html +++ b/Permissions_8h_source.html @@ -107,7 +107,7 @@ $(document).ready(function() { init_codefold(0); });
30};
31
-
32enum Delegation { delegatable, notDelegatable };
+
32enum Delegation { delegable, notDelegable };
33
@@ -190,8 +190,8 @@ $(document).ready(function() { init_codefold(0); });
TxType
Transaction type identifiers.
Definition TxFormats.h:38
GranularPermissionType
We have both transaction type permissions and granular type permissions.
Definition Permissions.h:20
-
@ notDelegatable
Definition Permissions.h:32
-
@ delegatable
Definition Permissions.h:32
+
@ notDelegable
Definition Permissions.h:32
+
@ delegable
Definition Permissions.h:32
diff --git a/ProtocolMessage_8h_source.html b/ProtocolMessage_8h_source.html index 30932d01fc..0164120082 100644 --- a/ProtocolMessage_8h_source.html +++ b/ProtocolMessage_8h_source.html @@ -152,9 +152,9 @@ $(document).ready(function() { init_codefold(0); });
63 return "status";
64 case protocol::mtHAVE_SET:
65 return "have_set";
-
66 case protocol::mtVALIDATORLIST:
+
66 case protocol::mtVALIDATOR_LIST:
67 return "validator_list";
-
68 case protocol::mtVALIDATORLISTCOLLECTION:
+
68 case protocol::mtVALIDATOR_LIST_COLLECTION:
69 return "validator_list_collection";
70 case protocol::mtVALIDATION:
71 return "validation";
@@ -481,11 +481,11 @@ $(document).ready(function() { init_codefold(0); });
411 success = detail::invoke<protocol::TMValidation>(
412 *header, buffers, handler);
413 break;
-
414 case protocol::mtVALIDATORLIST:
+
414 case protocol::mtVALIDATOR_LIST:
415 success = detail::invoke<protocol::TMValidatorList>(
416 *header, buffers, handler);
417 break;
-
418 case protocol::mtVALIDATORLISTCOLLECTION:
+
418 case protocol::mtVALIDATOR_LIST_COLLECTION:
419 success = detail::invoke<protocol::TMValidatorListCollection>(
420 *header, buffers, handler);
421 break;
diff --git a/RCLValidations_8cpp_source.html b/RCLValidations_8cpp_source.html index 377497391f..3a26f76d7a 100644 --- a/RCLValidations_8cpp_source.html +++ b/RCLValidations_8cpp_source.html @@ -367,8 +367,8 @@ $(document).ready(function() { init_codefold(0); });
RCLValidationsAdaptor(Application &app, beast::Journal j)
time_point closeTime() const
Returns the predicted close time, in network time.
Definition TimeKeeper.h:57
ValStatus add(NodeID const &nodeID, Validation const &val)
Add a new validation.
-
std::optional< PublicKey > getListedKey(PublicKey const &identity) const
Returns listed master public if public key is included on any lists.
-
std::optional< PublicKey > getTrustedKey(PublicKey const &identity) const
Returns master public key if public key is trusted.
+
std::optional< PublicKey > getListedKey(PublicKey const &identity) const
Returns listed master public if public key is included on any lists.
+
std::optional< PublicKey > getTrustedKey(PublicKey const &identity) const
Returns master public key if public key is trusted.
T is_same_v
diff --git a/TrafficCount_8cpp_source.html b/TrafficCount_8cpp_source.html index 42d5ab46e8..3cd3e21746 100644 --- a/TrafficCount_8cpp_source.html +++ b/TrafficCount_8cpp_source.html @@ -93,8 +93,8 @@ $(document).ready(function() { init_codefold(0); });
9 {protocol::mtMANIFESTS, TrafficCount::category::manifests},
10 {protocol::mtENDPOINTS, TrafficCount::category::overlay},
11 {protocol::mtTRANSACTION, TrafficCount::category::transaction},
-
12 {protocol::mtVALIDATORLIST, TrafficCount::category::validatorlist},
-
13 {protocol::mtVALIDATORLISTCOLLECTION,
+
12 {protocol::mtVALIDATOR_LIST, TrafficCount::category::validatorlist},
+
13 {protocol::mtVALIDATOR_LIST_COLLECTION,
15 {protocol::mtVALIDATION, TrafficCount::category::validation},
16 {protocol::mtPROPOSE_LEDGER, TrafficCount::category::proposal},
diff --git a/UnlList_8cpp_source.html b/UnlList_8cpp_source.html index 1295140e82..441067086a 100644 --- a/UnlList_8cpp_source.html +++ b/UnlList_8cpp_source.html @@ -116,7 +116,7 @@ $(document).ready(function() { init_codefold(0); });
Value & append(Value const &value)
Append value to array at the end.
virtual ValidatorList & validators()=0
A public key.
Definition PublicKey.h:43
-
void for_each_listed(std::function< void(PublicKey const &, bool)> func) const
Invokes the callback once for every listed validation public key.
+
void for_each_listed(std::function< void(PublicKey const &, bool)> func) const
Invokes the callback once for every listed validation public key.
@ objectValue
object value (collection of name/value pairs).
Definition json_value.h:27
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition AccountID.cpp:95
diff --git a/ValidatorList_8cpp_source.html b/ValidatorList_8cpp_source.html index 57ad2efaa0..7c7b330f00 100644 --- a/ValidatorList_8cpp_source.html +++ b/ValidatorList_8cpp_source.html @@ -646,7 +646,7 @@ $(document).ready(function() { init_codefold(0); });
528 "xrpl::splitMessageParts : maximum message size");
529
530 messages.emplace_back(
-
531 std::make_shared<Message>(smallMsg, protocol::mtVALIDATORLIST),
+
531 std::make_shared<Message>(smallMsg, protocol::mtVALIDATOR_LIST),
532 sha512Half(smallMsg),
533 1);
534 return messages.back().numVLs;
@@ -673,7 +673,7 @@ $(document).ready(function() { init_codefold(0); });
555 {
556 messages.emplace_back(
-
558 *smallMsg, protocol::mtVALIDATORLISTCOLLECTION),
+
558 *smallMsg, protocol::mtVALIDATOR_LIST_COLLECTION),
559 sha512Half(*smallMsg),
560 smallMsg->blobs_size());
561 return messages.back().numVLs;
@@ -712,7 +712,7 @@ $(document).ready(function() { init_codefold(0); });
592 "xrpl::buildValidatorListMessage(ValidatorBlobInfo) : maximum "
593 "message size");
594 messages.emplace_back(
-
595 std::make_shared<Message>(msg, protocol::mtVALIDATORLIST),
+
595 std::make_shared<Message>(msg, protocol::mtVALIDATOR_LIST),
596 sha512Half(msg),
597 1);
598 return 1;
@@ -762,1591 +762,1592 @@ $(document).ready(function() { init_codefold(0); });
640 else
641 {
642 messages.emplace_back(
-
643 std::make_shared<Message>(msg, protocol::mtVALIDATORLISTCOLLECTION),
-
644 sha512Half(msg),
-
645 msg.blobs_size());
-
646 return messages.back().numVLs;
-
647 }
-
648}
+ +
644 msg, protocol::mtVALIDATOR_LIST_COLLECTION),
+
645 sha512Half(msg),
+
646 msg.blobs_size());
+
647 return messages.back().numVLs;
+
648 }
+
649}
-
649
-
650[[nodiscard]]
-
651// static
-
652std::pair<std::size_t, std::size_t>
-
- -
654 std::size_t messageVersion,
-
655 std::uint64_t peerSequence,
-
656 std::size_t maxSequence,
-
657 std::uint32_t rawVersion,
-
658 std::string const& rawManifest,
- - -
661 std::size_t maxSize /*= maximumMessageSize*/)
-
662{
-
663 XRPL_ASSERT(
-
664 !blobInfos.empty(),
-
665 "xrpl::ValidatorList::buildValidatorListMessages : empty messages "
-
666 "input");
-
667 auto const& [currentSeq, currentBlob] = *blobInfos.begin();
-
668 auto numVLs = std::accumulate(
-
669 messages.begin(),
-
670 messages.end(),
-
671 0,
-
672 [](std::size_t total, MessageWithHash const& m) {
-
673 return total + m.numVLs;
-
674 });
-
675 if (messageVersion == 2 && peerSequence < maxSequence)
-
676 {
-
677 // Version 2
-
678 if (messages.empty())
-
679 {
- -
681 messages,
-
682 peerSequence,
-
683 rawVersion,
-
684 rawManifest,
-
685 blobInfos,
-
686 maxSize);
-
687 if (messages.empty())
-
688 // No message was generated. Create an empty placeholder so we
-
689 // dont' repeat the work later.
-
690 messages.emplace_back();
-
691 }
-
692
-
693 // Don't send it next time.
-
694 return {maxSequence, numVLs};
-
695 }
-
696 else if (messageVersion == 1 && peerSequence < currentSeq)
-
697 {
-
698 // Version 1
-
699 if (messages.empty())
-
700 {
- -
702 messages,
-
703 rawVersion,
-
704 currentBlob.manifest ? *currentBlob.manifest : rawManifest,
-
705 currentBlob,
-
706 maxSize);
-
707 if (messages.empty())
-
708 // No message was generated. Create an empty placeholder so we
-
709 // dont' repeat the work later.
-
710 messages.emplace_back();
-
711 }
-
712
-
713 // Don't send it next time.
-
714 return {currentSeq, numVLs};
-
715 }
-
716 return {0, 0};
-
717}
+
650
+
651[[nodiscard]]
+
652// static
+ +
+ +
655 std::size_t messageVersion,
+
656 std::uint64_t peerSequence,
+
657 std::size_t maxSequence,
+
658 std::uint32_t rawVersion,
+
659 std::string const& rawManifest,
+ + +
662 std::size_t maxSize /*= maximumMessageSize*/)
+
663{
+
664 XRPL_ASSERT(
+
665 !blobInfos.empty(),
+
666 "xrpl::ValidatorList::buildValidatorListMessages : empty messages "
+
667 "input");
+
668 auto const& [currentSeq, currentBlob] = *blobInfos.begin();
+
669 auto numVLs = std::accumulate(
+
670 messages.begin(),
+
671 messages.end(),
+
672 0,
+
673 [](std::size_t total, MessageWithHash const& m) {
+
674 return total + m.numVLs;
+
675 });
+
676 if (messageVersion == 2 && peerSequence < maxSequence)
+
677 {
+
678 // Version 2
+
679 if (messages.empty())
+
680 {
+ +
682 messages,
+
683 peerSequence,
+
684 rawVersion,
+
685 rawManifest,
+
686 blobInfos,
+
687 maxSize);
+
688 if (messages.empty())
+
689 // No message was generated. Create an empty placeholder so we
+
690 // dont' repeat the work later.
+
691 messages.emplace_back();
+
692 }
+
693
+
694 // Don't send it next time.
+
695 return {maxSequence, numVLs};
+
696 }
+
697 else if (messageVersion == 1 && peerSequence < currentSeq)
+
698 {
+
699 // Version 1
+
700 if (messages.empty())
+
701 {
+ +
703 messages,
+
704 rawVersion,
+
705 currentBlob.manifest ? *currentBlob.manifest : rawManifest,
+
706 currentBlob,
+
707 maxSize);
+
708 if (messages.empty())
+
709 // No message was generated. Create an empty placeholder so we
+
710 // dont' repeat the work later.
+
711 messages.emplace_back();
+
712 }
+
713
+
714 // Don't send it next time.
+
715 return {currentSeq, numVLs};
+
716 }
+
717 return {0, 0};
+
718}
-
718
-
719// static
-
720void
-
- -
722 Peer& peer,
-
723 std::uint64_t peerSequence,
-
724 PublicKey const& publisherKey,
-
725 std::size_t maxSequence,
-
726 std::uint32_t rawVersion,
-
727 std::string const& rawManifest,
- - -
730 HashRouter& hashRouter,
- -
732{
-
733 std::size_t const messageVersion =
- - -
736 : 0;
-
737 if (!messageVersion)
-
738 return;
-
739 auto const [newPeerSequence, numVLs] = buildValidatorListMessages(
-
740 messageVersion,
-
741 peerSequence,
-
742 maxSequence,
-
743 rawVersion,
-
744 rawManifest,
-
745 blobInfos,
-
746 messages);
-
747 if (newPeerSequence)
-
748 {
-
749 XRPL_ASSERT(
-
750 !messages.empty(),
-
751 "xrpl::ValidatorList::sendValidatorList : non-empty messages "
-
752 "input");
-
753 // Don't send it next time.
-
754 peer.setPublisherListSequence(publisherKey, newPeerSequence);
-
755
-
756 bool sent = false;
-
757 for (auto const& message : messages)
-
758 {
-
759 if (message.message)
-
760 {
-
761 peer.send(message.message);
-
762 hashRouter.addSuppressionPeer(message.hash, peer.id());
-
763 sent = true;
-
764 }
-
765 }
-
766 // The only way sent wil be false is if the messages was too big, and
-
767 // thus there will only be one entry without a message
-
768 XRPL_ASSERT(
-
769 sent || messages.size() == 1,
-
770 "xrpl::ValidatorList::sendValidatorList : sent or one message");
-
771 if (sent)
-
772 {
-
773 if (messageVersion > 1)
-
774 JLOG(j.debug())
-
775 << "Sent " << messages.size()
-
776 << " validator list collection(s) containing " << numVLs
-
777 << " validator list(s) for " << strHex(publisherKey)
-
778 << " with sequence range " << peerSequence << ", "
-
779 << newPeerSequence << " to " << peer.fingerprint();
-
780 else
-
781 {
-
782 XRPL_ASSERT(
-
783 numVLs == 1,
-
784 "xrpl::ValidatorList::sendValidatorList : one validator "
-
785 "list");
-
786 JLOG(j.debug())
-
787 << "Sent validator list for " << strHex(publisherKey)
-
788 << " with sequence " << newPeerSequence << " to "
-
789 << peer.fingerprint();
-
790 }
-
791 }
-
792 }
-
793}
+
719
+
720// static
+
721void
+
+ +
723 Peer& peer,
+
724 std::uint64_t peerSequence,
+
725 PublicKey const& publisherKey,
+
726 std::size_t maxSequence,
+
727 std::uint32_t rawVersion,
+
728 std::string const& rawManifest,
+ + +
731 HashRouter& hashRouter,
+ +
733{
+
734 std::size_t const messageVersion =
+ + +
737 : 0;
+
738 if (!messageVersion)
+
739 return;
+
740 auto const [newPeerSequence, numVLs] = buildValidatorListMessages(
+
741 messageVersion,
+
742 peerSequence,
+
743 maxSequence,
+
744 rawVersion,
+
745 rawManifest,
+
746 blobInfos,
+
747 messages);
+
748 if (newPeerSequence)
+
749 {
+
750 XRPL_ASSERT(
+
751 !messages.empty(),
+
752 "xrpl::ValidatorList::sendValidatorList : non-empty messages "
+
753 "input");
+
754 // Don't send it next time.
+
755 peer.setPublisherListSequence(publisherKey, newPeerSequence);
+
756
+
757 bool sent = false;
+
758 for (auto const& message : messages)
+
759 {
+
760 if (message.message)
+
761 {
+
762 peer.send(message.message);
+
763 hashRouter.addSuppressionPeer(message.hash, peer.id());
+
764 sent = true;
+
765 }
+
766 }
+
767 // The only way sent wil be false is if the messages was too big, and
+
768 // thus there will only be one entry without a message
+
769 XRPL_ASSERT(
+
770 sent || messages.size() == 1,
+
771 "xrpl::ValidatorList::sendValidatorList : sent or one message");
+
772 if (sent)
+
773 {
+
774 if (messageVersion > 1)
+
775 JLOG(j.debug())
+
776 << "Sent " << messages.size()
+
777 << " validator list collection(s) containing " << numVLs
+
778 << " validator list(s) for " << strHex(publisherKey)
+
779 << " with sequence range " << peerSequence << ", "
+
780 << newPeerSequence << " to " << peer.fingerprint();
+
781 else
+
782 {
+
783 XRPL_ASSERT(
+
784 numVLs == 1,
+
785 "xrpl::ValidatorList::sendValidatorList : one validator "
+
786 "list");
+
787 JLOG(j.debug())
+
788 << "Sent validator list for " << strHex(publisherKey)
+
789 << " with sequence " << newPeerSequence << " to "
+
790 << peer.fingerprint();
+
791 }
+
792 }
+
793 }
+
794}
-
794
-
795// static
-
796void
-
- -
798 Peer& peer,
-
799 std::uint64_t peerSequence,
-
800 PublicKey const& publisherKey,
-
801 std::size_t maxSequence,
-
802 std::uint32_t rawVersion,
-
803 std::string const& rawManifest,
- -
805 HashRouter& hashRouter,
- -
807{
- - -
810 peer,
-
811 peerSequence,
-
812 publisherKey,
-
813 maxSequence,
-
814 rawVersion,
-
815 rawManifest,
-
816 blobInfos,
-
817 messages,
-
818 hashRouter,
-
819 j);
-
820}
+
795
+
796// static
+
797void
+
+ +
799 Peer& peer,
+
800 std::uint64_t peerSequence,
+
801 PublicKey const& publisherKey,
+
802 std::size_t maxSequence,
+
803 std::uint32_t rawVersion,
+
804 std::string const& rawManifest,
+ +
806 HashRouter& hashRouter,
+ +
808{
+ + +
811 peer,
+
812 peerSequence,
+
813 publisherKey,
+
814 maxSequence,
+
815 rawVersion,
+
816 rawManifest,
+
817 blobInfos,
+
818 messages,
+
819 hashRouter,
+
820 j);
+
821}
-
821
-
822// static
-
823void
-
- - - -
827{
-
828 auto const& current = lists.current;
-
829 auto const& remaining = lists.remaining;
-
830 blobInfos[current.sequence] = {
-
831 current.rawBlob, current.rawSignature, current.rawManifest};
-
832 for (auto const& [sequence, vl] : remaining)
-
833 {
-
834 blobInfos[sequence] = {vl.rawBlob, vl.rawSignature, vl.rawManifest};
-
835 }
-
836}
+
822
+
823// static
+
824void
+
+ + + +
828{
+
829 auto const& current = lists.current;
+
830 auto const& remaining = lists.remaining;
+
831 blobInfos[current.sequence] = {
+
832 current.rawBlob, current.rawSignature, current.rawManifest};
+
833 for (auto const& [sequence, vl] : remaining)
+
834 {
+
835 blobInfos[sequence] = {vl.rawBlob, vl.rawSignature, vl.rawManifest};
+
836 }
+
837}
-
837
-
838// static
- -
- - -
842{
- -
844 buildBlobInfos(result, lists);
-
845 return result;
-
846}
+
838
+
839// static
+ +
+ + +
843{
+ +
845 buildBlobInfos(result, lists);
+
846 return result;
+
847}
-
847
-
848// static
-
849void
-
- -
851 PublicKey const& publisherKey,
- -
853 std::size_t maxSequence,
-
854 uint256 const& hash,
-
855 Overlay& overlay,
-
856 HashRouter& hashRouter,
- -
858{
-
859 auto const toSkip = hashRouter.shouldRelay(hash);
-
860
-
861 if (toSkip)
-
862 {
-
863 // We don't know what messages or message versions we're sending
-
864 // until we examine our peer's properties. Build the message(s) on
-
865 // demand, but reuse them when possible.
-
866
-
867 // This will hold a v1 message with only the current VL if we have
-
868 // any peers that don't support v2
- -
870 // This will hold v2 messages indexed by the peer's
-
871 // `publisherListSequence`. For each `publisherListSequence`, we'll
-
872 // only send the VLs with higher sequences.
- -
874 messages2;
-
875 // If any peers are found that are worth considering, this list will
-
876 // be built to hold info for all of the valid VLs.
- -
878
-
879 XRPL_ASSERT(
-
880 lists.current.sequence == maxSequence ||
-
881 lists.remaining.count(maxSequence) == 1,
-
882 "xrpl::ValidatorList::broadcastBlobs : valid sequence");
-
883 // Can't use overlay.foreach here because we need to modify
-
884 // the peer, and foreach provides a const&
-
885 for (auto& peer : overlay.getActivePeers())
-
886 {
-
887 if (toSkip->count(peer->id()) == 0)
-
888 {
-
889 auto const peerSequence =
-
890 peer->publisherListSequence(publisherKey).value_or(0);
-
891 if (peerSequence < maxSequence)
-
892 {
-
893 if (blobInfos.empty())
-
894 buildBlobInfos(blobInfos, lists);
-
895 auto const v2 = peer->supportsFeature(
- - -
898 *peer,
-
899 peerSequence,
-
900 publisherKey,
-
901 maxSequence,
-
902 lists.rawVersion,
-
903 lists.rawManifest,
-
904 blobInfos,
-
905 v2 ? messages2[peerSequence] : messages1,
-
906 hashRouter,
-
907 j);
-
908 // Even if the peer doesn't support the messages,
-
909 // suppress it so it'll be ignored next time.
-
910 hashRouter.addSuppressionPeer(hash, peer->id());
-
911 }
-
912 }
-
913 }
-
914 }
-
915}
+
848
+
849// static
+
850void
+
+ +
852 PublicKey const& publisherKey,
+ +
854 std::size_t maxSequence,
+
855 uint256 const& hash,
+
856 Overlay& overlay,
+
857 HashRouter& hashRouter,
+ +
859{
+
860 auto const toSkip = hashRouter.shouldRelay(hash);
+
861
+
862 if (toSkip)
+
863 {
+
864 // We don't know what messages or message versions we're sending
+
865 // until we examine our peer's properties. Build the message(s) on
+
866 // demand, but reuse them when possible.
+
867
+
868 // This will hold a v1 message with only the current VL if we have
+
869 // any peers that don't support v2
+ +
871 // This will hold v2 messages indexed by the peer's
+
872 // `publisherListSequence`. For each `publisherListSequence`, we'll
+
873 // only send the VLs with higher sequences.
+ +
875 messages2;
+
876 // If any peers are found that are worth considering, this list will
+
877 // be built to hold info for all of the valid VLs.
+ +
879
+
880 XRPL_ASSERT(
+
881 lists.current.sequence == maxSequence ||
+
882 lists.remaining.count(maxSequence) == 1,
+
883 "xrpl::ValidatorList::broadcastBlobs : valid sequence");
+
884 // Can't use overlay.foreach here because we need to modify
+
885 // the peer, and foreach provides a const&
+
886 for (auto& peer : overlay.getActivePeers())
+
887 {
+
888 if (toSkip->count(peer->id()) == 0)
+
889 {
+
890 auto const peerSequence =
+
891 peer->publisherListSequence(publisherKey).value_or(0);
+
892 if (peerSequence < maxSequence)
+
893 {
+
894 if (blobInfos.empty())
+
895 buildBlobInfos(blobInfos, lists);
+
896 auto const v2 = peer->supportsFeature(
+ + +
899 *peer,
+
900 peerSequence,
+
901 publisherKey,
+
902 maxSequence,
+
903 lists.rawVersion,
+
904 lists.rawManifest,
+
905 blobInfos,
+
906 v2 ? messages2[peerSequence] : messages1,
+
907 hashRouter,
+
908 j);
+
909 // Even if the peer doesn't support the messages,
+
910 // suppress it so it'll be ignored next time.
+
911 hashRouter.addSuppressionPeer(hash, peer->id());
+
912 }
+
913 }
+
914 }
+
915 }
+
916}
-
916
- -
- -
919 std::string const& manifest,
-
920 std::uint32_t version,
- -
922 std::string siteUri,
-
923 uint256 const& hash,
-
924 Overlay& overlay,
-
925 HashRouter& hashRouter,
-
926 NetworkOPs& networkOPs)
-
927{
-
928 auto const result =
-
929 applyLists(manifest, version, blobs, std::move(siteUri), hash);
-
930 auto const disposition = result.bestDisposition();
-
931
-
932 if (disposition == ListDisposition::accepted)
-
933 {
-
934 bool good = true;
-
935
-
936 // localPublisherList never expires, so localPublisherList is excluded
-
937 // from the below check.
-
938 for (auto const& [_, listCollection] : publisherLists_)
-
939 {
-
940 if (listCollection.status != PublisherStatus::available)
-
941 {
-
942 good = false;
-
943 break;
-
944 }
-
945 }
-
946 if (good)
-
947 {
-
948 networkOPs.clearUNLBlocked();
-
949 }
-
950 }
-
951 bool broadcast = disposition <= ListDisposition::known_sequence;
-
952
-
953 // this function is only called for PublicKeys which are not specified
-
954 // in the config file (Note: Keys specified in the local config file are
-
955 // stored in ValidatorList::localPublisherList data member).
-
956 if (broadcast && result.status <= PublisherStatus::expired &&
-
957 result.publisherKey &&
-
958 publisherLists_[*result.publisherKey].maxSequence)
-
959 {
-
960 auto const& pubCollection = publisherLists_[*result.publisherKey];
-
961
- -
963 *result.publisherKey,
-
964 pubCollection,
-
965 *pubCollection.maxSequence,
-
966 hash,
-
967 overlay,
-
968 hashRouter,
-
969 j_);
-
970 }
-
971
-
972 return result;
-
973}
+
917
+ +
+ +
920 std::string const& manifest,
+
921 std::uint32_t version,
+ +
923 std::string siteUri,
+
924 uint256 const& hash,
+
925 Overlay& overlay,
+
926 HashRouter& hashRouter,
+
927 NetworkOPs& networkOPs)
+
928{
+
929 auto const result =
+
930 applyLists(manifest, version, blobs, std::move(siteUri), hash);
+
931 auto const disposition = result.bestDisposition();
+
932
+
933 if (disposition == ListDisposition::accepted)
+
934 {
+
935 bool good = true;
+
936
+
937 // localPublisherList never expires, so localPublisherList is excluded
+
938 // from the below check.
+
939 for (auto const& [_, listCollection] : publisherLists_)
+
940 {
+
941 if (listCollection.status != PublisherStatus::available)
+
942 {
+
943 good = false;
+
944 break;
+
945 }
+
946 }
+
947 if (good)
+
948 {
+
949 networkOPs.clearUNLBlocked();
+
950 }
+
951 }
+
952 bool broadcast = disposition <= ListDisposition::known_sequence;
+
953
+
954 // this function is only called for PublicKeys which are not specified
+
955 // in the config file (Note: Keys specified in the local config file are
+
956 // stored in ValidatorList::localPublisherList data member).
+
957 if (broadcast && result.status <= PublisherStatus::expired &&
+
958 result.publisherKey &&
+
959 publisherLists_[*result.publisherKey].maxSequence)
+
960 {
+
961 auto const& pubCollection = publisherLists_[*result.publisherKey];
+
962
+ +
964 *result.publisherKey,
+
965 pubCollection,
+
966 *pubCollection.maxSequence,
+
967 hash,
+
968 overlay,
+
969 hashRouter,
+
970 j_);
+
971 }
+
972
+
973 return result;
+
974}
-
974
- -
- -
977 std::string const& manifest,
-
978 std::uint32_t version,
- -
980 std::string siteUri,
-
981 std::optional<uint256> const& hash /* = {} */)
-
982{
-
983 if (std::count(
- - -
986 version) != 1)
- -
988
- -
990
-
991 PublisherListStats result;
-
992 for (auto const& blobInfo : blobs)
-
993 {
-
994 auto stats = applyList(
-
995 manifest,
-
996 blobInfo.manifest,
-
997 blobInfo.blob,
-
998 blobInfo.signature,
-
999 version,
-
1000 siteUri,
-
1001 hash,
-
1002 lock);
-
1003
-
1004 if (stats.bestDisposition() < result.bestDisposition() ||
-
1005 (stats.bestDisposition() == result.bestDisposition() &&
-
1006 stats.sequence > result.sequence))
-
1007 {
-
1008 stats.mergeDispositions(result);
-
1009 result = std::move(stats);
-
1010 }
-
1011 else
-
1012 result.mergeDispositions(stats);
-
1014 }
-
1015
-
1016 // Clean up the collection, because some of the processing may have made it
-
1017 // inconsistent
-
1018 if (result.publisherKey && publisherLists_.count(*result.publisherKey))
-
1019 {
-
1020 auto& pubCollection = publisherLists_[*result.publisherKey];
-
1021 auto& remaining = pubCollection.remaining;
-
1022 auto const& current = pubCollection.current;
-
1023 for (auto iter = remaining.begin(); iter != remaining.end();)
-
1024 {
-
1025 auto next = std::next(iter);
-
1026 XRPL_ASSERT(
-
1027 next == remaining.end() || next->first > iter->first,
-
1028 "xrpl::ValidatorList::applyLists : next is valid");
-
1029 if (iter->first <= current.sequence ||
-
1030 (next != remaining.end() &&
-
1031 next->second.validFrom <= iter->second.validFrom))
-
1032 {
-
1033 iter = remaining.erase(iter);
-
1034 }
-
1035 else
-
1036 {
-
1037 iter = next;
-
1038 }
-
1039 }
-
1040
-
1041 cacheValidatorFile(lock, *result.publisherKey);
-
1042
-
1043 pubCollection.fullHash = sha512Half(pubCollection);
-
1044
-
1045 result.sequence = *pubCollection.maxSequence;
-
1046 }
-
1047
-
1048 return result;
-
1049}
+
975
+ +
+ +
978 std::string const& manifest,
+
979 std::uint32_t version,
+ +
981 std::string siteUri,
+
982 std::optional<uint256> const& hash /* = {} */)
+
983{
+
984 if (std::count(
+ + +
987 version) != 1)
+ +
989
+ +
991
+
992 PublisherListStats result;
+
993 for (auto const& blobInfo : blobs)
+
994 {
+
995 auto stats = applyList(
+
996 manifest,
+
997 blobInfo.manifest,
+
998 blobInfo.blob,
+
999 blobInfo.signature,
+
1000 version,
+
1001 siteUri,
+
1002 hash,
+
1003 lock);
+
1004
+
1005 if (stats.bestDisposition() < result.bestDisposition() ||
+
1006 (stats.bestDisposition() == result.bestDisposition() &&
+
1007 stats.sequence > result.sequence))
+
1008 {
+
1009 stats.mergeDispositions(result);
+
1010 result = std::move(stats);
+
1011 }
+
1012 else
+
1013 result.mergeDispositions(stats);
+
1015 }
+
1016
+
1017 // Clean up the collection, because some of the processing may have made it
+
1018 // inconsistent
+
1019 if (result.publisherKey && publisherLists_.count(*result.publisherKey))
+
1020 {
+
1021 auto& pubCollection = publisherLists_[*result.publisherKey];
+
1022 auto& remaining = pubCollection.remaining;
+
1023 auto const& current = pubCollection.current;
+
1024 for (auto iter = remaining.begin(); iter != remaining.end();)
+
1025 {
+
1026 auto next = std::next(iter);
+
1027 XRPL_ASSERT(
+
1028 next == remaining.end() || next->first > iter->first,
+
1029 "xrpl::ValidatorList::applyLists : next is valid");
+
1030 if (iter->first <= current.sequence ||
+
1031 (next != remaining.end() &&
+
1032 next->second.validFrom <= iter->second.validFrom))
+
1033 {
+
1034 iter = remaining.erase(iter);
+
1035 }
+
1036 else
+
1037 {
+
1038 iter = next;
+
1039 }
+
1040 }
+
1041
+
1042 cacheValidatorFile(lock, *result.publisherKey);
+
1043
+
1044 pubCollection.fullHash = sha512Half(pubCollection);
+
1045
+
1046 result.sequence = *pubCollection.maxSequence;
+
1047 }
+
1048
+
1049 return result;
+
1050}
-
1050
-
1051void
-
- -
1053 PublicKey const& pubKey,
-
1054 PublisherList const& current,
-
1055 std::vector<PublicKey> const& oldList,
- -
1057{
-
1058 // Update keyListings_ for added and removed keys
-
1059 std::vector<PublicKey> const& publisherList = current.list;
-
1060 std::vector<std::string> const& manifests = current.manifests;
-
1061 auto iNew = publisherList.begin();
-
1062 auto iOld = oldList.begin();
-
1063 while (iNew != publisherList.end() || iOld != oldList.end())
-
1064 {
-
1065 if (iOld == oldList.end() ||
-
1066 (iNew != publisherList.end() && *iNew < *iOld))
-
1067 {
-
1068 // Increment list count for added keys
-
1069 ++keyListings_[*iNew];
-
1070 ++iNew;
-
1071 }
-
1072 else if (
-
1073 iNew == publisherList.end() ||
-
1074 (iOld != oldList.end() && *iOld < *iNew))
-
1075 {
-
1076 // Decrement list count for removed keys
-
1077 if (keyListings_[*iOld] <= 1)
-
1078 keyListings_.erase(*iOld);
-
1079 else
-
1080 --keyListings_[*iOld];
-
1081 ++iOld;
-
1082 }
-
1083 else
-
1084 {
-
1085 ++iNew;
-
1086 ++iOld;
-
1087 }
-
1088 }
-
1089
-
1090 if (publisherList.empty())
-
1091 {
-
1092 JLOG(j_.warn()) << "No validator keys included in valid list";
-
1093 }
-
1094
-
1095 for (auto const& valManifest : manifests)
-
1096 {
-
1097 auto m = deserializeManifest(base64_decode(valManifest));
-
1098
-
1099 if (!m || !keyListings_.count(m->masterKey))
-
1100 {
-
1101 JLOG(j_.warn()) << "List for " << strHex(pubKey)
-
1102 << " contained untrusted validator manifest";
-
1103 continue;
-
1104 }
-
1105
-
1106 if (auto const r = validatorManifests_.applyManifest(std::move(*m));
- -
1108 {
-
1109 JLOG(j_.warn()) << "List for " << strHex(pubKey)
-
1110 << " contained invalid validator manifest";
-
1111 }
-
1112 }
-
1113}
+
1051
+
1052void
+
+ +
1054 PublicKey const& pubKey,
+
1055 PublisherList const& current,
+
1056 std::vector<PublicKey> const& oldList,
+ +
1058{
+
1059 // Update keyListings_ for added and removed keys
+
1060 std::vector<PublicKey> const& publisherList = current.list;
+
1061 std::vector<std::string> const& manifests = current.manifests;
+
1062 auto iNew = publisherList.begin();
+
1063 auto iOld = oldList.begin();
+
1064 while (iNew != publisherList.end() || iOld != oldList.end())
+
1065 {
+
1066 if (iOld == oldList.end() ||
+
1067 (iNew != publisherList.end() && *iNew < *iOld))
+
1068 {
+
1069 // Increment list count for added keys
+
1070 ++keyListings_[*iNew];
+
1071 ++iNew;
+
1072 }
+
1073 else if (
+
1074 iNew == publisherList.end() ||
+
1075 (iOld != oldList.end() && *iOld < *iNew))
+
1076 {
+
1077 // Decrement list count for removed keys
+
1078 if (keyListings_[*iOld] <= 1)
+
1079 keyListings_.erase(*iOld);
+
1080 else
+
1081 --keyListings_[*iOld];
+
1082 ++iOld;
+
1083 }
+
1084 else
+
1085 {
+
1086 ++iNew;
+
1087 ++iOld;
+
1088 }
+
1089 }
+
1090
+
1091 if (publisherList.empty())
+
1092 {
+
1093 JLOG(j_.warn()) << "No validator keys included in valid list";
+
1094 }
+
1095
+
1096 for (auto const& valManifest : manifests)
+
1097 {
+
1098 auto m = deserializeManifest(base64_decode(valManifest));
+
1099
+
1100 if (!m || !keyListings_.count(m->masterKey))
+
1101 {
+
1102 JLOG(j_.warn()) << "List for " << strHex(pubKey)
+
1103 << " contained untrusted validator manifest";
+
1104 continue;
+
1105 }
+
1106
+
1107 if (auto const r = validatorManifests_.applyManifest(std::move(*m));
+ +
1109 {
+
1110 JLOG(j_.warn()) << "List for " << strHex(pubKey)
+
1111 << " contained invalid validator manifest";
+
1112 }
+
1113 }
+
1114}
-
1114
- -
- -
1117 std::string const& globalManifest,
-
1118 std::optional<std::string> const& localManifest,
-
1119 std::string const& blob,
-
1120 std::string const& signature,
-
1121 std::uint32_t version,
-
1122 std::string siteUri,
-
1123 std::optional<uint256> const& hash,
-
1124 ValidatorList::lock_guard const& lock)
-
1125{
-
1126 using namespace std::string_literals;
-
1127
-
1128 Json::Value list;
-
1129 auto const& manifest = localManifest ? *localManifest : globalManifest;
- -
1131 if (!m)
-
1132 {
-
1133 JLOG(j_.warn()) << "UNL manifest cannot be deserialized";
- -
1135 }
-
1136
-
1137 auto [result, pubKeyOpt] =
-
1138 verify(lock, list, std::move(*m), blob, signature);
-
1139
-
1140 if (!pubKeyOpt)
-
1141 {
-
1142 JLOG(j_.warn())
-
1143 << "UNL manifest is signed with an unrecognized master public key";
-
1144 return PublisherListStats{result};
-
1145 }
-
1146
-
1147 if (!publicKeyType(*pubKeyOpt))
-
1148 {
-
1149 // This is an impossible situation because we will never load an
-
1150 // invalid public key type (see checks in `ValidatorList::load`) however
-
1151 // we can only arrive here if the key used by the manifest matched one
-
1152 // of the loaded keys
-
1153 // LCOV_EXCL_START
-
1154 UNREACHABLE("xrpl::ValidatorList::applyList : invalid public key type");
-
1155 return PublisherListStats{result};
-
1156 // LCOV_EXCL_STOP
-
1157 }
-
1158
-
1159 PublicKey pubKey = *pubKeyOpt;
-
1160 if (result > ListDisposition::pending)
-
1161 {
-
1162 if (publisherLists_.count(pubKey))
-
1163 {
-
1164 auto const& pubCollection = publisherLists_[pubKey];
-
1165 if (pubCollection.maxSequence &&
-
1166 (result == ListDisposition::same_sequence ||
- -
1168 {
-
1169 // We've seen something valid list for this publisher
-
1170 // already, so return what we know about it.
-
1171 return PublisherListStats{
-
1172 result,
-
1173 pubKey,
-
1174 pubCollection.status,
-
1175 *pubCollection.maxSequence};
-
1176 }
-
1177 }
-
1178 return PublisherListStats{result};
-
1179 }
-
1180
-
1181 // Update publisher's list
-
1182 auto& pubCollection = publisherLists_[pubKey];
-
1183 auto const sequence = list[jss::sequence].asUInt();
-
1184 auto const accepted =
-
1185 (result == ListDisposition::accepted ||
-
1186 result == ListDisposition::expired);
-
1187
-
1188 if (accepted)
-
1189 pubCollection.status = result == ListDisposition::accepted
- - -
1192 pubCollection.rawManifest = globalManifest;
-
1193 if (!pubCollection.maxSequence || sequence > *pubCollection.maxSequence)
-
1194 pubCollection.maxSequence = sequence;
-
1195
-
1196 Json::Value const& newList = list[jss::validators];
-
1197 std::vector<PublicKey> oldList;
-
1198 if (accepted && pubCollection.remaining.count(sequence) != 0)
-
1199 {
-
1200 // We've seen this list before and stored it in "remaining". The
-
1201 // normal expected process is that the processed list would have
-
1202 // already been moved in to "current" by "updateTrusted()", but race
-
1203 // conditions are possible, or the node may have lost sync, so do
-
1204 // some of that work here.
-
1205 auto& publisher = pubCollection.current;
-
1206 // Copy the old validator list
-
1207 oldList = std::move(pubCollection.current.list);
-
1208 // Move the publisher info from "remaining" to "current"
-
1209 publisher = std::move(pubCollection.remaining[sequence]);
-
1210 // Remove the entry in "remaining"
-
1211 pubCollection.remaining.erase(sequence);
-
1212 // Done
-
1213 XRPL_ASSERT(
-
1214 publisher.sequence == sequence,
-
1215 "xrpl::ValidatorList::applyList : publisher sequence match");
-
1216 }
-
1217 else
-
1218 {
-
1219 auto& publisher = accepted ? pubCollection.current
-
1220 : pubCollection.remaining[sequence];
-
1221 publisher.sequence = sequence;
-
1222 publisher.validFrom = TimeKeeper::time_point{TimeKeeper::duration{
-
1223 list.isMember(jss::effective) ? list[jss::effective].asUInt() : 0}};
-
1224 publisher.validUntil = TimeKeeper::time_point{
-
1225 TimeKeeper::duration{list[jss::expiration].asUInt()}};
-
1226 publisher.siteUri = std::move(siteUri);
-
1227 publisher.rawBlob = blob;
-
1228 publisher.rawSignature = signature;
-
1229 publisher.rawManifest = localManifest;
-
1230 if (hash)
-
1231 publisher.hash = *hash;
-
1232
-
1233 std::vector<PublicKey>& publisherList = publisher.list;
-
1234 std::vector<std::string>& manifests = publisher.manifests;
-
1235
-
1236 // Copy the old validator list
-
1237 oldList = std::move(publisherList);
-
1238 // Build the new validator list from "newList"
-
1239 publisherList.clear();
-
1240 publisherList.reserve(newList.size());
-
1241 for (auto const& val : newList)
-
1242 {
-
1243 if (val.isObject() && val.isMember(jss::validation_public_key) &&
-
1244 val[jss::validation_public_key].isString())
-
1245 {
-
1246 std::optional<Blob> const ret =
-
1247 strUnHex(val[jss::validation_public_key].asString());
-
1248
-
1249 if (!ret || !publicKeyType(makeSlice(*ret)))
-
1250 {
-
1251 JLOG(j_.error())
-
1252 << "Invalid node identity: "
-
1253 << val[jss::validation_public_key].asString();
-
1254 }
-
1255 else
-
1256 {
-
1257 publisherList.push_back(
-
1258 PublicKey(Slice{ret->data(), ret->size()}));
-
1259 }
-
1260
-
1261 if (val.isMember(jss::manifest) &&
-
1262 val[jss::manifest].isString())
-
1263 manifests.push_back(val[jss::manifest].asString());
-
1264 }
-
1265 }
-
1266
-
1267 // Standardize the list order by sorting
-
1268 std::sort(publisherList.begin(), publisherList.end());
-
1269 }
-
1270 // If this publisher has ever sent a more updated version than the one
-
1271 // in this file, keep it. This scenario is unlikely, but legal.
-
1272 pubCollection.rawVersion = std::max(pubCollection.rawVersion, version);
-
1273 if (!pubCollection.remaining.empty())
-
1274 {
-
1275 // If there are any pending VLs, then this collection must be at least
-
1276 // version 2.
-
1277 pubCollection.rawVersion = std::max(pubCollection.rawVersion, 2u);
-
1278 }
-
1279
-
1280 PublisherListStats const applyResult{
-
1281 result, pubKey, pubCollection.status, *pubCollection.maxSequence};
-
1282
-
1283 if (accepted)
-
1284 {
-
1285 updatePublisherList(pubKey, pubCollection.current, oldList, lock);
-
1286 }
-
1287
-
1288 return applyResult;
-
1289}
+
1115
+ +
+ +
1118 std::string const& globalManifest,
+
1119 std::optional<std::string> const& localManifest,
+
1120 std::string const& blob,
+
1121 std::string const& signature,
+
1122 std::uint32_t version,
+
1123 std::string siteUri,
+
1124 std::optional<uint256> const& hash,
+
1125 ValidatorList::lock_guard const& lock)
+
1126{
+
1127 using namespace std::string_literals;
+
1128
+
1129 Json::Value list;
+
1130 auto const& manifest = localManifest ? *localManifest : globalManifest;
+ +
1132 if (!m)
+
1133 {
+
1134 JLOG(j_.warn()) << "UNL manifest cannot be deserialized";
+ +
1136 }
+
1137
+
1138 auto [result, pubKeyOpt] =
+
1139 verify(lock, list, std::move(*m), blob, signature);
+
1140
+
1141 if (!pubKeyOpt)
+
1142 {
+
1143 JLOG(j_.warn())
+
1144 << "UNL manifest is signed with an unrecognized master public key";
+
1145 return PublisherListStats{result};
+
1146 }
+
1147
+
1148 if (!publicKeyType(*pubKeyOpt))
+
1149 {
+
1150 // This is an impossible situation because we will never load an
+
1151 // invalid public key type (see checks in `ValidatorList::load`) however
+
1152 // we can only arrive here if the key used by the manifest matched one
+
1153 // of the loaded keys
+
1154 // LCOV_EXCL_START
+
1155 UNREACHABLE("xrpl::ValidatorList::applyList : invalid public key type");
+
1156 return PublisherListStats{result};
+
1157 // LCOV_EXCL_STOP
+
1158 }
+
1159
+
1160 PublicKey pubKey = *pubKeyOpt;
+
1161 if (result > ListDisposition::pending)
+
1162 {
+
1163 if (publisherLists_.count(pubKey))
+
1164 {
+
1165 auto const& pubCollection = publisherLists_[pubKey];
+
1166 if (pubCollection.maxSequence &&
+
1167 (result == ListDisposition::same_sequence ||
+ +
1169 {
+
1170 // We've seen something valid list for this publisher
+
1171 // already, so return what we know about it.
+
1172 return PublisherListStats{
+
1173 result,
+
1174 pubKey,
+
1175 pubCollection.status,
+
1176 *pubCollection.maxSequence};
+
1177 }
+
1178 }
+
1179 return PublisherListStats{result};
+
1180 }
+
1181
+
1182 // Update publisher's list
+
1183 auto& pubCollection = publisherLists_[pubKey];
+
1184 auto const sequence = list[jss::sequence].asUInt();
+
1185 auto const accepted =
+
1186 (result == ListDisposition::accepted ||
+
1187 result == ListDisposition::expired);
+
1188
+
1189 if (accepted)
+
1190 pubCollection.status = result == ListDisposition::accepted
+ + +
1193 pubCollection.rawManifest = globalManifest;
+
1194 if (!pubCollection.maxSequence || sequence > *pubCollection.maxSequence)
+
1195 pubCollection.maxSequence = sequence;
+
1196
+
1197 Json::Value const& newList = list[jss::validators];
+
1198 std::vector<PublicKey> oldList;
+
1199 if (accepted && pubCollection.remaining.count(sequence) != 0)
+
1200 {
+
1201 // We've seen this list before and stored it in "remaining". The
+
1202 // normal expected process is that the processed list would have
+
1203 // already been moved in to "current" by "updateTrusted()", but race
+
1204 // conditions are possible, or the node may have lost sync, so do
+
1205 // some of that work here.
+
1206 auto& publisher = pubCollection.current;
+
1207 // Copy the old validator list
+
1208 oldList = std::move(pubCollection.current.list);
+
1209 // Move the publisher info from "remaining" to "current"
+
1210 publisher = std::move(pubCollection.remaining[sequence]);
+
1211 // Remove the entry in "remaining"
+
1212 pubCollection.remaining.erase(sequence);
+
1213 // Done
+
1214 XRPL_ASSERT(
+
1215 publisher.sequence == sequence,
+
1216 "xrpl::ValidatorList::applyList : publisher sequence match");
+
1217 }
+
1218 else
+
1219 {
+
1220 auto& publisher = accepted ? pubCollection.current
+
1221 : pubCollection.remaining[sequence];
+
1222 publisher.sequence = sequence;
+
1223 publisher.validFrom = TimeKeeper::time_point{TimeKeeper::duration{
+
1224 list.isMember(jss::effective) ? list[jss::effective].asUInt() : 0}};
+
1225 publisher.validUntil = TimeKeeper::time_point{
+
1226 TimeKeeper::duration{list[jss::expiration].asUInt()}};
+
1227 publisher.siteUri = std::move(siteUri);
+
1228 publisher.rawBlob = blob;
+
1229 publisher.rawSignature = signature;
+
1230 publisher.rawManifest = localManifest;
+
1231 if (hash)
+
1232 publisher.hash = *hash;
+
1233
+
1234 std::vector<PublicKey>& publisherList = publisher.list;
+
1235 std::vector<std::string>& manifests = publisher.manifests;
+
1236
+
1237 // Copy the old validator list
+
1238 oldList = std::move(publisherList);
+
1239 // Build the new validator list from "newList"
+
1240 publisherList.clear();
+
1241 publisherList.reserve(newList.size());
+
1242 for (auto const& val : newList)
+
1243 {
+
1244 if (val.isObject() && val.isMember(jss::validation_public_key) &&
+
1245 val[jss::validation_public_key].isString())
+
1246 {
+
1247 std::optional<Blob> const ret =
+
1248 strUnHex(val[jss::validation_public_key].asString());
+
1249
+
1250 if (!ret || !publicKeyType(makeSlice(*ret)))
+
1251 {
+
1252 JLOG(j_.error())
+
1253 << "Invalid node identity: "
+
1254 << val[jss::validation_public_key].asString();
+
1255 }
+
1256 else
+
1257 {
+
1258 publisherList.push_back(
+
1259 PublicKey(Slice{ret->data(), ret->size()}));
+
1260 }
+
1261
+
1262 if (val.isMember(jss::manifest) &&
+
1263 val[jss::manifest].isString())
+
1264 manifests.push_back(val[jss::manifest].asString());
+
1265 }
+
1266 }
+
1267
+
1268 // Standardize the list order by sorting
+
1269 std::sort(publisherList.begin(), publisherList.end());
+
1270 }
+
1271 // If this publisher has ever sent a more updated version than the one
+
1272 // in this file, keep it. This scenario is unlikely, but legal.
+
1273 pubCollection.rawVersion = std::max(pubCollection.rawVersion, version);
+
1274 if (!pubCollection.remaining.empty())
+
1275 {
+
1276 // If there are any pending VLs, then this collection must be at least
+
1277 // version 2.
+
1278 pubCollection.rawVersion = std::max(pubCollection.rawVersion, 2u);
+
1279 }
+
1280
+
1281 PublisherListStats const applyResult{
+
1282 result, pubKey, pubCollection.status, *pubCollection.maxSequence};
+
1283
+
1284 if (accepted)
+
1285 {
+
1286 updatePublisherList(pubKey, pubCollection.current, oldList, lock);
+
1287 }
+
1288
+
1289 return applyResult;
+
1290}
-
1290
- -
- -
1293{
-
1294 using namespace std::string_literals;
-
1295 using namespace boost::filesystem;
-
1296 using namespace boost::system::errc;
-
1297
-
1298 std::lock_guard lock{mutex_};
-
1299
- -
1301 sites.reserve(publisherLists_.size());
-
1302 for (auto const& [pubKey, publisherCollection] : publisherLists_)
-
1303 {
-
1304 boost::system::error_code ec;
-
1305
-
1306 if (publisherCollection.status == PublisherStatus::available)
-
1307 continue;
-
1308
-
1309 boost::filesystem::path const filename = getCacheFileName(lock, pubKey);
-
1310
-
1311 auto const fullPath{canonical(filename, ec)};
-
1312 if (ec)
-
1313 continue;
-
1314
-
1315 auto size = file_size(fullPath, ec);
-
1316 if (!ec && !size)
-
1317 {
-
1318 // Treat an empty file as a missing file, because
-
1319 // nobody else is going to write it.
-
1320 ec = make_error_code(no_such_file_or_directory);
-
1321 }
-
1322 if (ec)
-
1323 continue;
-
1324
-
1325 std::string const prefix = [&fullPath]() {
-
1326#if _MSC_VER // MSVC: Windows paths need a leading / added
-
1327 {
-
1328 return fullPath.root_path() == "/"s ? "file://" : "file:///";
-
1329 }
-
1330#else
-
1331 {
-
1332 (void)fullPath;
-
1333 return "file://";
-
1334 }
-
1335#endif
-
1336 }();
-
1337 sites.emplace_back(prefix + fullPath.string());
-
1338 }
-
1339
-
1340 // Then let the ValidatorSites do the rest of the work.
-
1341 return sites;
-
1342}
+
1291
+ +
+ +
1294{
+
1295 using namespace std::string_literals;
+
1296 using namespace boost::filesystem;
+
1297 using namespace boost::system::errc;
+
1298
+
1299 std::lock_guard lock{mutex_};
+
1300
+ +
1302 sites.reserve(publisherLists_.size());
+
1303 for (auto const& [pubKey, publisherCollection] : publisherLists_)
+
1304 {
+
1305 boost::system::error_code ec;
+
1306
+
1307 if (publisherCollection.status == PublisherStatus::available)
+
1308 continue;
+
1309
+
1310 boost::filesystem::path const filename = getCacheFileName(lock, pubKey);
+
1311
+
1312 auto const fullPath{canonical(filename, ec)};
+
1313 if (ec)
+
1314 continue;
+
1315
+
1316 auto size = file_size(fullPath, ec);
+
1317 if (!ec && !size)
+
1318 {
+
1319 // Treat an empty file as a missing file, because
+
1320 // nobody else is going to write it.
+
1321 ec = make_error_code(no_such_file_or_directory);
+
1322 }
+
1323 if (ec)
+
1324 continue;
+
1325
+
1326 std::string const prefix = [&fullPath]() {
+
1327#if _MSC_VER // MSVC: Windows paths need a leading / added
+
1328 {
+
1329 return fullPath.root_path() == "/"s ? "file://" : "file:///";
+
1330 }
+
1331#else
+
1332 {
+
1333 (void)fullPath;
+
1334 return "file://";
+
1335 }
+
1336#endif
+
1337 }();
+
1338 sites.emplace_back(prefix + fullPath.string());
+
1339 }
+
1340
+
1341 // Then let the ValidatorSites do the rest of the work.
+
1342 return sites;
+
1343}
-
1343
-
1344// The returned PublicKey value is read from the manifest. Manifests do not
-
1345// contain the default-constructed public keys
- -
- -
1348 ValidatorList::lock_guard const& lock,
-
1349 Json::Value& list,
- -
1351 std::string const& blob,
-
1352 std::string const& signature)
-
1353{
-
1354 if (!publisherLists_.count(manifest.masterKey))
-
1355 return {ListDisposition::untrusted, {}};
-
1356
-
1357 PublicKey masterPubKey = manifest.masterKey;
-
1358 auto const revoked = manifest.revoked();
-
1359
-
1360 auto const result = publisherManifests_.applyManifest(std::move(manifest));
-
1361
-
1362 if (revoked && result == ManifestDisposition::accepted)
-
1363 {
-
1364 removePublisherList(lock, masterPubKey, PublisherStatus::revoked);
-
1365 // If the manifest is revoked, no future list is valid either
-
1366 publisherLists_[masterPubKey].remaining.clear();
-
1367 }
-
1368
-
1369 auto const signingKey = publisherManifests_.getSigningKey(masterPubKey);
-
1370
-
1371 if (revoked || !signingKey || result == ManifestDisposition::invalid)
-
1372 return {ListDisposition::untrusted, masterPubKey};
-
1373
-
1374 auto const sig = strUnHex(signature);
-
1375 auto const data = base64_decode(blob);
-
1376 if (!sig || !xrpl::verify(*signingKey, makeSlice(data), makeSlice(*sig)))
-
1377 return {ListDisposition::invalid, masterPubKey};
-
1378
-
1379 Json::Reader r;
-
1380 if (!r.parse(data, list))
-
1381 return {ListDisposition::invalid, masterPubKey};
-
1382
-
1383 if (list.isMember(jss::sequence) && list[jss::sequence].isInt() &&
-
1384 list.isMember(jss::expiration) && list[jss::expiration].isInt() &&
-
1385 (!list.isMember(jss::effective) || list[jss::effective].isInt()) &&
-
1386 list.isMember(jss::validators) && list[jss::validators].isArray())
-
1387 {
-
1388 auto const sequence = list[jss::sequence].asUInt();
-
1389 auto const validFrom = TimeKeeper::time_point{TimeKeeper::duration{
-
1390 list.isMember(jss::effective) ? list[jss::effective].asUInt() : 0}};
-
1391 auto const validUntil = TimeKeeper::time_point{
-
1392 TimeKeeper::duration{list[jss::expiration].asUInt()}};
-
1393 auto const now = timeKeeper_.now();
-
1394 auto const& listCollection = publisherLists_[masterPubKey];
-
1395 if (validUntil <= validFrom)
-
1396 return {ListDisposition::invalid, masterPubKey};
-
1397 else if (sequence < listCollection.current.sequence)
-
1398 return {ListDisposition::stale, masterPubKey};
-
1399 else if (sequence == listCollection.current.sequence)
-
1400 return {ListDisposition::same_sequence, masterPubKey};
-
1401 else if (validUntil <= now)
-
1402 return {ListDisposition::expired, masterPubKey};
-
1403 else if (validFrom > now)
-
1404 // Not yet valid. Return pending if one of the following is true
-
1405 // * There's no maxSequence, indicating this is the first blob seen
-
1406 // for this publisher
-
1407 // * The sequence is larger than the maxSequence, indicating this
-
1408 // blob is new
-
1409 // * There's no entry for this sequence AND this blob is valid
-
1410 // before the last blob, indicating blobs may be processing out of
-
1411 // order. This may result in some duplicated processing, but
-
1412 // prevents the risk of missing valid data. Else return
-
1413 // known_sequence
-
1414 return !listCollection.maxSequence ||
-
1415 sequence > *listCollection.maxSequence ||
-
1416 (listCollection.remaining.count(sequence) == 0 &&
-
1417 validFrom < listCollection.remaining
-
1418 .at(*listCollection.maxSequence)
-
1419 .validFrom)
- - -
1422 }
-
1423 else
-
1424 {
-
1425 return {ListDisposition::invalid, masterPubKey};
-
1426 }
-
1427
-
1428 return {ListDisposition::accepted, masterPubKey};
-
1429}
+
1344
+
1345// The returned PublicKey value is read from the manifest. Manifests do not
+
1346// contain the default-constructed public keys
+ +
+ +
1349 ValidatorList::lock_guard const& lock,
+
1350 Json::Value& list,
+ +
1352 std::string const& blob,
+
1353 std::string const& signature)
+
1354{
+
1355 if (!publisherLists_.count(manifest.masterKey))
+
1356 return {ListDisposition::untrusted, {}};
+
1357
+
1358 PublicKey masterPubKey = manifest.masterKey;
+
1359 auto const revoked = manifest.revoked();
+
1360
+
1361 auto const result = publisherManifests_.applyManifest(std::move(manifest));
+
1362
+
1363 if (revoked && result == ManifestDisposition::accepted)
+
1364 {
+
1365 removePublisherList(lock, masterPubKey, PublisherStatus::revoked);
+
1366 // If the manifest is revoked, no future list is valid either
+
1367 publisherLists_[masterPubKey].remaining.clear();
+
1368 }
+
1369
+
1370 auto const signingKey = publisherManifests_.getSigningKey(masterPubKey);
+
1371
+
1372 if (revoked || !signingKey || result == ManifestDisposition::invalid)
+
1373 return {ListDisposition::untrusted, masterPubKey};
+
1374
+
1375 auto const sig = strUnHex(signature);
+
1376 auto const data = base64_decode(blob);
+
1377 if (!sig || !xrpl::verify(*signingKey, makeSlice(data), makeSlice(*sig)))
+
1378 return {ListDisposition::invalid, masterPubKey};
+
1379
+
1380 Json::Reader r;
+
1381 if (!r.parse(data, list))
+
1382 return {ListDisposition::invalid, masterPubKey};
+
1383
+
1384 if (list.isMember(jss::sequence) && list[jss::sequence].isInt() &&
+
1385 list.isMember(jss::expiration) && list[jss::expiration].isInt() &&
+
1386 (!list.isMember(jss::effective) || list[jss::effective].isInt()) &&
+
1387 list.isMember(jss::validators) && list[jss::validators].isArray())
+
1388 {
+
1389 auto const sequence = list[jss::sequence].asUInt();
+
1390 auto const validFrom = TimeKeeper::time_point{TimeKeeper::duration{
+
1391 list.isMember(jss::effective) ? list[jss::effective].asUInt() : 0}};
+
1392 auto const validUntil = TimeKeeper::time_point{
+
1393 TimeKeeper::duration{list[jss::expiration].asUInt()}};
+
1394 auto const now = timeKeeper_.now();
+
1395 auto const& listCollection = publisherLists_[masterPubKey];
+
1396 if (validUntil <= validFrom)
+
1397 return {ListDisposition::invalid, masterPubKey};
+
1398 else if (sequence < listCollection.current.sequence)
+
1399 return {ListDisposition::stale, masterPubKey};
+
1400 else if (sequence == listCollection.current.sequence)
+
1401 return {ListDisposition::same_sequence, masterPubKey};
+
1402 else if (validUntil <= now)
+
1403 return {ListDisposition::expired, masterPubKey};
+
1404 else if (validFrom > now)
+
1405 // Not yet valid. Return pending if one of the following is true
+
1406 // * There's no maxSequence, indicating this is the first blob seen
+
1407 // for this publisher
+
1408 // * The sequence is larger than the maxSequence, indicating this
+
1409 // blob is new
+
1410 // * There's no entry for this sequence AND this blob is valid
+
1411 // before the last blob, indicating blobs may be processing out of
+
1412 // order. This may result in some duplicated processing, but
+
1413 // prevents the risk of missing valid data. Else return
+
1414 // known_sequence
+
1415 return !listCollection.maxSequence ||
+
1416 sequence > *listCollection.maxSequence ||
+
1417 (listCollection.remaining.count(sequence) == 0 &&
+
1418 validFrom < listCollection.remaining
+
1419 .at(*listCollection.maxSequence)
+
1420 .validFrom)
+ + +
1423 }
+
1424 else
+
1425 {
+
1426 return {ListDisposition::invalid, masterPubKey};
+
1427 }
+
1428
+
1429 return {ListDisposition::accepted, masterPubKey};
+
1430}
-
1430
-
1431bool
-
-
1432ValidatorList::listed(PublicKey const& identity) const
-
1433{
-
1434 std::shared_lock read_lock{mutex_};
-
1435
-
1436 auto const pubKey = validatorManifests_.getMasterKey(identity);
-
1437 return keyListings_.find(pubKey) != keyListings_.end();
-
1438}
+
1431
+
1432bool
+
+
1433ValidatorList::listed(PublicKey const& identity) const
+
1434{
+
1435 std::shared_lock read_lock{mutex_};
+
1436
+
1437 auto const pubKey = validatorManifests_.getMasterKey(identity);
+
1438 return keyListings_.find(pubKey) != keyListings_.end();
+
1439}
-
1439
-
1440bool
-
- - -
1443 PublicKey const& identity) const
-
1444{
-
1445 auto const pubKey = validatorManifests_.getMasterKey(identity);
-
1446 return trustedMasterKeys_.find(pubKey) != trustedMasterKeys_.end();
-
1447}
+
1440
+
1441bool
+
+ + +
1444 PublicKey const& identity) const
+
1445{
+
1446 auto const pubKey = validatorManifests_.getMasterKey(identity);
+
1447 return trustedMasterKeys_.find(pubKey) != trustedMasterKeys_.end();
+
1448}
-
1448
-
1449bool
-
-
1450ValidatorList::trusted(PublicKey const& identity) const
-
1451{
-
1452 std::shared_lock read_lock{mutex_};
-
1453 return trusted(read_lock, identity);
-
1454}
+
1449
+
1450bool
+
+
1451ValidatorList::trusted(PublicKey const& identity) const
+
1452{
+
1453 std::shared_lock read_lock{mutex_};
+
1454 return trusted(read_lock, identity);
+
1455}
-
1455
- -
- -
1458{
-
1459 std::shared_lock read_lock{mutex_};
-
1460
-
1461 auto const pubKey = validatorManifests_.getMasterKey(identity);
-
1462 if (keyListings_.find(pubKey) != keyListings_.end())
-
1463 return pubKey;
-
1464 return std::nullopt;
-
1465}
+
1456
+ +
+ +
1459{
+
1460 std::shared_lock read_lock{mutex_};
+
1461
+
1462 auto const pubKey = validatorManifests_.getMasterKey(identity);
+
1463 if (keyListings_.find(pubKey) != keyListings_.end())
+
1464 return pubKey;
+
1465 return std::nullopt;
+
1466}
-
1466
- -
- - -
1470 PublicKey const& identity) const
-
1471{
-
1472 auto const pubKey = validatorManifests_.getMasterKey(identity);
-
1473 if (trustedMasterKeys_.find(pubKey) != trustedMasterKeys_.end())
-
1474 return pubKey;
-
1475 return std::nullopt;
-
1476}
+
1467
+ +
+ + +
1471 PublicKey const& identity) const
+
1472{
+
1473 auto const pubKey = validatorManifests_.getMasterKey(identity);
+
1474 if (trustedMasterKeys_.find(pubKey) != trustedMasterKeys_.end())
+
1475 return pubKey;
+
1476 return std::nullopt;
+
1477}
-
1477
- -
- -
1480{
-
1481 std::shared_lock read_lock{mutex_};
-
1482
-
1483 return getTrustedKey(read_lock, identity);
-
1484}
+
1478
+ +
+ +
1481{
+
1482 std::shared_lock read_lock{mutex_};
+
1483
+
1484 return getTrustedKey(read_lock, identity);
+
1485}
-
1485
-
1486bool
-
- -
1488{
-
1489 std::shared_lock read_lock{mutex_};
-
1490 return identity.size() && publisherLists_.count(identity) &&
-
1491 publisherLists_.at(identity).status < PublisherStatus::revoked;
-
1492}
+
1486
+
1487bool
+
+ +
1489{
+
1490 std::shared_lock read_lock{mutex_};
+
1491 return identity.size() && publisherLists_.count(identity) &&
+
1492 publisherLists_.at(identity).status < PublisherStatus::revoked;
+
1493}
-
1493
- -
- -
1496{
-
1497 std::shared_lock read_lock{mutex_};
-
1498 return localPubKey_;
-
1499}
+
1494
+ +
+ +
1497{
+
1498 std::shared_lock read_lock{mutex_};
+
1499 return localPubKey_;
+
1500}
-
1500
-
1501bool
-
- - -
1504 PublicKey const& publisherKey,
-
1505 PublisherStatus reason)
-
1506{
-
1507 XRPL_ASSERT(
-
1508 reason != PublisherStatus::available &&
- -
1510 "xrpl::ValidatorList::removePublisherList : valid reason input");
-
1511 auto const iList = publisherLists_.find(publisherKey);
-
1512 if (iList == publisherLists_.end())
-
1513 return false;
-
1514
-
1515 JLOG(j_.debug()) << "Removing validator list for publisher "
-
1516 << strHex(publisherKey);
-
1517
-
1518 for (auto const& val : iList->second.current.list)
-
1519 {
-
1520 auto const& iVal = keyListings_.find(val);
-
1521 if (iVal == keyListings_.end())
-
1522 continue;
-
1523
-
1524 if (iVal->second <= 1)
-
1525 keyListings_.erase(iVal);
-
1526 else
-
1527 --iVal->second;
-
1528 }
-
1529
-
1530 iList->second.current.list.clear();
-
1531 iList->second.status = reason;
-
1532
-
1533 return true;
-
1534}
+
1501
+
1502bool
+
+ + +
1505 PublicKey const& publisherKey,
+
1506 PublisherStatus reason)
+
1507{
+
1508 XRPL_ASSERT(
+
1509 reason != PublisherStatus::available &&
+ +
1511 "xrpl::ValidatorList::removePublisherList : valid reason input");
+
1512 auto const iList = publisherLists_.find(publisherKey);
+
1513 if (iList == publisherLists_.end())
+
1514 return false;
+
1515
+
1516 JLOG(j_.debug()) << "Removing validator list for publisher "
+
1517 << strHex(publisherKey);
+
1518
+
1519 for (auto const& val : iList->second.current.list)
+
1520 {
+
1521 auto const& iVal = keyListings_.find(val);
+
1522 if (iVal == keyListings_.end())
+
1523 continue;
+
1524
+
1525 if (iVal->second <= 1)
+
1526 keyListings_.erase(iVal);
+
1527 else
+
1528 --iVal->second;
+
1529 }
+
1530
+
1531 iList->second.current.list.clear();
+
1532 iList->second.status = reason;
+
1533
+
1534 return true;
+
1535}
-
1535
- -
- -
1538{
-
1539 return publisherLists_.size() + (localPublisherList.list.size() > 0);
-
1540}
+
1536
+ +
+ +
1539{
+
1540 return publisherLists_.size() + (localPublisherList.list.size() > 0);
+
1541}
-
1541
- -
- -
1544{
-
1545 std::shared_lock read_lock{mutex_};
-
1546 return count(read_lock);
-
1547}
+
1542
+ +
+ +
1545{
+
1546 std::shared_lock read_lock{mutex_};
+
1547 return count(read_lock);
+
1548}
-
1548
- -
- -
1551{
- -
1553 for (auto const& [_, collection] : publisherLists_)
-
1554 {
-
1555 // Unfetched
-
1556 auto const& current = collection.current;
-
1557 if (current.validUntil == TimeKeeper::time_point{})
-
1558 {
-
1559 return std::nullopt;
-
1560 }
-
1561
-
1562 // Find the latest validUntil in a chain where the next validFrom
-
1563 // overlaps with the previous validUntil. applyLists has already cleaned
-
1564 // up the list so the validFrom dates are guaranteed increasing.
-
1565 auto chainedExpiration = current.validUntil;
-
1566 for (auto const& [sequence, check] : collection.remaining)
-
1567 {
-
1568 (void)sequence;
-
1569 if (check.validFrom <= chainedExpiration)
-
1570 chainedExpiration = check.validUntil;
-
1571 else
-
1572 break;
-
1573 }
-
1574
-
1575 // Earliest
-
1576 if (!res || chainedExpiration < *res)
-
1577 {
-
1578 res = chainedExpiration;
-
1579 }
-
1580 }
-
1581
-
1582 if (localPublisherList.list.size() > 0)
-
1583 {
-
1584 PublisherList collection = localPublisherList;
-
1585 // Unfetched
-
1586 auto const& current = collection;
-
1587 auto chainedExpiration = current.validUntil;
-
1588
-
1589 // Earliest
-
1590 if (!res || chainedExpiration < *res)
-
1591 {
-
1592 res = chainedExpiration;
-
1593 }
-
1594 }
-
1595 return res;
-
1596}
+
1549
+ +
+ +
1552{
+ +
1554 for (auto const& [_, collection] : publisherLists_)
+
1555 {
+
1556 // Unfetched
+
1557 auto const& current = collection.current;
+
1558 if (current.validUntil == TimeKeeper::time_point{})
+
1559 {
+
1560 return std::nullopt;
+
1561 }
+
1562
+
1563 // Find the latest validUntil in a chain where the next validFrom
+
1564 // overlaps with the previous validUntil. applyLists has already cleaned
+
1565 // up the list so the validFrom dates are guaranteed increasing.
+
1566 auto chainedExpiration = current.validUntil;
+
1567 for (auto const& [sequence, check] : collection.remaining)
+
1568 {
+
1569 (void)sequence;
+
1570 if (check.validFrom <= chainedExpiration)
+
1571 chainedExpiration = check.validUntil;
+
1572 else
+
1573 break;
+
1574 }
+
1575
+
1576 // Earliest
+
1577 if (!res || chainedExpiration < *res)
+
1578 {
+
1579 res = chainedExpiration;
+
1580 }
+
1581 }
+
1582
+
1583 if (localPublisherList.list.size() > 0)
+
1584 {
+
1585 PublisherList collection = localPublisherList;
+
1586 // Unfetched
+
1587 auto const& current = collection;
+
1588 auto chainedExpiration = current.validUntil;
+
1589
+
1590 // Earliest
+
1591 if (!res || chainedExpiration < *res)
+
1592 {
+
1593 res = chainedExpiration;
+
1594 }
+
1595 }
+
1596 return res;
+
1597}
-
1597
- -
-
1599ValidatorList::expires() const
-
1600{
-
1601 std::shared_lock read_lock{mutex_};
-
1602 return expires(read_lock);
-
1603}
+
1598
+ +
+
1600ValidatorList::expires() const
+
1601{
+
1602 std::shared_lock read_lock{mutex_};
+
1603 return expires(read_lock);
+
1604}
-
1604
- -
-
1606ValidatorList::getJson() const
-
1607{
- -
1609
-
1610 std::shared_lock read_lock{mutex_};
-
1611
-
1612 res[jss::validation_quorum] = static_cast<Json::UInt>(quorum_);
-
1613
-
1614 {
-
1615 auto& x = (res[jss::validator_list] = Json::objectValue);
-
1616
-
1617 x[jss::count] = static_cast<Json::UInt>(count(read_lock));
-
1618
-
1619 if (auto when = expires(read_lock))
-
1620 {
-
1621 if (*when == TimeKeeper::time_point::max())
-
1622 {
-
1623 x[jss::expiration] = "never";
-
1624 x[jss::status] = "active";
-
1625 }
-
1626 else
-
1627 {
-
1628 x[jss::expiration] = to_string(*when);
-
1629
-
1630 if (*when > timeKeeper_.now())
-
1631 x[jss::status] = "active";
-
1632 else
-
1633 x[jss::status] = "expired";
-
1634 }
-
1635 }
-
1636 else
-
1637 {
-
1638 x[jss::status] = "unknown";
-
1639 x[jss::expiration] = "unknown";
-
1640 }
-
1641
-
1642 x[jss::validator_list_threshold] = Json::UInt(listThreshold_);
-
1643 }
-
1644
-
1645 // Validator keys listed in the local config file
-
1646 Json::Value& jLocalStaticKeys =
-
1647 (res[jss::local_static_keys] = Json::arrayValue);
-
1648
-
1649 for (auto const& key : localPublisherList.list)
-
1650 jLocalStaticKeys.append(toBase58(TokenType::NodePublic, key));
-
1651
-
1652 // Publisher lists
-
1653 Json::Value& jPublisherLists =
-
1654 (res[jss::publisher_lists] = Json::arrayValue);
-
1655 for (auto const& [publicKey, pubCollection] : publisherLists_)
-
1656 {
-
1657 Json::Value& curr = jPublisherLists.append(Json::objectValue);
-
1658 curr[jss::pubkey_publisher] = strHex(publicKey);
-
1659 curr[jss::available] =
-
1660 pubCollection.status == PublisherStatus::available;
-
1661
-
1662 auto appendList = [](PublisherList const& publisherList,
-
1663 Json::Value& target) {
-
1664 target[jss::uri] = publisherList.siteUri;
-
1665 if (publisherList.validUntil != TimeKeeper::time_point{})
-
1666 {
-
1667 target[jss::seq] =
-
1668 static_cast<Json::UInt>(publisherList.sequence);
-
1669 target[jss::expiration] = to_string(publisherList.validUntil);
-
1670 }
-
1671 if (publisherList.validFrom != TimeKeeper::time_point{})
-
1672 target[jss::effective] = to_string(publisherList.validFrom);
-
1673 Json::Value& keys = (target[jss::list] = Json::arrayValue);
-
1674 for (auto const& key : publisherList.list)
-
1675 {
-
1676 keys.append(toBase58(TokenType::NodePublic, key));
-
1677 }
-
1678 };
-
1679 {
-
1680 auto const& current = pubCollection.current;
-
1681 appendList(current, curr);
-
1682 if (current.validUntil != TimeKeeper::time_point{})
-
1683 {
-
1684 curr[jss::version] = pubCollection.rawVersion;
-
1685 }
-
1686 }
-
1687
-
1688 Json::Value remaining(Json::arrayValue);
-
1689 for (auto const& [sequence, future] : pubCollection.remaining)
-
1690 {
-
1691 using namespace std::chrono_literals;
-
1692
-
1693 (void)sequence;
-
1694 Json::Value& r = remaining.append(Json::objectValue);
-
1695 appendList(future, r);
-
1696 // Race conditions can happen, so make this check "fuzzy"
-
1697 XRPL_ASSERT(
-
1698 future.validFrom > timeKeeper_.now() + 600s,
-
1699 "xrpl::ValidatorList::getJson : minimum valid from");
-
1700 }
-
1701 if (remaining.size())
-
1702 curr[jss::remaining] = std::move(remaining);
-
1703 }
-
1704
-
1705 // Trusted validator keys
-
1706 Json::Value& jValidatorKeys =
-
1707 (res[jss::trusted_validator_keys] = Json::arrayValue);
-
1708 for (auto const& k : trustedMasterKeys_)
-
1709 {
-
1710 jValidatorKeys.append(toBase58(TokenType::NodePublic, k));
-
1711 }
-
1712
-
1713 // signing keys
-
1714 Json::Value& jSigningKeys = (res[jss::signing_keys] = Json::objectValue);
-
1715 validatorManifests_.for_each_manifest([&jSigningKeys,
-
1716 this](Manifest const& manifest) {
-
1717 auto it = keyListings_.find(manifest.masterKey);
-
1718 if (it != keyListings_.end() && manifest.signingKey)
-
1719 {
-
1720 jSigningKeys[toBase58(TokenType::NodePublic, manifest.masterKey)] =
-
1721 toBase58(TokenType::NodePublic, *manifest.signingKey);
-
1722 }
-
1723 });
-
1724
-
1725 // Negative UNL
-
1726 if (!negativeUNL_.empty())
-
1727 {
-
1728 Json::Value& jNegativeUNL = (res[jss::NegativeUNL] = Json::arrayValue);
-
1729 for (auto const& k : negativeUNL_)
-
1730 {
-
1731 jNegativeUNL.append(toBase58(TokenType::NodePublic, k));
-
1732 }
-
1733 }
-
1734
-
1735 return res;
-
1736}
+
1605
+ +
+
1607ValidatorList::getJson() const
+
1608{
+ +
1610
+
1611 std::shared_lock read_lock{mutex_};
+
1612
+
1613 res[jss::validation_quorum] = static_cast<Json::UInt>(quorum_);
+
1614
+
1615 {
+
1616 auto& x = (res[jss::validator_list] = Json::objectValue);
+
1617
+
1618 x[jss::count] = static_cast<Json::UInt>(count(read_lock));
+
1619
+
1620 if (auto when = expires(read_lock))
+
1621 {
+
1622 if (*when == TimeKeeper::time_point::max())
+
1623 {
+
1624 x[jss::expiration] = "never";
+
1625 x[jss::status] = "active";
+
1626 }
+
1627 else
+
1628 {
+
1629 x[jss::expiration] = to_string(*when);
+
1630
+
1631 if (*when > timeKeeper_.now())
+
1632 x[jss::status] = "active";
+
1633 else
+
1634 x[jss::status] = "expired";
+
1635 }
+
1636 }
+
1637 else
+
1638 {
+
1639 x[jss::status] = "unknown";
+
1640 x[jss::expiration] = "unknown";
+
1641 }
+
1642
+
1643 x[jss::validator_list_threshold] = Json::UInt(listThreshold_);
+
1644 }
+
1645
+
1646 // Validator keys listed in the local config file
+
1647 Json::Value& jLocalStaticKeys =
+
1648 (res[jss::local_static_keys] = Json::arrayValue);
+
1649
+
1650 for (auto const& key : localPublisherList.list)
+
1651 jLocalStaticKeys.append(toBase58(TokenType::NodePublic, key));
+
1652
+
1653 // Publisher lists
+
1654 Json::Value& jPublisherLists =
+
1655 (res[jss::publisher_lists] = Json::arrayValue);
+
1656 for (auto const& [publicKey, pubCollection] : publisherLists_)
+
1657 {
+
1658 Json::Value& curr = jPublisherLists.append(Json::objectValue);
+
1659 curr[jss::pubkey_publisher] = strHex(publicKey);
+
1660 curr[jss::available] =
+
1661 pubCollection.status == PublisherStatus::available;
+
1662
+
1663 auto appendList = [](PublisherList const& publisherList,
+
1664 Json::Value& target) {
+
1665 target[jss::uri] = publisherList.siteUri;
+
1666 if (publisherList.validUntil != TimeKeeper::time_point{})
+
1667 {
+
1668 target[jss::seq] =
+
1669 static_cast<Json::UInt>(publisherList.sequence);
+
1670 target[jss::expiration] = to_string(publisherList.validUntil);
+
1671 }
+
1672 if (publisherList.validFrom != TimeKeeper::time_point{})
+
1673 target[jss::effective] = to_string(publisherList.validFrom);
+
1674 Json::Value& keys = (target[jss::list] = Json::arrayValue);
+
1675 for (auto const& key : publisherList.list)
+
1676 {
+
1677 keys.append(toBase58(TokenType::NodePublic, key));
+
1678 }
+
1679 };
+
1680 {
+
1681 auto const& current = pubCollection.current;
+
1682 appendList(current, curr);
+
1683 if (current.validUntil != TimeKeeper::time_point{})
+
1684 {
+
1685 curr[jss::version] = pubCollection.rawVersion;
+
1686 }
+
1687 }
+
1688
+
1689 Json::Value remaining(Json::arrayValue);
+
1690 for (auto const& [sequence, future] : pubCollection.remaining)
+
1691 {
+
1692 using namespace std::chrono_literals;
+
1693
+
1694 (void)sequence;
+
1695 Json::Value& r = remaining.append(Json::objectValue);
+
1696 appendList(future, r);
+
1697 // Race conditions can happen, so make this check "fuzzy"
+
1698 XRPL_ASSERT(
+
1699 future.validFrom > timeKeeper_.now() + 600s,
+
1700 "xrpl::ValidatorList::getJson : minimum valid from");
+
1701 }
+
1702 if (remaining.size())
+
1703 curr[jss::remaining] = std::move(remaining);
+
1704 }
+
1705
+
1706 // Trusted validator keys
+
1707 Json::Value& jValidatorKeys =
+
1708 (res[jss::trusted_validator_keys] = Json::arrayValue);
+
1709 for (auto const& k : trustedMasterKeys_)
+
1710 {
+
1711 jValidatorKeys.append(toBase58(TokenType::NodePublic, k));
+
1712 }
+
1713
+
1714 // signing keys
+
1715 Json::Value& jSigningKeys = (res[jss::signing_keys] = Json::objectValue);
+
1716 validatorManifests_.for_each_manifest([&jSigningKeys,
+
1717 this](Manifest const& manifest) {
+
1718 auto it = keyListings_.find(manifest.masterKey);
+
1719 if (it != keyListings_.end() && manifest.signingKey)
+
1720 {
+
1721 jSigningKeys[toBase58(TokenType::NodePublic, manifest.masterKey)] =
+
1722 toBase58(TokenType::NodePublic, *manifest.signingKey);
+
1723 }
+
1724 });
+
1725
+
1726 // Negative UNL
+
1727 if (!negativeUNL_.empty())
+
1728 {
+
1729 Json::Value& jNegativeUNL = (res[jss::NegativeUNL] = Json::arrayValue);
+
1730 for (auto const& k : negativeUNL_)
+
1731 {
+
1732 jNegativeUNL.append(toBase58(TokenType::NodePublic, k));
+
1733 }
+
1734 }
+
1735
+
1736 return res;
+
1737}
-
1737
-
1738void
-
-
1739ValidatorList::for_each_listed(
-
1740 std::function<void(PublicKey const&, bool)> func) const
-
1741{
-
1742 std::shared_lock read_lock{mutex_};
-
1743
-
1744 for (auto const& v : keyListings_)
-
1745 func(v.first, trusted(read_lock, v.first));
-
1746}
+
1738
+
1739void
+
+
1740ValidatorList::for_each_listed(
+
1741 std::function<void(PublicKey const&, bool)> func) const
+
1742{
+
1743 std::shared_lock read_lock{mutex_};
+
1744
+
1745 for (auto const& v : keyListings_)
+
1746 func(v.first, trusted(read_lock, v.first));
+
1747}
-
1747
-
1748void
-
-
1749ValidatorList::for_each_available(
-
1750 std::function<void(
-
1751 std::string const& manifest,
-
1752 std::uint32_t version,
- -
1754 PublicKey const& pubKey,
-
1755 std::size_t maxSequence,
-
1756 uint256 const& hash)> func) const
-
1757{
-
1758 std::shared_lock read_lock{mutex_};
-
1759
-
1760 for (auto const& [key, plCollection] : publisherLists_)
-
1761 {
-
1762 if (plCollection.status != PublisherStatus::available)
-
1763 continue;
-
1764 XRPL_ASSERT(
-
1765 plCollection.maxSequence != 0,
-
1766 "xrpl::ValidatorList::for_each_available : nonzero maxSequence");
-
1767 func(
-
1768 plCollection.rawManifest,
-
1769 plCollection.rawVersion,
-
1770 buildBlobInfos(plCollection),
-
1771 key,
-
1772 plCollection.maxSequence.value_or(0),
-
1773 plCollection.fullHash);
-
1774 }
-
1775}
+
1748
+
1749void
+
+
1750ValidatorList::for_each_available(
+
1751 std::function<void(
+
1752 std::string const& manifest,
+
1753 std::uint32_t version,
+ +
1755 PublicKey const& pubKey,
+
1756 std::size_t maxSequence,
+
1757 uint256 const& hash)> func) const
+
1758{
+
1759 std::shared_lock read_lock{mutex_};
+
1760
+
1761 for (auto const& [key, plCollection] : publisherLists_)
+
1762 {
+
1763 if (plCollection.status != PublisherStatus::available)
+
1764 continue;
+
1765 XRPL_ASSERT(
+
1766 plCollection.maxSequence != 0,
+
1767 "xrpl::ValidatorList::for_each_available : nonzero maxSequence");
+
1768 func(
+
1769 plCollection.rawManifest,
+
1770 plCollection.rawVersion,
+
1771 buildBlobInfos(plCollection),
+
1772 key,
+
1773 plCollection.maxSequence.value_or(0),
+
1774 plCollection.fullHash);
+
1775 }
+
1776}
-
1776
- -
-
1778ValidatorList::getAvailable(
-
1779 std::string_view pubKey,
-
1780 std::optional<std::uint32_t> forceVersion /* = {} */)
-
1781{
-
1782 std::shared_lock read_lock{mutex_};
-
1783
-
1784 auto const keyBlob = strViewUnHex(pubKey);
-
1785
-
1786 if (!keyBlob || !publicKeyType(makeSlice(*keyBlob)))
-
1787 {
-
1788 JLOG(j_.warn()) << "Invalid requested validator list publisher key: "
-
1789 << pubKey;
-
1790 return {};
-
1791 }
-
1792
-
1793 auto id = PublicKey(makeSlice(*keyBlob));
-
1794
-
1795 auto const iter = publisherLists_.find(id);
-
1796
-
1797 if (iter == publisherLists_.end() ||
-
1798 iter->second.status != PublisherStatus::available)
-
1799 return {};
-
1800
-
1801 Json::Value value =
-
1802 buildFileData(std::string{pubKey}, iter->second, forceVersion, j_);
-
1803
-
1804 return value;
-
1805}
+
1777
+ +
+
1779ValidatorList::getAvailable(
+
1780 std::string_view pubKey,
+
1781 std::optional<std::uint32_t> forceVersion /* = {} */)
+
1782{
+
1783 std::shared_lock read_lock{mutex_};
+
1784
+
1785 auto const keyBlob = strViewUnHex(pubKey);
+
1786
+
1787 if (!keyBlob || !publicKeyType(makeSlice(*keyBlob)))
+
1788 {
+
1789 JLOG(j_.warn()) << "Invalid requested validator list publisher key: "
+
1790 << pubKey;
+
1791 return {};
+
1792 }
+
1793
+
1794 auto id = PublicKey(makeSlice(*keyBlob));
+
1795
+
1796 auto const iter = publisherLists_.find(id);
+
1797
+
1798 if (iter == publisherLists_.end() ||
+
1799 iter->second.status != PublisherStatus::available)
+
1800 return {};
+
1801
+
1802 Json::Value value =
+
1803 buildFileData(std::string{pubKey}, iter->second, forceVersion, j_);
+
1804
+
1805 return value;
+
1806}
-
1806
- -
-
1808ValidatorList::calculateQuorum(
-
1809 std::size_t unlSize,
-
1810 std::size_t effectiveUnlSize,
-
1811 std::size_t seenSize)
-
1812{
-
1813 // Use quorum if specified via command line.
-
1814 if (minimumQuorum_ > 0)
-
1815 {
-
1816 JLOG(j_.warn()) << "Using potentially unsafe quorum of "
-
1817 << *minimumQuorum_
-
1818 << " as specified on the command line";
-
1819 return *minimumQuorum_;
-
1820 }
-
1821
-
1822 if (!publisherLists_.empty())
-
1823 {
-
1824 // Do not use achievable quorum until lists from a sufficient number of
-
1825 // configured publishers are available
- -
1827 for (auto const& list : publisherLists_)
-
1828 {
-
1829 if (list.second.status != PublisherStatus::available)
-
1830 unavailable += 1;
-
1831 }
-
1832 // There are two, subtly different, sides to list threshold:
-
1833 //
-
1834 // 1. The minimum required intersection between lists listThreshold_
-
1835 // for a validator to be included in trustedMasterKeys_.
-
1836 // If this many (or more) publishers are unavailable, we are likely
-
1837 // to NOT include a validator which otherwise would have been used.
-
1838 // We disable quorum if this happens.
-
1839 // 2. The minimum number of publishers which, when unavailable, will
-
1840 // prevent us from hitting the above threshold on ANY validator.
-
1841 // This is calculated as:
-
1842 // N - M + 1
-
1843 // where
-
1844 // N: number of publishers i.e. publisherLists_.size()
-
1845 // M: minimum required intersection i.e. listThreshold_
-
1846 // If this happens, we still have this local validator and we do not
-
1847 // want it to form a quorum of 1, so we disable quorum as well.
-
1848 //
-
1849 // We disable quorum if the number of unavailable publishers exceeds
-
1850 // either of the above thresholds
-
1851 auto const errorThreshold = std::min(
-
1852 listThreshold_, //
-
1853 publisherLists_.size() - listThreshold_ + 1);
-
1854 XRPL_ASSERT(
-
1855 errorThreshold > 0,
-
1856 "xrpl::ValidatorList::calculateQuorum : nonzero error threshold");
-
1857 if (unavailable >= errorThreshold)
- -
1859 }
-
1860
-
1861 // Use an 80% quorum to balance fork safety, liveness, and required UNL
-
1862 // overlap.
-
1863 //
-
1864 // Theorem 8 of the Analysis of the XRP Ledger Consensus Protocol
-
1865 // (https://arxiv.org/abs/1802.07242) says:
-
1866 // XRP LCP guarantees fork safety if Oi,j > nj/2 + ni − qi + ti,j
-
1867 // for every pair of nodes Pi, Pj.
-
1868 //
-
1869 // ni: size of Pi's UNL
-
1870 // nj: size of Pj's UNL
-
1871 // Oi,j: number of validators in both UNLs
-
1872 // qi: validation quorum for Pi's UNL
-
1873 // ti, tj: maximum number of allowed Byzantine faults in Pi and Pj's
-
1874 // UNLs ti,j: min{ti, tj, Oi,j}
-
1875 //
-
1876 // Assume ni < nj, meaning and ti,j = ti
-
1877 //
-
1878 // For qi = .8*ni, we make ti <= .2*ni
-
1879 // (We could make ti lower and tolerate less UNL overlap. However in
-
1880 // order to prioritize safety over liveness, we need ti >= ni - qi)
-
1881 //
-
1882 // An 80% quorum allows two UNLs to safely have < .2*ni unique
-
1883 // validators between them:
-
1884 //
-
1885 // pi = ni - Oi,j
-
1886 // pj = nj - Oi,j
-
1887 //
-
1888 // Oi,j > nj/2 + ni − qi + ti,j
-
1889 // ni - pi > (ni - pi + pj)/2 + ni − .8*ni + .2*ni
-
1890 // pi + pj < .2*ni
-
1891 //
-
1892 // Note that the negative UNL protocol introduced the
-
1893 // AbsoluteMinimumQuorum which is 60% of the original UNL size. The
-
1894 // effective quorum should not be lower than it.
-
1895 return static_cast<std::size_t>(std::max(
-
1896 std::ceil(effectiveUnlSize * 0.8f), std::ceil(unlSize * 0.6f)));
-
1897}
+
1807
+ +
+
1809ValidatorList::calculateQuorum(
+
1810 std::size_t unlSize,
+
1811 std::size_t effectiveUnlSize,
+
1812 std::size_t seenSize)
+
1813{
+
1814 // Use quorum if specified via command line.
+
1815 if (minimumQuorum_ > 0)
+
1816 {
+
1817 JLOG(j_.warn()) << "Using potentially unsafe quorum of "
+
1818 << *minimumQuorum_
+
1819 << " as specified on the command line";
+
1820 return *minimumQuorum_;
+
1821 }
+
1822
+
1823 if (!publisherLists_.empty())
+
1824 {
+
1825 // Do not use achievable quorum until lists from a sufficient number of
+
1826 // configured publishers are available
+ +
1828 for (auto const& list : publisherLists_)
+
1829 {
+
1830 if (list.second.status != PublisherStatus::available)
+
1831 unavailable += 1;
+
1832 }
+
1833 // There are two, subtly different, sides to list threshold:
+
1834 //
+
1835 // 1. The minimum required intersection between lists listThreshold_
+
1836 // for a validator to be included in trustedMasterKeys_.
+
1837 // If this many (or more) publishers are unavailable, we are likely
+
1838 // to NOT include a validator which otherwise would have been used.
+
1839 // We disable quorum if this happens.
+
1840 // 2. The minimum number of publishers which, when unavailable, will
+
1841 // prevent us from hitting the above threshold on ANY validator.
+
1842 // This is calculated as:
+
1843 // N - M + 1
+
1844 // where
+
1845 // N: number of publishers i.e. publisherLists_.size()
+
1846 // M: minimum required intersection i.e. listThreshold_
+
1847 // If this happens, we still have this local validator and we do not
+
1848 // want it to form a quorum of 1, so we disable quorum as well.
+
1849 //
+
1850 // We disable quorum if the number of unavailable publishers exceeds
+
1851 // either of the above thresholds
+
1852 auto const errorThreshold = std::min(
+
1853 listThreshold_, //
+
1854 publisherLists_.size() - listThreshold_ + 1);
+
1855 XRPL_ASSERT(
+
1856 errorThreshold > 0,
+
1857 "xrpl::ValidatorList::calculateQuorum : nonzero error threshold");
+
1858 if (unavailable >= errorThreshold)
+ +
1860 }
+
1861
+
1862 // Use an 80% quorum to balance fork safety, liveness, and required UNL
+
1863 // overlap.
+
1864 //
+
1865 // Theorem 8 of the Analysis of the XRP Ledger Consensus Protocol
+
1866 // (https://arxiv.org/abs/1802.07242) says:
+
1867 // XRP LCP guarantees fork safety if Oi,j > nj/2 + ni − qi + ti,j
+
1868 // for every pair of nodes Pi, Pj.
+
1869 //
+
1870 // ni: size of Pi's UNL
+
1871 // nj: size of Pj's UNL
+
1872 // Oi,j: number of validators in both UNLs
+
1873 // qi: validation quorum for Pi's UNL
+
1874 // ti, tj: maximum number of allowed Byzantine faults in Pi and Pj's
+
1875 // UNLs ti,j: min{ti, tj, Oi,j}
+
1876 //
+
1877 // Assume ni < nj, meaning and ti,j = ti
+
1878 //
+
1879 // For qi = .8*ni, we make ti <= .2*ni
+
1880 // (We could make ti lower and tolerate less UNL overlap. However in
+
1881 // order to prioritize safety over liveness, we need ti >= ni - qi)
+
1882 //
+
1883 // An 80% quorum allows two UNLs to safely have < .2*ni unique
+
1884 // validators between them:
+
1885 //
+
1886 // pi = ni - Oi,j
+
1887 // pj = nj - Oi,j
+
1888 //
+
1889 // Oi,j > nj/2 + ni − qi + ti,j
+
1890 // ni - pi > (ni - pi + pj)/2 + ni − .8*ni + .2*ni
+
1891 // pi + pj < .2*ni
+
1892 //
+
1893 // Note that the negative UNL protocol introduced the
+
1894 // AbsoluteMinimumQuorum which is 60% of the original UNL size. The
+
1895 // effective quorum should not be lower than it.
+
1896 return static_cast<std::size_t>(std::max(
+
1897 std::ceil(effectiveUnlSize * 0.8f), std::ceil(unlSize * 0.6f)));
+
1898}
-
1898
- -
-
1900ValidatorList::updateTrusted(
-
1901 hash_set<NodeID> const& seenValidators,
-
1902 NetClock::time_point closeTime,
-
1903 NetworkOPs& ops,
-
1904 Overlay& overlay,
-
1905 HashRouter& hashRouter)
-
1906{
-
1907 using namespace std::chrono_literals;
-
1908 if (timeKeeper_.now() > closeTime + 30s)
-
1909 closeTime = timeKeeper_.now();
-
1910
-
1911 std::lock_guard lock{mutex_};
-
1912
-
1913 // Rotate pending and remove expired published lists
-
1914 bool good = true;
-
1915 // localPublisherList is not processed here. This is because the
-
1916 // Validators specified in the local config file do not expire nor do
-
1917 // they have a "remaining" section of PublisherList.
-
1918 for (auto& [pubKey, collection] : publisherLists_)
-
1919 {
-
1920 {
-
1921 auto& remaining = collection.remaining;
-
1922 auto const firstIter = remaining.begin();
-
1923 auto iter = firstIter;
-
1924 if (iter != remaining.end() && iter->second.validFrom <= closeTime)
-
1925 {
-
1926 // Find the LAST candidate that is ready to go live.
-
1927 for (auto next = std::next(iter); next != remaining.end() &&
-
1928 next->second.validFrom <= closeTime;
-
1929 ++iter, ++next)
-
1930 {
-
1931 XRPL_ASSERT(
-
1932 std::next(iter) == next,
-
1933 "xrpl::ValidatorList::updateTrusted : sequential "
-
1934 "remaining");
-
1935 }
-
1936 XRPL_ASSERT(
-
1937 iter != remaining.end(),
-
1938 "xrpl::ValidatorList::updateTrusted : non-end of "
-
1939 "remaining");
-
1940
-
1941 // Rotate the pending list in to current
-
1942 auto sequence = iter->first;
-
1943 auto& candidate = iter->second;
-
1944 auto& current = collection.current;
-
1945 XRPL_ASSERT(
-
1946 candidate.validFrom <= closeTime,
-
1947 "xrpl::ValidatorList::updateTrusted : maximum time");
-
1948
-
1949 auto const oldList = current.list;
-
1950 current = std::move(candidate);
-
1951 if (collection.status != PublisherStatus::available)
-
1952 collection.status = PublisherStatus::available;
-
1953 XRPL_ASSERT(
-
1954 current.sequence == sequence,
-
1955 "xrpl::ValidatorList::updateTrusted : sequence match");
-
1956 // If the list is expired, remove the validators so they don't
-
1957 // get processed in. The expiration check below will do the rest
-
1958 // of the work
-
1959 if (current.validUntil <= closeTime)
-
1960 current.list.clear();
-
1961
-
1962 updatePublisherList(pubKey, current, oldList, lock);
-
1963
-
1964 // Only broadcast the current, which will consequently only
-
1965 // send to peers that don't understand v2, or which are
-
1966 // unknown (unlikely). Those that do understand v2 should
-
1967 // already have this list and are in the process of
-
1968 // switching themselves.
-
1969 broadcastBlobs(
-
1970 pubKey,
-
1971 collection,
-
1972 sequence,
-
1973 current.hash,
-
1974 overlay,
-
1975 hashRouter,
-
1976 j_);
-
1977
-
1978 // Erase any candidates that we skipped over, plus this one
-
1979 remaining.erase(firstIter, std::next(iter));
-
1980 }
-
1981 }
-
1982 // Remove if expired
-
1983 // ValidatorLists specified in the local config file never expire.
-
1984 // Hence, the below steps are not relevant for localPublisherList
-
1985 if (collection.status == PublisherStatus::available &&
-
1986 collection.current.validUntil <= closeTime)
-
1987 {
-
1988 removePublisherList(lock, pubKey, PublisherStatus::expired);
-
1989 ops.setUNLBlocked();
-
1990 }
-
1991 if (collection.status != PublisherStatus::available)
-
1992 good = false;
-
1993 }
-
1994 if (good)
-
1995 ops.clearUNLBlocked();
-
1996
-
1997 TrustChanges trustChanges;
-
1998
-
1999 auto it = trustedMasterKeys_.cbegin();
-
2000 while (it != trustedMasterKeys_.cend())
-
2001 {
-
2002 auto const kit = keyListings_.find(*it);
-
2003 if (kit == keyListings_.end() || //
-
2004 kit->second < listThreshold_ || //
-
2005 validatorManifests_.revoked(*it))
-
2006 {
-
2007 trustChanges.removed.insert(calcNodeID(*it));
-
2008 it = trustedMasterKeys_.erase(it);
-
2009 }
-
2010 else
-
2011 {
-
2012 XRPL_ASSERT(
-
2013 kit->second >= listThreshold_,
-
2014 "xrpl::ValidatorList::updateTrusted : count meets threshold");
-
2015 ++it;
-
2016 }
-
2017 }
-
2018
-
2019 for (auto const& val : keyListings_)
-
2020 {
-
2021 if (val.second >= listThreshold_ &&
-
2022 !validatorManifests_.revoked(val.first) &&
-
2023 trustedMasterKeys_.emplace(val.first).second)
-
2024 trustChanges.added.insert(calcNodeID(val.first));
-
2025 }
-
2026
-
2027 // If there were any changes, we need to update the ephemeral signing
-
2028 // keys:
-
2029 if (!trustChanges.added.empty() || !trustChanges.removed.empty())
-
2030 {
-
2031 trustedSigningKeys_.clear();
-
2032
-
2033 // trustedMasterKeys_ contain non-revoked manifests only. Hence the
-
2034 // manifests must contain a valid signingKey
-
2035 for (auto const& k : trustedMasterKeys_)
-
2036 {
-
2037 std::optional<PublicKey> const signingKey =
-
2038 validatorManifests_.getSigningKey(k);
-
2039 XRPL_ASSERT(
-
2040 signingKey,
-
2041 "xrpl::ValidatorList::updateTrusted : found signing key");
-
2042 trustedSigningKeys_.insert(*signingKey);
-
2043 }
-
2044 }
-
2045
-
2046 JLOG(j_.debug())
-
2047 << trustedMasterKeys_.size() << " of " << keyListings_.size()
-
2048 << " listed validators eligible for inclusion in the trusted set";
-
2049
-
2050 auto const unlSize = trustedMasterKeys_.size();
-
2051 auto effectiveUnlSize = unlSize;
-
2052 auto seenSize = seenValidators.size();
-
2053 if (!negativeUNL_.empty())
-
2054 {
-
2055 for (auto const& k : trustedMasterKeys_)
-
2056 {
-
2057 if (negativeUNL_.count(k))
-
2058 --effectiveUnlSize;
-
2059 }
-
2060 hash_set<NodeID> negUnlNodeIDs;
-
2061 for (auto const& k : negativeUNL_)
-
2062 {
-
2063 negUnlNodeIDs.emplace(calcNodeID(k));
-
2064 }
-
2065 for (auto const& nid : seenValidators)
-
2066 {
-
2067 if (negUnlNodeIDs.count(nid))
-
2068 --seenSize;
-
2069 }
-
2070 }
-
2071 quorum_ = calculateQuorum(unlSize, effectiveUnlSize, seenSize);
-
2072
-
2073 JLOG(j_.debug()) << "Using quorum of " << quorum_ << " for new set of "
-
2074 << unlSize << " trusted validators ("
-
2075 << trustChanges.added.size() << " added, "
-
2076 << trustChanges.removed.size() << " removed)";
-
2077
-
2078 if (unlSize < quorum_)
-
2079 {
-
2080 JLOG(j_.warn()) << "New quorum of " << quorum_
-
2081 << " exceeds the number of trusted validators ("
-
2082 << unlSize << ")";
-
2083 }
-
2084
-
2085 if ((publisherLists_.size() || localPublisherList.list.size()) &&
-
2086 unlSize == 0)
-
2087 {
-
2088 // No validators. Lock down.
-
2089 ops.setUNLBlocked();
-
2090 }
-
2091
-
2092 return trustChanges;
-
2093}
+
1899
+ +
+
1901ValidatorList::updateTrusted(
+
1902 hash_set<NodeID> const& seenValidators,
+
1903 NetClock::time_point closeTime,
+
1904 NetworkOPs& ops,
+
1905 Overlay& overlay,
+
1906 HashRouter& hashRouter)
+
1907{
+
1908 using namespace std::chrono_literals;
+
1909 if (timeKeeper_.now() > closeTime + 30s)
+
1910 closeTime = timeKeeper_.now();
+
1911
+
1912 std::lock_guard lock{mutex_};
+
1913
+
1914 // Rotate pending and remove expired published lists
+
1915 bool good = true;
+
1916 // localPublisherList is not processed here. This is because the
+
1917 // Validators specified in the local config file do not expire nor do
+
1918 // they have a "remaining" section of PublisherList.
+
1919 for (auto& [pubKey, collection] : publisherLists_)
+
1920 {
+
1921 {
+
1922 auto& remaining = collection.remaining;
+
1923 auto const firstIter = remaining.begin();
+
1924 auto iter = firstIter;
+
1925 if (iter != remaining.end() && iter->second.validFrom <= closeTime)
+
1926 {
+
1927 // Find the LAST candidate that is ready to go live.
+
1928 for (auto next = std::next(iter); next != remaining.end() &&
+
1929 next->second.validFrom <= closeTime;
+
1930 ++iter, ++next)
+
1931 {
+
1932 XRPL_ASSERT(
+
1933 std::next(iter) == next,
+
1934 "xrpl::ValidatorList::updateTrusted : sequential "
+
1935 "remaining");
+
1936 }
+
1937 XRPL_ASSERT(
+
1938 iter != remaining.end(),
+
1939 "xrpl::ValidatorList::updateTrusted : non-end of "
+
1940 "remaining");
+
1941
+
1942 // Rotate the pending list in to current
+
1943 auto sequence = iter->first;
+
1944 auto& candidate = iter->second;
+
1945 auto& current = collection.current;
+
1946 XRPL_ASSERT(
+
1947 candidate.validFrom <= closeTime,
+
1948 "xrpl::ValidatorList::updateTrusted : maximum time");
+
1949
+
1950 auto const oldList = current.list;
+
1951 current = std::move(candidate);
+
1952 if (collection.status != PublisherStatus::available)
+
1953 collection.status = PublisherStatus::available;
+
1954 XRPL_ASSERT(
+
1955 current.sequence == sequence,
+
1956 "xrpl::ValidatorList::updateTrusted : sequence match");
+
1957 // If the list is expired, remove the validators so they don't
+
1958 // get processed in. The expiration check below will do the rest
+
1959 // of the work
+
1960 if (current.validUntil <= closeTime)
+
1961 current.list.clear();
+
1962
+
1963 updatePublisherList(pubKey, current, oldList, lock);
+
1964
+
1965 // Only broadcast the current, which will consequently only
+
1966 // send to peers that don't understand v2, or which are
+
1967 // unknown (unlikely). Those that do understand v2 should
+
1968 // already have this list and are in the process of
+
1969 // switching themselves.
+
1970 broadcastBlobs(
+
1971 pubKey,
+
1972 collection,
+
1973 sequence,
+
1974 current.hash,
+
1975 overlay,
+
1976 hashRouter,
+
1977 j_);
+
1978
+
1979 // Erase any candidates that we skipped over, plus this one
+
1980 remaining.erase(firstIter, std::next(iter));
+
1981 }
+
1982 }
+
1983 // Remove if expired
+
1984 // ValidatorLists specified in the local config file never expire.
+
1985 // Hence, the below steps are not relevant for localPublisherList
+
1986 if (collection.status == PublisherStatus::available &&
+
1987 collection.current.validUntil <= closeTime)
+
1988 {
+
1989 removePublisherList(lock, pubKey, PublisherStatus::expired);
+
1990 ops.setUNLBlocked();
+
1991 }
+
1992 if (collection.status != PublisherStatus::available)
+
1993 good = false;
+
1994 }
+
1995 if (good)
+
1996 ops.clearUNLBlocked();
+
1997
+
1998 TrustChanges trustChanges;
+
1999
+
2000 auto it = trustedMasterKeys_.cbegin();
+
2001 while (it != trustedMasterKeys_.cend())
+
2002 {
+
2003 auto const kit = keyListings_.find(*it);
+
2004 if (kit == keyListings_.end() || //
+
2005 kit->second < listThreshold_ || //
+
2006 validatorManifests_.revoked(*it))
+
2007 {
+
2008 trustChanges.removed.insert(calcNodeID(*it));
+
2009 it = trustedMasterKeys_.erase(it);
+
2010 }
+
2011 else
+
2012 {
+
2013 XRPL_ASSERT(
+
2014 kit->second >= listThreshold_,
+
2015 "xrpl::ValidatorList::updateTrusted : count meets threshold");
+
2016 ++it;
+
2017 }
+
2018 }
+
2019
+
2020 for (auto const& val : keyListings_)
+
2021 {
+
2022 if (val.second >= listThreshold_ &&
+
2023 !validatorManifests_.revoked(val.first) &&
+
2024 trustedMasterKeys_.emplace(val.first).second)
+
2025 trustChanges.added.insert(calcNodeID(val.first));
+
2026 }
+
2027
+
2028 // If there were any changes, we need to update the ephemeral signing
+
2029 // keys:
+
2030 if (!trustChanges.added.empty() || !trustChanges.removed.empty())
+
2031 {
+
2032 trustedSigningKeys_.clear();
+
2033
+
2034 // trustedMasterKeys_ contain non-revoked manifests only. Hence the
+
2035 // manifests must contain a valid signingKey
+
2036 for (auto const& k : trustedMasterKeys_)
+
2037 {
+
2038 std::optional<PublicKey> const signingKey =
+
2039 validatorManifests_.getSigningKey(k);
+
2040 XRPL_ASSERT(
+
2041 signingKey,
+
2042 "xrpl::ValidatorList::updateTrusted : found signing key");
+
2043 trustedSigningKeys_.insert(*signingKey);
+
2044 }
+
2045 }
+
2046
+
2047 JLOG(j_.debug())
+
2048 << trustedMasterKeys_.size() << " of " << keyListings_.size()
+
2049 << " listed validators eligible for inclusion in the trusted set";
+
2050
+
2051 auto const unlSize = trustedMasterKeys_.size();
+
2052 auto effectiveUnlSize = unlSize;
+
2053 auto seenSize = seenValidators.size();
+
2054 if (!negativeUNL_.empty())
+
2055 {
+
2056 for (auto const& k : trustedMasterKeys_)
+
2057 {
+
2058 if (negativeUNL_.count(k))
+
2059 --effectiveUnlSize;
+
2060 }
+
2061 hash_set<NodeID> negUnlNodeIDs;
+
2062 for (auto const& k : negativeUNL_)
+
2063 {
+
2064 negUnlNodeIDs.emplace(calcNodeID(k));
+
2065 }
+
2066 for (auto const& nid : seenValidators)
+
2067 {
+
2068 if (negUnlNodeIDs.count(nid))
+
2069 --seenSize;
+
2070 }
+
2071 }
+
2072 quorum_ = calculateQuorum(unlSize, effectiveUnlSize, seenSize);
+
2073
+
2074 JLOG(j_.debug()) << "Using quorum of " << quorum_ << " for new set of "
+
2075 << unlSize << " trusted validators ("
+
2076 << trustChanges.added.size() << " added, "
+
2077 << trustChanges.removed.size() << " removed)";
+
2078
+
2079 if (unlSize < quorum_)
+
2080 {
+
2081 JLOG(j_.warn()) << "New quorum of " << quorum_
+
2082 << " exceeds the number of trusted validators ("
+
2083 << unlSize << ")";
+
2084 }
+
2085
+
2086 if ((publisherLists_.size() || localPublisherList.list.size()) &&
+
2087 unlSize == 0)
+
2088 {
+
2089 // No validators. Lock down.
+
2090 ops.setUNLBlocked();
+
2091 }
+
2092
+
2093 return trustChanges;
+
2094}
-
2094
- -
-
2096ValidatorList::getTrustedMasterKeys() const
-
2097{
-
2098 std::shared_lock read_lock{mutex_};
-
2099 return trustedMasterKeys_;
-
2100}
+
2095
+ +
+
2097ValidatorList::getTrustedMasterKeys() const
+
2098{
+
2099 std::shared_lock read_lock{mutex_};
+
2100 return trustedMasterKeys_;
+
2101}
-
2101
- -
-
2103ValidatorList::getListThreshold() const
-
2104{
-
2105 std::shared_lock read_lock{mutex_};
-
2106 return listThreshold_;
-
2107}
+
2102
+ +
+
2104ValidatorList::getListThreshold() const
+
2105{
+
2106 std::shared_lock read_lock{mutex_};
+
2107 return listThreshold_;
+
2108}
-
2108
- -
-
2110ValidatorList::getNegativeUNL() const
-
2111{
-
2112 std::shared_lock read_lock{mutex_};
-
2113 return negativeUNL_;
-
2114}
+
2109
+ +
+
2111ValidatorList::getNegativeUNL() const
+
2112{
+
2113 std::shared_lock read_lock{mutex_};
+
2114 return negativeUNL_;
+
2115}
-
2115
-
2116void
-
-
2117ValidatorList::setNegativeUNL(hash_set<PublicKey> const& negUnl)
-
2118{
-
2119 std::lock_guard lock{mutex_};
-
2120 negativeUNL_ = negUnl;
-
2121}
+
2116
+
2117void
+
+
2118ValidatorList::setNegativeUNL(hash_set<PublicKey> const& negUnl)
+
2119{
+
2120 std::lock_guard lock{mutex_};
+
2121 negativeUNL_ = negUnl;
+
2122}
-
2122
- -
-
2124ValidatorList::negativeUNLFilter(
-
2125 std::vector<std::shared_ptr<STValidation>>&& validations) const
-
2126{
-
2127 // Remove validations that are from validators on the negative UNL.
-
2128 auto ret = std::move(validations);
-
2129
-
2130 std::shared_lock read_lock{mutex_};
-
2131 if (!negativeUNL_.empty())
-
2132 {
-
2133 ret.erase(
- -
2135 ret.begin(),
-
2136 ret.end(),
-
2137 [&](auto const& v) -> bool {
-
2138 if (auto const masterKey =
-
2139 getTrustedKey(read_lock, v->getSignerPublic());
-
2140 masterKey)
-
2141 {
-
2142 return negativeUNL_.count(*masterKey);
-
2143 }
-
2144 else
-
2145 {
-
2146 return false;
-
2147 }
-
2148 }),
-
2149 ret.end());
-
2150 }
-
2151
-
2152 return ret;
-
2153}
+
2123
+ +
+
2125ValidatorList::negativeUNLFilter(
+
2126 std::vector<std::shared_ptr<STValidation>>&& validations) const
+
2127{
+
2128 // Remove validations that are from validators on the negative UNL.
+
2129 auto ret = std::move(validations);
+
2130
+
2131 std::shared_lock read_lock{mutex_};
+
2132 if (!negativeUNL_.empty())
+
2133 {
+
2134 ret.erase(
+ +
2136 ret.begin(),
+
2137 ret.end(),
+
2138 [&](auto const& v) -> bool {
+
2139 if (auto const masterKey =
+
2140 getTrustedKey(read_lock, v->getSignerPublic());
+
2141 masterKey)
+
2142 {
+
2143 return negativeUNL_.count(*masterKey);
+
2144 }
+
2145 else
+
2146 {
+
2147 return false;
+
2148 }
+
2149 }),
+
2150 ret.end());
+
2151 }
+
2152
+
2153 return ret;
+
2154}
-
2154
-
2155} // namespace xrpl
+
2155
+
2156} // namespace xrpl
T accumulate(T... args)
T at(T... args)
T back(T... args)
@@ -2399,47 +2400,47 @@ $(document).ready(function() { init_codefold(0); });
An immutable linear range of bytes.
Definition Slice.h:27
Manages various times used by the server.
Definition TimeKeeper.h:13
time_point now() const override
Returns the current time, using the server's clock.
Definition TimeKeeper.h:45
-
static std::pair< std::size_t, std::size_t > buildValidatorListMessages(std::size_t messageVersion, std::uint64_t peerSequence, std::size_t maxSequence, std::uint32_t rawVersion, std::string const &rawManifest, std::map< std::size_t, ValidatorBlobInfo > const &blobInfos, std::vector< MessageWithHash > &messages, std::size_t maxSize=maximumMessageSize)
-
static void sendValidatorList(Peer &peer, std::uint64_t peerSequence, PublicKey const &publisherKey, std::size_t maxSequence, std::uint32_t rawVersion, std::string const &rawManifest, std::map< std::size_t, ValidatorBlobInfo > const &blobInfos, HashRouter &hashRouter, beast::Journal j)
+
static std::pair< std::size_t, std::size_t > buildValidatorListMessages(std::size_t messageVersion, std::uint64_t peerSequence, std::size_t maxSequence, std::uint32_t rawVersion, std::string const &rawManifest, std::map< std::size_t, ValidatorBlobInfo > const &blobInfos, std::vector< MessageWithHash > &messages, std::size_t maxSize=maximumMessageSize)
+
static void sendValidatorList(Peer &peer, std::uint64_t peerSequence, PublicKey const &publisherKey, std::size_t maxSequence, std::uint32_t rawVersion, std::string const &rawManifest, std::map< std::size_t, ValidatorBlobInfo > const &blobInfos, HashRouter &hashRouter, beast::Journal j)
TimeKeeper & timeKeeper_
static constexpr std::uint32_t supportedListVersions[]
PublisherList localPublisherList
hash_set< PublicKey > trustedMasterKeys_
-
bool trustedPublisher(PublicKey const &identity) const
Returns true if public key is a trusted publisher.
+
bool trustedPublisher(PublicKey const &identity) const
Returns true if public key is a trusted publisher.
static constexpr std::size_t maxSupportedBlobs
ValidatorList(ManifestCache &validatorManifests, ManifestCache &publisherManifests, TimeKeeper &timeKeeper, std::string const &databasePath, beast::Journal j, std::optional< std::size_t > minimumQuorum=std::nullopt)
static Json::Value buildFileData(std::string const &pubKey, PublisherListCollection const &pubCollection, beast::Journal j)
Build a Json representation of the collection, suitable for writing to a cache file,...
-
std::vector< std::string > loadLists()
+
std::vector< std::string > loadLists()
std::optional< PublicKey > localPubKey_
std::atomic< std::size_t > quorum_
-
std::pair< ListDisposition, std::optional< PublicKey > > verify(lock_guard const &, Json::Value &list, Manifest manifest, std::string const &blob, std::string const &signature)
Check response for trusted valid published list.
+
std::pair< ListDisposition, std::optional< PublicKey > > verify(lock_guard const &, Json::Value &list, Manifest manifest, std::string const &blob, std::string const &signature)
Check response for trusted valid published list.
beast::Journal const j_
boost::filesystem::path const dataPath_
std::shared_mutex mutex_
bool load(std::optional< PublicKey > const &localSigningKey, std::vector< std::string > const &configKeys, std::vector< std::string > const &publisherKeys, std::optional< std::size_t > listThreshold={})
Load configured trusted keys.
-
bool removePublisherList(lock_guard const &, PublicKey const &publisherKey, PublisherStatus reason)
Stop trusting publisher's list of keys.
-
PublisherListStats applyLists(std::string const &manifest, std::uint32_t version, std::vector< ValidatorBlobInfo > const &blobs, std::string siteUri, std::optional< uint256 > const &hash={})
Apply multiple published lists of public keys.
-
std::optional< PublicKey > localPublicKey() const
This function returns the local validator public key or a std::nullopt.
-
PublisherListStats applyList(std::string const &globalManifest, std::optional< std::string > const &localManifest, std::string const &blob, std::string const &signature, std::uint32_t version, std::string siteUri, std::optional< uint256 > const &hash, lock_guard const &)
Apply published list of public keys.
-
std::optional< PublicKey > getListedKey(PublicKey const &identity) const
Returns listed master public if public key is included on any lists.
+
bool removePublisherList(lock_guard const &, PublicKey const &publisherKey, PublisherStatus reason)
Stop trusting publisher's list of keys.
+
PublisherListStats applyLists(std::string const &manifest, std::uint32_t version, std::vector< ValidatorBlobInfo > const &blobs, std::string siteUri, std::optional< uint256 > const &hash={})
Apply multiple published lists of public keys.
+
std::optional< PublicKey > localPublicKey() const
This function returns the local validator public key or a std::nullopt.
+
PublisherListStats applyList(std::string const &globalManifest, std::optional< std::string > const &localManifest, std::string const &blob, std::string const &signature, std::uint32_t version, std::string siteUri, std::optional< uint256 > const &hash, lock_guard const &)
Apply published list of public keys.
+
std::optional< PublicKey > getListedKey(PublicKey const &identity) const
Returns listed master public if public key is included on any lists.
void cacheValidatorFile(lock_guard const &lock, PublicKey const &pubKey) const
Write a JSON UNL to a cache file.
std::optional< std::size_t > minimumQuorum_
static std::vector< ValidatorBlobInfo > parseBlobs(std::uint32_t version, Json::Value const &body)
Pull the blob/signature/manifest information out of the appropriate Json body fields depending on the...
ManifestCache & publisherManifests_
hash_map< PublicKey, std::size_t > keyListings_
-
std::optional< TimeKeeper::time_point > expires() const
Return the time when the validator list will expire.
-
static void buildBlobInfos(std::map< std::size_t, ValidatorBlobInfo > &blobInfos, PublisherListCollection const &lists)
+
std::optional< TimeKeeper::time_point > expires() const
Return the time when the validator list will expire.
+
static void buildBlobInfos(std::map< std::size_t, ValidatorBlobInfo > &blobInfos, PublisherListCollection const &lists)
ManifestCache & validatorManifests_
std::size_t listThreshold_
-
static void broadcastBlobs(PublicKey const &publisherKey, PublisherListCollection const &lists, std::size_t maxSequence, uint256 const &hash, Overlay &overlay, HashRouter &hashRouter, beast::Journal j)
-
std::size_t count() const
Return the number of configured validator list sites.
-
std::optional< PublicKey > getTrustedKey(PublicKey const &identity) const
Returns master public key if public key is trusted.
-
void updatePublisherList(PublicKey const &pubKey, PublisherList const &current, std::vector< PublicKey > const &oldList, lock_guard const &)
-
PublisherListStats applyListsAndBroadcast(std::string const &manifest, std::uint32_t version, std::vector< ValidatorBlobInfo > const &blobs, std::string siteUri, uint256 const &hash, Overlay &overlay, HashRouter &hashRouter, NetworkOPs &networkOPs)
Apply multiple published lists of public keys, then broadcast it to all peers that have not seen it o...
+
static void broadcastBlobs(PublicKey const &publisherKey, PublisherListCollection const &lists, std::size_t maxSequence, uint256 const &hash, Overlay &overlay, HashRouter &hashRouter, beast::Journal j)
+
std::size_t count() const
Return the number of configured validator list sites.
+
std::optional< PublicKey > getTrustedKey(PublicKey const &identity) const
Returns master public key if public key is trusted.
+
void updatePublisherList(PublicKey const &pubKey, PublisherList const &current, std::vector< PublicKey > const &oldList, lock_guard const &)
+
PublisherListStats applyListsAndBroadcast(std::string const &manifest, std::uint32_t version, std::vector< ValidatorBlobInfo > const &blobs, std::string siteUri, uint256 const &hash, Overlay &overlay, HashRouter &hashRouter, NetworkOPs &networkOPs)
Apply multiple published lists of public keys, then broadcast it to all peers that have not seen it o...
boost::filesystem::path getCacheFileName(lock_guard const &, PublicKey const &pubKey) const
Get the filename used for caching UNLs.
-
bool trusted(PublicKey const &identity) const
Returns true if public key is trusted.
+
bool trusted(PublicKey const &identity) const
Returns true if public key is trusted.
static std::string const filePrefix_
-
bool listed(PublicKey const &identity) const
Returns true if public key is included on any lists.
+
bool listed(PublicKey const &identity) const
Returns true if public key is included on any lists.
hash_map< PublicKey, PublisherListCollection > publisherLists_
T clear(T... args)
diff --git a/ValidatorList_8h_source.html b/ValidatorList_8h_source.html index a45428109c..370873c177 100644 --- a/ValidatorList_8h_source.html +++ b/ValidatorList_8h_source.html @@ -699,64 +699,64 @@ $(document).ready(function() { init_codefold(0); });
A public key.
Definition PublicKey.h:43
Manages various times used by the server.
Definition TimeKeeper.h:13
-
static std::pair< std::size_t, std::size_t > buildValidatorListMessages(std::size_t messageVersion, std::uint64_t peerSequence, std::size_t maxSequence, std::uint32_t rawVersion, std::string const &rawManifest, std::map< std::size_t, ValidatorBlobInfo > const &blobInfos, std::vector< MessageWithHash > &messages, std::size_t maxSize=maximumMessageSize)
-
static void sendValidatorList(Peer &peer, std::uint64_t peerSequence, PublicKey const &publisherKey, std::size_t maxSequence, std::uint32_t rawVersion, std::string const &rawManifest, std::map< std::size_t, ValidatorBlobInfo > const &blobInfos, HashRouter &hashRouter, beast::Journal j)
+
static std::pair< std::size_t, std::size_t > buildValidatorListMessages(std::size_t messageVersion, std::uint64_t peerSequence, std::size_t maxSequence, std::uint32_t rawVersion, std::string const &rawManifest, std::map< std::size_t, ValidatorBlobInfo > const &blobInfos, std::vector< MessageWithHash > &messages, std::size_t maxSize=maximumMessageSize)
+
static void sendValidatorList(Peer &peer, std::uint64_t peerSequence, PublicKey const &publisherKey, std::size_t maxSequence, std::uint32_t rawVersion, std::string const &rawManifest, std::map< std::size_t, ValidatorBlobInfo > const &blobInfos, HashRouter &hashRouter, beast::Journal j)
TimeKeeper & timeKeeper_
static constexpr std::uint32_t supportedListVersions[]
std::shared_lock< decltype(mutex_)> shared_lock
PublisherList localPublisherList
hash_set< PublicKey > trustedMasterKeys_
-
bool trustedPublisher(PublicKey const &identity) const
Returns true if public key is a trusted publisher.
+
bool trustedPublisher(PublicKey const &identity) const
Returns true if public key is a trusted publisher.
static constexpr std::size_t maxSupportedBlobs
hash_set< PublicKey > trustedSigningKeys_
-
std::size_t calculateQuorum(std::size_t unlSize, std::size_t effectiveUnlSize, std::size_t seenSize)
Return quorum for trusted validator set.
+
std::size_t calculateQuorum(std::size_t unlSize, std::size_t effectiveUnlSize, std::size_t seenSize)
Return quorum for trusted validator set.
~ValidatorList()=default
static Json::Value buildFileData(std::string const &pubKey, PublisherListCollection const &pubCollection, beast::Journal j)
Build a Json representation of the collection, suitable for writing to a cache file,...
-
std::vector< std::string > loadLists()
-
Json::Value getJson() const
Return a JSON representation of the state of the validator list.
-
void for_each_listed(std::function< void(PublicKey const &, bool)> func) const
Invokes the callback once for every listed validation public key.
-
hash_set< PublicKey > getTrustedMasterKeys() const
get the trusted master public keys
+
std::vector< std::string > loadLists()
+
Json::Value getJson() const
Return a JSON representation of the state of the validator list.
+
void for_each_listed(std::function< void(PublicKey const &, bool)> func) const
Invokes the callback once for every listed validation public key.
+
hash_set< PublicKey > getTrustedMasterKeys() const
get the trusted master public keys
std::optional< PublicKey > localPubKey_
std::atomic< std::size_t > quorum_
QuorumKeys getQuorumKeys() const
Get the quorum and all of the trusted keys.
-
void for_each_available(std::function< void(std::string const &manifest, std::uint32_t version, std::map< std::size_t, ValidatorBlobInfo > const &blobInfos, PublicKey const &pubKey, std::size_t maxSequence, uint256 const &hash)> func) const
Invokes the callback once for every available publisher list's raw data members.
-
std::pair< ListDisposition, std::optional< PublicKey > > verify(lock_guard const &, Json::Value &list, Manifest manifest, std::string const &blob, std::string const &signature)
Check response for trusted valid published list.
+
void for_each_available(std::function< void(std::string const &manifest, std::uint32_t version, std::map< std::size_t, ValidatorBlobInfo > const &blobInfos, PublicKey const &pubKey, std::size_t maxSequence, uint256 const &hash)> func) const
Invokes the callback once for every available publisher list's raw data members.
+
std::pair< ListDisposition, std::optional< PublicKey > > verify(lock_guard const &, Json::Value &list, Manifest manifest, std::string const &blob, std::string const &signature)
Check response for trusted valid published list.
beast::Journal const j_
-
TrustChanges updateTrusted(hash_set< NodeID > const &seenValidators, NetClock::time_point closeTime, NetworkOPs &ops, Overlay &overlay, HashRouter &hashRouter)
Update trusted nodes.
+
TrustChanges updateTrusted(hash_set< NodeID > const &seenValidators, NetClock::time_point closeTime, NetworkOPs &ops, Overlay &overlay, HashRouter &hashRouter)
Update trusted nodes.
boost::filesystem::path const dataPath_
std::shared_mutex mutex_
bool load(std::optional< PublicKey > const &localSigningKey, std::vector< std::string > const &configKeys, std::vector< std::string > const &publisherKeys, std::optional< std::size_t > listThreshold={})
Load configured trusted keys.
-
bool removePublisherList(lock_guard const &, PublicKey const &publisherKey, PublisherStatus reason)
Stop trusting publisher's list of keys.
-
PublisherListStats applyLists(std::string const &manifest, std::uint32_t version, std::vector< ValidatorBlobInfo > const &blobs, std::string siteUri, std::optional< uint256 > const &hash={})
Apply multiple published lists of public keys.
-
std::optional< PublicKey > localPublicKey() const
This function returns the local validator public key or a std::nullopt.
+
bool removePublisherList(lock_guard const &, PublicKey const &publisherKey, PublisherStatus reason)
Stop trusting publisher's list of keys.
+
PublisherListStats applyLists(std::string const &manifest, std::uint32_t version, std::vector< ValidatorBlobInfo > const &blobs, std::string siteUri, std::optional< uint256 > const &hash={})
Apply multiple published lists of public keys.
+
std::optional< PublicKey > localPublicKey() const
This function returns the local validator public key or a std::nullopt.
std::size_t quorum() const
Get quorum value for current trusted key set.
-
PublisherListStats applyList(std::string const &globalManifest, std::optional< std::string > const &localManifest, std::string const &blob, std::string const &signature, std::uint32_t version, std::string siteUri, std::optional< uint256 > const &hash, lock_guard const &)
Apply published list of public keys.
-
std::optional< PublicKey > getListedKey(PublicKey const &identity) const
Returns listed master public if public key is included on any lists.
+
PublisherListStats applyList(std::string const &globalManifest, std::optional< std::string > const &localManifest, std::string const &blob, std::string const &signature, std::uint32_t version, std::string siteUri, std::optional< uint256 > const &hash, lock_guard const &)
Apply published list of public keys.
+
std::optional< PublicKey > getListedKey(PublicKey const &identity) const
Returns listed master public if public key is included on any lists.
void cacheValidatorFile(lock_guard const &lock, PublicKey const &pubKey) const
Write a JSON UNL to a cache file.
std::lock_guard< decltype(mutex_)> lock_guard
-
hash_set< PublicKey > getNegativeUNL() const
get the master public keys of Negative UNL validators
+
hash_set< PublicKey > getNegativeUNL() const
get the master public keys of Negative UNL validators
std::optional< std::size_t > minimumQuorum_
static std::vector< ValidatorBlobInfo > parseBlobs(std::uint32_t version, Json::Value const &body)
Pull the blob/signature/manifest information out of the appropriate Json body fields depending on the...
ManifestCache & publisherManifests_
hash_map< PublicKey, std::size_t > keyListings_
-
std::size_t getListThreshold() const
get the validator list threshold
-
std::optional< TimeKeeper::time_point > expires() const
Return the time when the validator list will expire.
-
static void buildBlobInfos(std::map< std::size_t, ValidatorBlobInfo > &blobInfos, PublisherListCollection const &lists)
+
std::size_t getListThreshold() const
get the validator list threshold
+
std::optional< TimeKeeper::time_point > expires() const
Return the time when the validator list will expire.
+
static void buildBlobInfos(std::map< std::size_t, ValidatorBlobInfo > &blobInfos, PublisherListCollection const &lists)
ManifestCache & validatorManifests_
hash_set< PublicKey > negativeUNL_
std::size_t listThreshold_
-
void setNegativeUNL(hash_set< PublicKey > const &negUnl)
set the Negative UNL with validators' master public keys
-
static void broadcastBlobs(PublicKey const &publisherKey, PublisherListCollection const &lists, std::size_t maxSequence, uint256 const &hash, Overlay &overlay, HashRouter &hashRouter, beast::Journal j)
-
std::size_t count() const
Return the number of configured validator list sites.
-
std::optional< PublicKey > getTrustedKey(PublicKey const &identity) const
Returns master public key if public key is trusted.
-
std::vector< std::shared_ptr< STValidation > > negativeUNLFilter(std::vector< std::shared_ptr< STValidation > > &&validations) const
Remove validations that are from validators on the negative UNL.
-
std::optional< Json::Value > getAvailable(std::string_view pubKey, std::optional< std::uint32_t > forceVersion={})
Returns the current valid list for the given publisher key, if available, as a Json object.
-
void updatePublisherList(PublicKey const &pubKey, PublisherList const &current, std::vector< PublicKey > const &oldList, lock_guard const &)
-
PublisherListStats applyListsAndBroadcast(std::string const &manifest, std::uint32_t version, std::vector< ValidatorBlobInfo > const &blobs, std::string siteUri, uint256 const &hash, Overlay &overlay, HashRouter &hashRouter, NetworkOPs &networkOPs)
Apply multiple published lists of public keys, then broadcast it to all peers that have not seen it o...
+
void setNegativeUNL(hash_set< PublicKey > const &negUnl)
set the Negative UNL with validators' master public keys
+
static void broadcastBlobs(PublicKey const &publisherKey, PublisherListCollection const &lists, std::size_t maxSequence, uint256 const &hash, Overlay &overlay, HashRouter &hashRouter, beast::Journal j)
+
std::size_t count() const
Return the number of configured validator list sites.
+
std::optional< PublicKey > getTrustedKey(PublicKey const &identity) const
Returns master public key if public key is trusted.
+
std::vector< std::shared_ptr< STValidation > > negativeUNLFilter(std::vector< std::shared_ptr< STValidation > > &&validations) const
Remove validations that are from validators on the negative UNL.
+
std::optional< Json::Value > getAvailable(std::string_view pubKey, std::optional< std::uint32_t > forceVersion={})
Returns the current valid list for the given publisher key, if available, as a Json object.
+
void updatePublisherList(PublicKey const &pubKey, PublisherList const &current, std::vector< PublicKey > const &oldList, lock_guard const &)
+
PublisherListStats applyListsAndBroadcast(std::string const &manifest, std::uint32_t version, std::vector< ValidatorBlobInfo > const &blobs, std::string siteUri, uint256 const &hash, Overlay &overlay, HashRouter &hashRouter, NetworkOPs &networkOPs)
Apply multiple published lists of public keys, then broadcast it to all peers that have not seen it o...
boost::filesystem::path getCacheFileName(lock_guard const &, PublicKey const &pubKey) const
Get the filename used for caching UNLs.
-
bool trusted(PublicKey const &identity) const
Returns true if public key is trusted.
+
bool trusted(PublicKey const &identity) const
Returns true if public key is trusted.
static std::string const filePrefix_
-
bool listed(PublicKey const &identity) const
Returns true if public key is included on any lists.
+
bool listed(PublicKey const &identity) const
Returns true if public key is included on any lists.
hash_map< PublicKey, PublisherListCollection > publisherLists_
friend void hash_append(Hasher &h, PublisherListCollection pl)
diff --git a/ValidatorList__test_8cpp_source.html b/ValidatorList__test_8cpp_source.html index 69c05cddaf..2711b79def 100644 --- a/ValidatorList__test_8cpp_source.html +++ b/ValidatorList__test_8cpp_source.html @@ -2491,1791 +2491,1792 @@ $(document).ready(function() { init_codefold(0); });
2370 &extractHeader](Message& message) {
2371 auto [header, buffers] = extractHeader(message);
2372 if (BEAST_EXPECT(header) &&
-
2373 BEAST_EXPECT(header->message_type == protocol::mtVALIDATORLIST))
-
2374 {
-
2375 auto const msg =
-
2376 detail::parseMessageContent<protocol::TMValidatorList>(
-
2377 *header, buffers.data());
-
2378 BEAST_EXPECT(msg);
-
2379 return msg;
-
2380 }
- -
2382 };
-
2383 auto extractProtocolMessage2 = [this,
-
2384 &extractHeader](Message& message) {
-
2385 auto [header, buffers] = extractHeader(message);
-
2386 if (BEAST_EXPECT(header) &&
-
2387 BEAST_EXPECT(
-
2388 header->message_type ==
-
2389 protocol::mtVALIDATORLISTCOLLECTION))
-
2390 {
-
2391 auto const msg = detail::parseMessageContent<
-
2392 protocol::TMValidatorListCollection>(
-
2393 *header, buffers.data());
-
2394 BEAST_EXPECT(msg);
-
2395 return msg;
-
2396 }
- -
2398 };
-
2399 auto verifyMessage =
-
2400 [this,
-
2401 manifestCutoff,
-
2402 &extractProtocolMessage1,
-
2403 &extractProtocolMessage2](
-
2404 auto const version,
-
2405 auto const& manifest,
-
2406 auto const& blobInfos,
-
2407 auto const& messages,
- -
2409 expectedInfo) {
-
2410 BEAST_EXPECT(messages.size() == expectedInfo.size());
-
2411 auto msgIter = expectedInfo.begin();
-
2412 for (auto const& messageWithHash : messages)
-
2413 {
-
2414 if (!BEAST_EXPECT(msgIter != expectedInfo.end()))
-
2415 break;
-
2416 if (!BEAST_EXPECT(messageWithHash.message))
-
2417 continue;
-
2418 auto const& expectedSeqs = msgIter->second;
-
2419 auto seqIter = expectedSeqs.begin();
-
2420 auto const size =
-
2421 messageWithHash.message
-
2422 ->getBuffer(compression::Compressed::Off)
-
2423 .size();
-
2424 // This size is arbitrary, but shouldn't change
-
2425 BEAST_EXPECT(size == msgIter->first);
-
2426 if (expectedSeqs.size() == 1)
-
2427 {
-
2428 auto const msg =
-
2429 extractProtocolMessage1(*messageWithHash.message);
-
2430 auto const expectedVersion = 1;
-
2431 if (BEAST_EXPECT(msg))
-
2432 {
-
2433 BEAST_EXPECT(msg->version() == expectedVersion);
-
2434 if (!BEAST_EXPECT(seqIter != expectedSeqs.end()))
-
2435 continue;
-
2436 auto const& expectedBlob = blobInfos.at(*seqIter);
-
2437 BEAST_EXPECT(
-
2438 (*seqIter < manifestCutoff) ==
-
2439 !!expectedBlob.manifest);
-
2440 auto const expectedManifest =
-
2441 *seqIter < manifestCutoff &&
-
2442 expectedBlob.manifest
-
2443 ? *expectedBlob.manifest
-
2444 : manifest;
-
2445 BEAST_EXPECT(msg->manifest() == expectedManifest);
-
2446 BEAST_EXPECT(msg->blob() == expectedBlob.blob);
-
2447 BEAST_EXPECT(
-
2448 msg->signature() == expectedBlob.signature);
-
2449 ++seqIter;
-
2450 BEAST_EXPECT(seqIter == expectedSeqs.end());
-
2451
-
2452 BEAST_EXPECT(
-
2453 messageWithHash.hash ==
-
2454 sha512Half(
-
2455 expectedManifest,
-
2456 expectedBlob.blob,
-
2457 expectedBlob.signature,
-
2458 expectedVersion));
-
2459 }
-
2460 }
-
2461 else
-
2462 {
-
2463 std::vector<ValidatorBlobInfo> hashingBlobs;
-
2464 hashingBlobs.reserve(msgIter->second.size());
-
2465
-
2466 auto const msg =
-
2467 extractProtocolMessage2(*messageWithHash.message);
-
2468 if (BEAST_EXPECT(msg))
-
2469 {
-
2470 BEAST_EXPECT(msg->version() == version);
-
2471 BEAST_EXPECT(msg->manifest() == manifest);
-
2472 for (auto const& blobInfo : msg->blobs())
-
2473 {
-
2474 if (!BEAST_EXPECT(
-
2475 seqIter != expectedSeqs.end()))
-
2476 break;
-
2477 auto const& expectedBlob =
-
2478 blobInfos.at(*seqIter);
-
2479 hashingBlobs.push_back(expectedBlob);
-
2480 BEAST_EXPECT(
-
2481 blobInfo.has_manifest() ==
-
2482 !!expectedBlob.manifest);
-
2483 BEAST_EXPECT(
-
2484 blobInfo.has_manifest() ==
-
2485 (*seqIter < manifestCutoff));
-
2486
-
2487 if (*seqIter < manifestCutoff)
-
2488 BEAST_EXPECT(
-
2489 blobInfo.manifest() ==
-
2490 *expectedBlob.manifest);
-
2491 BEAST_EXPECT(
-
2492 blobInfo.blob() == expectedBlob.blob);
-
2493 BEAST_EXPECT(
-
2494 blobInfo.signature() ==
-
2495 expectedBlob.signature);
-
2496 ++seqIter;
-
2497 }
-
2498 BEAST_EXPECT(seqIter == expectedSeqs.end());
-
2499 }
-
2500 BEAST_EXPECT(
-
2501 messageWithHash.hash ==
-
2502 sha512Half(manifest, hashingBlobs, version));
-
2503 }
-
2504 ++msgIter;
-
2505 }
-
2506 BEAST_EXPECT(msgIter == expectedInfo.end());
-
2507 };
-
2508 auto verifyBuildMessages =
-
2509 [this](
- -
2511 std::size_t expectedSequence,
-
2512 std::size_t expectedSize) {
-
2513 BEAST_EXPECT(result.first == expectedSequence);
-
2514 BEAST_EXPECT(result.second == expectedSize);
-
2515 };
-
2516
-
2517 std::string const manifest = "This is not a manifest";
-
2518 std::uint32_t const version = 2;
-
2519 // Mutable so items can be removed in later tests.
-
2520 auto const blobInfos = [manifestCutoff = manifestCutoff]() {
- -
2522
-
2523 for (auto seq : {5, 6, 7, 10, 12})
-
2524 {
-
2525 auto& b = bis[seq];
- -
2527 s << "This is not a blob with sequence " << seq;
-
2528 b.blob = s.str();
-
2529 s.str(std::string());
-
2530 s << "This is not a signature for sequence " << seq;
-
2531 b.signature = s.str();
-
2532 if (seq < manifestCutoff)
-
2533 {
-
2534 // add a manifest for the "early" blobs
-
2535 s.str(std::string());
-
2536 s << "This is not manifest " << seq;
-
2537 b.manifest = s.str();
-
2538 }
-
2539 }
-
2540 return bis;
-
2541 }();
-
2542 auto const maxSequence = blobInfos.rbegin()->first;
-
2543 BEAST_EXPECT(maxSequence == 12);
-
2544
- -
2546
-
2547 // Version 1
-
2548
-
2549 // This peer has a VL ahead of our "current"
-
2550 verifyBuildMessages(
-
2551 ValidatorList::buildValidatorListMessages(
-
2552 1, 8, maxSequence, version, manifest, blobInfos, messages),
-
2553 0,
-
2554 0);
-
2555 BEAST_EXPECT(messages.size() == 0);
-
2556
-
2557 // Don't repeat the work if messages is populated, even though the
-
2558 // peerSequence provided indicates it should. Note that this
-
2559 // situation is contrived for this test and should never happen in
-
2560 // real code.
-
2561 messages.emplace_back();
-
2562 verifyBuildMessages(
-
2563 ValidatorList::buildValidatorListMessages(
-
2564 1, 3, maxSequence, version, manifest, blobInfos, messages),
-
2565 5,
-
2566 0);
-
2567 BEAST_EXPECT(messages.size() == 1 && !messages.front().message);
-
2568
-
2569 // Generate a version 1 message
-
2570 messages.clear();
-
2571 verifyBuildMessages(
-
2572 ValidatorList::buildValidatorListMessages(
-
2573 1, 3, maxSequence, version, manifest, blobInfos, messages),
-
2574 5,
-
2575 1);
-
2576 if (BEAST_EXPECT(messages.size() == 1) &&
-
2577 BEAST_EXPECT(messages.front().message))
-
2578 {
-
2579 auto const& messageWithHash = messages.front();
-
2580 auto const msg = extractProtocolMessage1(*messageWithHash.message);
-
2581 auto const size =
-
2582 messageWithHash.message->getBuffer(compression::Compressed::Off)
-
2583 .size();
-
2584 // This size is arbitrary, but shouldn't change
-
2585 BEAST_EXPECT(size == 108);
-
2586 auto const& expected = blobInfos.at(5);
-
2587 if (BEAST_EXPECT(msg))
-
2588 {
-
2589 BEAST_EXPECT(msg->version() == 1);
-
2590 BEAST_EXPECT(msg->manifest() == *expected.manifest);
-
2591 BEAST_EXPECT(msg->blob() == expected.blob);
-
2592 BEAST_EXPECT(msg->signature() == expected.signature);
-
2593 }
-
2594 BEAST_EXPECT(
-
2595 messageWithHash.hash ==
-
2596 sha512Half(
-
2597 *expected.manifest, expected.blob, expected.signature, 1));
-
2598 }
-
2599
-
2600 // Version 2
-
2601
-
2602 messages.clear();
-
2603
-
2604 // This peer has a VL ahead of us.
-
2605 verifyBuildMessages(
-
2606 ValidatorList::buildValidatorListMessages(
-
2607 2,
-
2608 maxSequence * 2,
-
2609 maxSequence,
-
2610 version,
-
2611 manifest,
-
2612 blobInfos,
-
2613 messages),
-
2614 0,
-
2615 0);
-
2616 BEAST_EXPECT(messages.size() == 0);
-
2617
-
2618 // Don't repeat the work if messages is populated, even though the
-
2619 // peerSequence provided indicates it should. Note that this
-
2620 // situation is contrived for this test and should never happen in
-
2621 // real code.
-
2622 messages.emplace_back();
-
2623 verifyBuildMessages(
-
2624 ValidatorList::buildValidatorListMessages(
-
2625 2, 3, maxSequence, version, manifest, blobInfos, messages),
-
2626 maxSequence,
-
2627 0);
-
2628 BEAST_EXPECT(messages.size() == 1 && !messages.front().message);
-
2629
-
2630 // Generate a version 2 message. Don't send the current
-
2631 messages.clear();
-
2632 verifyBuildMessages(
-
2633 ValidatorList::buildValidatorListMessages(
-
2634 2, 5, maxSequence, version, manifest, blobInfos, messages),
-
2635 maxSequence,
-
2636 4);
-
2637 verifyMessage(
-
2638 version, manifest, blobInfos, messages, {{372, {6, 7, 10, 12}}});
-
2639
-
2640 // Test message splitting on size limits.
-
2641
-
2642 // Set a limit that should give two messages
-
2643 messages.clear();
-
2644 verifyBuildMessages(
-
2645 ValidatorList::buildValidatorListMessages(
-
2646 2, 5, maxSequence, version, manifest, blobInfos, messages, 300),
-
2647 maxSequence,
-
2648 4);
-
2649 verifyMessage(
-
2650 version,
-
2651 manifest,
-
2652 blobInfos,
-
2653 messages,
-
2654 {{212, {6, 7}}, {192, {10, 12}}});
-
2655
-
2656 // Set a limit between the size of the two earlier messages so one
-
2657 // will split and the other won't
-
2658 messages.clear();
-
2659 verifyBuildMessages(
-
2660 ValidatorList::buildValidatorListMessages(
-
2661 2, 5, maxSequence, version, manifest, blobInfos, messages, 200),
-
2662 maxSequence,
-
2663 4);
-
2664 verifyMessage(
-
2665 version,
-
2666 manifest,
-
2667 blobInfos,
-
2668 messages,
-
2669 {{108, {6}}, {108, {7}}, {192, {10, 12}}});
-
2670
-
2671 // Set a limit so that all the VLs are sent individually
-
2672 messages.clear();
-
2673 verifyBuildMessages(
-
2674 ValidatorList::buildValidatorListMessages(
-
2675 2, 5, maxSequence, version, manifest, blobInfos, messages, 150),
-
2676 maxSequence,
-
2677 4);
-
2678 verifyMessage(
-
2679 version,
-
2680 manifest,
-
2681 blobInfos,
-
2682 messages,
-
2683 {{108, {6}}, {108, {7}}, {110, {10}}, {110, {12}}});
-
2684
-
2685 // Set a limit smaller than some of the messages. Because single
-
2686 // messages send regardless, they will all still be sent
-
2687 messages.clear();
-
2688 verifyBuildMessages(
-
2689 ValidatorList::buildValidatorListMessages(
-
2690 2, 5, maxSequence, version, manifest, blobInfos, messages, 108),
-
2691 maxSequence,
-
2692 4);
-
2693 verifyMessage(
-
2694 version,
-
2695 manifest,
-
2696 blobInfos,
-
2697 messages,
-
2698 {{108, {6}}, {108, {7}}, {110, {10}}, {110, {12}}});
-
2699 }
+
2373 BEAST_EXPECT(
+
2374 header->message_type == protocol::mtVALIDATOR_LIST))
+
2375 {
+
2376 auto const msg =
+
2377 detail::parseMessageContent<protocol::TMValidatorList>(
+
2378 *header, buffers.data());
+
2379 BEAST_EXPECT(msg);
+
2380 return msg;
+
2381 }
+ +
2383 };
+
2384 auto extractProtocolMessage2 = [this,
+
2385 &extractHeader](Message& message) {
+
2386 auto [header, buffers] = extractHeader(message);
+
2387 if (BEAST_EXPECT(header) &&
+
2388 BEAST_EXPECT(
+
2389 header->message_type ==
+
2390 protocol::mtVALIDATOR_LIST_COLLECTION))
+
2391 {
+
2392 auto const msg = detail::parseMessageContent<
+
2393 protocol::TMValidatorListCollection>(
+
2394 *header, buffers.data());
+
2395 BEAST_EXPECT(msg);
+
2396 return msg;
+
2397 }
+ +
2399 };
+
2400 auto verifyMessage =
+
2401 [this,
+
2402 manifestCutoff,
+
2403 &extractProtocolMessage1,
+
2404 &extractProtocolMessage2](
+
2405 auto const version,
+
2406 auto const& manifest,
+
2407 auto const& blobInfos,
+
2408 auto const& messages,
+ +
2410 expectedInfo) {
+
2411 BEAST_EXPECT(messages.size() == expectedInfo.size());
+
2412 auto msgIter = expectedInfo.begin();
+
2413 for (auto const& messageWithHash : messages)
+
2414 {
+
2415 if (!BEAST_EXPECT(msgIter != expectedInfo.end()))
+
2416 break;
+
2417 if (!BEAST_EXPECT(messageWithHash.message))
+
2418 continue;
+
2419 auto const& expectedSeqs = msgIter->second;
+
2420 auto seqIter = expectedSeqs.begin();
+
2421 auto const size =
+
2422 messageWithHash.message
+
2423 ->getBuffer(compression::Compressed::Off)
+
2424 .size();
+
2425 // This size is arbitrary, but shouldn't change
+
2426 BEAST_EXPECT(size == msgIter->first);
+
2427 if (expectedSeqs.size() == 1)
+
2428 {
+
2429 auto const msg =
+
2430 extractProtocolMessage1(*messageWithHash.message);
+
2431 auto const expectedVersion = 1;
+
2432 if (BEAST_EXPECT(msg))
+
2433 {
+
2434 BEAST_EXPECT(msg->version() == expectedVersion);
+
2435 if (!BEAST_EXPECT(seqIter != expectedSeqs.end()))
+
2436 continue;
+
2437 auto const& expectedBlob = blobInfos.at(*seqIter);
+
2438 BEAST_EXPECT(
+
2439 (*seqIter < manifestCutoff) ==
+
2440 !!expectedBlob.manifest);
+
2441 auto const expectedManifest =
+
2442 *seqIter < manifestCutoff &&
+
2443 expectedBlob.manifest
+
2444 ? *expectedBlob.manifest
+
2445 : manifest;
+
2446 BEAST_EXPECT(msg->manifest() == expectedManifest);
+
2447 BEAST_EXPECT(msg->blob() == expectedBlob.blob);
+
2448 BEAST_EXPECT(
+
2449 msg->signature() == expectedBlob.signature);
+
2450 ++seqIter;
+
2451 BEAST_EXPECT(seqIter == expectedSeqs.end());
+
2452
+
2453 BEAST_EXPECT(
+
2454 messageWithHash.hash ==
+
2455 sha512Half(
+
2456 expectedManifest,
+
2457 expectedBlob.blob,
+
2458 expectedBlob.signature,
+
2459 expectedVersion));
+
2460 }
+
2461 }
+
2462 else
+
2463 {
+
2464 std::vector<ValidatorBlobInfo> hashingBlobs;
+
2465 hashingBlobs.reserve(msgIter->second.size());
+
2466
+
2467 auto const msg =
+
2468 extractProtocolMessage2(*messageWithHash.message);
+
2469 if (BEAST_EXPECT(msg))
+
2470 {
+
2471 BEAST_EXPECT(msg->version() == version);
+
2472 BEAST_EXPECT(msg->manifest() == manifest);
+
2473 for (auto const& blobInfo : msg->blobs())
+
2474 {
+
2475 if (!BEAST_EXPECT(
+
2476 seqIter != expectedSeqs.end()))
+
2477 break;
+
2478 auto const& expectedBlob =
+
2479 blobInfos.at(*seqIter);
+
2480 hashingBlobs.push_back(expectedBlob);
+
2481 BEAST_EXPECT(
+
2482 blobInfo.has_manifest() ==
+
2483 !!expectedBlob.manifest);
+
2484 BEAST_EXPECT(
+
2485 blobInfo.has_manifest() ==
+
2486 (*seqIter < manifestCutoff));
+
2487
+
2488 if (*seqIter < manifestCutoff)
+
2489 BEAST_EXPECT(
+
2490 blobInfo.manifest() ==
+
2491 *expectedBlob.manifest);
+
2492 BEAST_EXPECT(
+
2493 blobInfo.blob() == expectedBlob.blob);
+
2494 BEAST_EXPECT(
+
2495 blobInfo.signature() ==
+
2496 expectedBlob.signature);
+
2497 ++seqIter;
+
2498 }
+
2499 BEAST_EXPECT(seqIter == expectedSeqs.end());
+
2500 }
+
2501 BEAST_EXPECT(
+
2502 messageWithHash.hash ==
+
2503 sha512Half(manifest, hashingBlobs, version));
+
2504 }
+
2505 ++msgIter;
+
2506 }
+
2507 BEAST_EXPECT(msgIter == expectedInfo.end());
+
2508 };
+
2509 auto verifyBuildMessages =
+
2510 [this](
+ +
2512 std::size_t expectedSequence,
+
2513 std::size_t expectedSize) {
+
2514 BEAST_EXPECT(result.first == expectedSequence);
+
2515 BEAST_EXPECT(result.second == expectedSize);
+
2516 };
+
2517
+
2518 std::string const manifest = "This is not a manifest";
+
2519 std::uint32_t const version = 2;
+
2520 // Mutable so items can be removed in later tests.
+
2521 auto const blobInfos = [manifestCutoff = manifestCutoff]() {
+ +
2523
+
2524 for (auto seq : {5, 6, 7, 10, 12})
+
2525 {
+
2526 auto& b = bis[seq];
+ +
2528 s << "This is not a blob with sequence " << seq;
+
2529 b.blob = s.str();
+
2530 s.str(std::string());
+
2531 s << "This is not a signature for sequence " << seq;
+
2532 b.signature = s.str();
+
2533 if (seq < manifestCutoff)
+
2534 {
+
2535 // add a manifest for the "early" blobs
+
2536 s.str(std::string());
+
2537 s << "This is not manifest " << seq;
+
2538 b.manifest = s.str();
+
2539 }
+
2540 }
+
2541 return bis;
+
2542 }();
+
2543 auto const maxSequence = blobInfos.rbegin()->first;
+
2544 BEAST_EXPECT(maxSequence == 12);
+
2545
+ +
2547
+
2548 // Version 1
+
2549
+
2550 // This peer has a VL ahead of our "current"
+
2551 verifyBuildMessages(
+
2552 ValidatorList::buildValidatorListMessages(
+
2553 1, 8, maxSequence, version, manifest, blobInfos, messages),
+
2554 0,
+
2555 0);
+
2556 BEAST_EXPECT(messages.size() == 0);
+
2557
+
2558 // Don't repeat the work if messages is populated, even though the
+
2559 // peerSequence provided indicates it should. Note that this
+
2560 // situation is contrived for this test and should never happen in
+
2561 // real code.
+
2562 messages.emplace_back();
+
2563 verifyBuildMessages(
+
2564 ValidatorList::buildValidatorListMessages(
+
2565 1, 3, maxSequence, version, manifest, blobInfos, messages),
+
2566 5,
+
2567 0);
+
2568 BEAST_EXPECT(messages.size() == 1 && !messages.front().message);
+
2569
+
2570 // Generate a version 1 message
+
2571 messages.clear();
+
2572 verifyBuildMessages(
+
2573 ValidatorList::buildValidatorListMessages(
+
2574 1, 3, maxSequence, version, manifest, blobInfos, messages),
+
2575 5,
+
2576 1);
+
2577 if (BEAST_EXPECT(messages.size() == 1) &&
+
2578 BEAST_EXPECT(messages.front().message))
+
2579 {
+
2580 auto const& messageWithHash = messages.front();
+
2581 auto const msg = extractProtocolMessage1(*messageWithHash.message);
+
2582 auto const size =
+
2583 messageWithHash.message->getBuffer(compression::Compressed::Off)
+
2584 .size();
+
2585 // This size is arbitrary, but shouldn't change
+
2586 BEAST_EXPECT(size == 108);
+
2587 auto const& expected = blobInfos.at(5);
+
2588 if (BEAST_EXPECT(msg))
+
2589 {
+
2590 BEAST_EXPECT(msg->version() == 1);
+
2591 BEAST_EXPECT(msg->manifest() == *expected.manifest);
+
2592 BEAST_EXPECT(msg->blob() == expected.blob);
+
2593 BEAST_EXPECT(msg->signature() == expected.signature);
+
2594 }
+
2595 BEAST_EXPECT(
+
2596 messageWithHash.hash ==
+
2597 sha512Half(
+
2598 *expected.manifest, expected.blob, expected.signature, 1));
+
2599 }
+
2600
+
2601 // Version 2
+
2602
+
2603 messages.clear();
+
2604
+
2605 // This peer has a VL ahead of us.
+
2606 verifyBuildMessages(
+
2607 ValidatorList::buildValidatorListMessages(
+
2608 2,
+
2609 maxSequence * 2,
+
2610 maxSequence,
+
2611 version,
+
2612 manifest,
+
2613 blobInfos,
+
2614 messages),
+
2615 0,
+
2616 0);
+
2617 BEAST_EXPECT(messages.size() == 0);
+
2618
+
2619 // Don't repeat the work if messages is populated, even though the
+
2620 // peerSequence provided indicates it should. Note that this
+
2621 // situation is contrived for this test and should never happen in
+
2622 // real code.
+
2623 messages.emplace_back();
+
2624 verifyBuildMessages(
+
2625 ValidatorList::buildValidatorListMessages(
+
2626 2, 3, maxSequence, version, manifest, blobInfos, messages),
+
2627 maxSequence,
+
2628 0);
+
2629 BEAST_EXPECT(messages.size() == 1 && !messages.front().message);
+
2630
+
2631 // Generate a version 2 message. Don't send the current
+
2632 messages.clear();
+
2633 verifyBuildMessages(
+
2634 ValidatorList::buildValidatorListMessages(
+
2635 2, 5, maxSequence, version, manifest, blobInfos, messages),
+
2636 maxSequence,
+
2637 4);
+
2638 verifyMessage(
+
2639 version, manifest, blobInfos, messages, {{372, {6, 7, 10, 12}}});
+
2640
+
2641 // Test message splitting on size limits.
+
2642
+
2643 // Set a limit that should give two messages
+
2644 messages.clear();
+
2645 verifyBuildMessages(
+
2646 ValidatorList::buildValidatorListMessages(
+
2647 2, 5, maxSequence, version, manifest, blobInfos, messages, 300),
+
2648 maxSequence,
+
2649 4);
+
2650 verifyMessage(
+
2651 version,
+
2652 manifest,
+
2653 blobInfos,
+
2654 messages,
+
2655 {{212, {6, 7}}, {192, {10, 12}}});
+
2656
+
2657 // Set a limit between the size of the two earlier messages so one
+
2658 // will split and the other won't
+
2659 messages.clear();
+
2660 verifyBuildMessages(
+
2661 ValidatorList::buildValidatorListMessages(
+
2662 2, 5, maxSequence, version, manifest, blobInfos, messages, 200),
+
2663 maxSequence,
+
2664 4);
+
2665 verifyMessage(
+
2666 version,
+
2667 manifest,
+
2668 blobInfos,
+
2669 messages,
+
2670 {{108, {6}}, {108, {7}}, {192, {10, 12}}});
+
2671
+
2672 // Set a limit so that all the VLs are sent individually
+
2673 messages.clear();
+
2674 verifyBuildMessages(
+
2675 ValidatorList::buildValidatorListMessages(
+
2676 2, 5, maxSequence, version, manifest, blobInfos, messages, 150),
+
2677 maxSequence,
+
2678 4);
+
2679 verifyMessage(
+
2680 version,
+
2681 manifest,
+
2682 blobInfos,
+
2683 messages,
+
2684 {{108, {6}}, {108, {7}}, {110, {10}}, {110, {12}}});
+
2685
+
2686 // Set a limit smaller than some of the messages. Because single
+
2687 // messages send regardless, they will all still be sent
+
2688 messages.clear();
+
2689 verifyBuildMessages(
+
2690 ValidatorList::buildValidatorListMessages(
+
2691 2, 5, maxSequence, version, manifest, blobInfos, messages, 108),
+
2692 maxSequence,
+
2693 4);
+
2694 verifyMessage(
+
2695 version,
+
2696 manifest,
+
2697 blobInfos,
+
2698 messages,
+
2699 {{108, {6}}, {108, {7}}, {110, {10}}, {110, {12}}});
+
2700 }
-
2700
-
2701 void
-
- -
2703 {
-
2704 testcase("Test quorum disabled");
-
2705
-
2706 std::string const siteUri = "testQuorumDisabled.test";
-
2707 jtx::Env env(*this);
-
2708 auto& app = env.app();
-
2709
-
2710 constexpr std::size_t maxKeys = 20;
-
2711 hash_set<NodeID> activeValidators;
-
2712 std::vector<Validator> valKeys;
-
2713 while (valKeys.size() != maxKeys)
-
2714 {
-
2715 valKeys.push_back(randomValidator());
-
2716 activeValidators.emplace(calcNodeID(valKeys.back().masterPublic));
-
2717 }
-
2718
-
2719 struct Publisher
-
2720 {
-
2721 bool revoked;
-
2722 PublicKey pubKey;
- - -
2725 NetClock::time_point expiry = {};
-
2726 };
-
2727
-
2728 // Create ValidatorList with a set of countTotal publishers, of which
-
2729 // first countRevoked are revoked and the last one expires early
-
2730 auto makeValidatorList = [&, this](
-
2731 std::size_t countTotal,
-
2732 std::size_t countRevoked,
-
2733 std::size_t listThreshold,
-
2734 ManifestCache& pubManifests,
-
2735 ManifestCache& valManifests,
- -
2737 std::vector<Publisher>& publishers // out
- -
2739 auto result = std::make_unique<ValidatorList>(
-
2740 valManifests,
-
2741 pubManifests,
-
2742 env.timeKeeper(),
-
2743 app.config().legacy("database_path"),
-
2744 env.journal);
-
2745
-
2746 std::vector<std::string> cfgPublishers;
-
2747 for (std::size_t i = 0; i < countTotal; ++i)
-
2748 {
-
2749 auto const publisherSecret = randomSecretKey();
-
2750 auto const publisherPublic =
-
2751 derivePublicKey(KeyType::ed25519, publisherSecret);
-
2752 auto const pubSigningKeys = randomKeyPair(KeyType::secp256k1);
-
2753 cfgPublishers.push_back(strHex(publisherPublic));
-
2754
-
2755 constexpr auto revoked =
- -
2757 auto const manifest = base64_encode(makeManifestString(
-
2758 publisherPublic,
-
2759 publisherSecret,
-
2760 pubSigningKeys.first,
-
2761 pubSigningKeys.second,
-
2762 i < countRevoked ? revoked : 1));
-
2763 publishers.push_back(Publisher{
-
2764 i < countRevoked,
-
2765 publisherPublic,
-
2766 pubSigningKeys,
-
2767 manifest});
-
2768 }
-
2769
-
2770 std::vector<std::string> const emptyCfgKeys;
-
2771 auto threshold =
-
2772 listThreshold > 0 ? std::optional(listThreshold) : std::nullopt;
-
2773 if (self)
-
2774 {
-
2775 valManifests.applyManifest(
-
2776 *deserializeManifest(base64_decode(self->manifest)));
-
2777 BEAST_EXPECT(result->load(
-
2778 self->signingPublic,
-
2779 emptyCfgKeys,
-
2780 cfgPublishers,
-
2781 threshold));
-
2782 }
-
2783 else
-
2784 {
-
2785 BEAST_EXPECT(
-
2786 result->load({}, emptyCfgKeys, cfgPublishers, threshold));
-
2787 }
-
2788
-
2789 for (std::size_t i = 0; i < countTotal; ++i)
-
2790 {
-
2791 using namespace std::chrono_literals;
-
2792 publishers[i].expiry = env.timeKeeper().now() +
-
2793 (i == countTotal - 1 ? 60s : 3600s);
-
2794 auto const blob = makeList(
-
2795 valKeys,
-
2796 1,
-
2797 publishers[i].expiry.time_since_epoch().count());
-
2798 auto const sig = signList(blob, publishers[i].signingKeys);
-
2799
-
2800 BEAST_EXPECT(
-
2801 result
-
2802 ->applyLists(
-
2803 publishers[i].manifest,
-
2804 1,
-
2805 {{blob, sig, {}}},
-
2806 siteUri)
-
2807 .bestDisposition() ==
-
2808 (publishers[i].revoked ? ListDisposition::untrusted
-
2809 : ListDisposition::accepted));
-
2810 }
-
2811
-
2812 return result;
-
2813 };
-
2814
-
2815 // Test cases use 5 publishers.
-
2816 constexpr auto quorumDisabled = std::numeric_limits<std::size_t>::max();
-
2817 {
-
2818 // List threshold = 5 (same as number of trusted publishers)
-
2819 ManifestCache pubManifests;
-
2820 ManifestCache valManifests;
-
2821 std::vector<Publisher> publishers;
-
2822 // Self is a random validator
-
2823 auto const self = randomValidator();
-
2824 auto const keysTotal = valKeys.size() + 1;
-
2825 auto trustedKeys = makeValidatorList(
-
2826 5, //
-
2827 0,
-
2828 5,
-
2829 pubManifests,
-
2830 valManifests,
-
2831 self,
-
2832 publishers);
-
2833 BEAST_EXPECT(trustedKeys->getListThreshold() == 5);
-
2834 for (auto const& p : publishers)
-
2835 BEAST_EXPECT(trustedKeys->trustedPublisher(p.pubKey));
-
2836
-
2837 TrustChanges changes = trustedKeys->updateTrusted(
-
2838 activeValidators,
-
2839 env.timeKeeper().now(),
-
2840 env.app().getOPs(),
-
2841 env.app().overlay(),
-
2842 env.app().getHashRouter());
-
2843 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
-
2844 BEAST_EXPECT(
-
2845 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
-
2846
-
2847 hash_set<NodeID> added;
-
2848 added.insert(calcNodeID(self.masterPublic));
-
2849 for (auto const& val : valKeys)
-
2850 {
-
2851 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
-
2852 added.insert(calcNodeID(val.masterPublic));
-
2853 }
-
2854 BEAST_EXPECT(changes.added == added);
-
2855 BEAST_EXPECT(changes.removed.empty());
-
2856
-
2857 // Expire one publisher - only trusted validator is self
-
2858 env.timeKeeper().set(publishers.back().expiry);
-
2859 changes = trustedKeys->updateTrusted(
-
2860 activeValidators,
-
2861 env.timeKeeper().now(),
-
2862 env.app().getOPs(),
-
2863 env.app().overlay(),
-
2864 env.app().getHashRouter());
-
2865 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
-
2866 BEAST_EXPECT(trustedKeys->getTrustedMasterKeys().size() == 1);
-
2867
-
2868 hash_set<NodeID> removed;
-
2869 BEAST_EXPECT(trustedKeys->trusted(self.masterPublic));
-
2870 for (auto const& val : valKeys)
-
2871 {
-
2872 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
-
2873 BEAST_EXPECT(!trustedKeys->trusted(val.masterPublic));
-
2874 removed.insert(calcNodeID(val.masterPublic));
-
2875 }
-
2876 BEAST_EXPECT(changes.added.empty());
-
2877 BEAST_EXPECT(changes.removed == removed);
-
2878 }
-
2879 {
-
2880 // List threshold = 5 (same as number of trusted publishers)
-
2881 ManifestCache pubManifests;
-
2882 ManifestCache valManifests;
-
2883 std::vector<Publisher> publishers;
-
2884 auto const keysTotal = valKeys.size();
-
2885 auto trustedKeys = makeValidatorList(
-
2886 5, //
-
2887 0,
-
2888 5,
-
2889 pubManifests,
-
2890 valManifests,
-
2891 {},
-
2892 publishers);
-
2893 BEAST_EXPECT(trustedKeys->getListThreshold() == 5);
-
2894 for (auto const& p : publishers)
-
2895 BEAST_EXPECT(trustedKeys->trustedPublisher(p.pubKey));
-
2896
-
2897 TrustChanges changes = trustedKeys->updateTrusted(
-
2898 activeValidators,
-
2899 env.timeKeeper().now(),
-
2900 env.app().getOPs(),
-
2901 env.app().overlay(),
-
2902 env.app().getHashRouter());
-
2903 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
-
2904 BEAST_EXPECT(
-
2905 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
-
2906
-
2907 hash_set<NodeID> added;
-
2908 for (auto const& val : valKeys)
-
2909 {
-
2910 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
-
2911 added.insert(calcNodeID(val.masterPublic));
-
2912 }
-
2913 BEAST_EXPECT(changes.added == added);
-
2914 BEAST_EXPECT(changes.removed.empty());
-
2915
-
2916 // Expire one publisher - no trusted validators
-
2917 env.timeKeeper().set(publishers.back().expiry);
-
2918 changes = trustedKeys->updateTrusted(
-
2919 activeValidators,
-
2920 env.timeKeeper().now(),
-
2921 env.app().getOPs(),
-
2922 env.app().overlay(),
-
2923 env.app().getHashRouter());
-
2924 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
-
2925 BEAST_EXPECT(trustedKeys->getTrustedMasterKeys().size() == 0);
-
2926
-
2927 hash_set<NodeID> removed;
-
2928 for (auto const& val : valKeys)
-
2929 {
-
2930 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
-
2931 BEAST_EXPECT(!trustedKeys->trusted(val.masterPublic));
-
2932 removed.insert(calcNodeID(val.masterPublic));
-
2933 }
-
2934 BEAST_EXPECT(changes.added.empty());
-
2935 BEAST_EXPECT(changes.removed == removed);
-
2936 }
-
2937 {
-
2938 // List threshold = 4, 1 publisher is revoked
-
2939 ManifestCache pubManifests;
-
2940 ManifestCache valManifests;
-
2941 std::vector<Publisher> publishers;
-
2942 // Self is in UNL
-
2943 auto const self = valKeys[1];
-
2944 auto const keysTotal = valKeys.size();
-
2945 auto trustedKeys = makeValidatorList(
-
2946 5, //
-
2947 1,
-
2948 4,
-
2949 pubManifests,
-
2950 valManifests,
-
2951 self,
-
2952 publishers);
-
2953 BEAST_EXPECT(trustedKeys->getListThreshold() == 4);
-
2954 int untrustedCount = 0;
-
2955 for (auto const& p : publishers)
-
2956 {
-
2957 bool const trusted = trustedKeys->trustedPublisher(p.pubKey);
-
2958 BEAST_EXPECT(p.revoked ^ trusted);
-
2959 untrustedCount += trusted ? 0 : 1;
-
2960 }
-
2961 BEAST_EXPECT(untrustedCount == 1);
-
2962
-
2963 TrustChanges changes = trustedKeys->updateTrusted(
-
2964 activeValidators,
-
2965 env.timeKeeper().now(),
-
2966 env.app().getOPs(),
-
2967 env.app().overlay(),
-
2968 env.app().getHashRouter());
-
2969 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
-
2970 BEAST_EXPECT(
-
2971 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
-
2972
-
2973 hash_set<NodeID> added;
-
2974 for (auto const& val : valKeys)
-
2975 {
-
2976 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
-
2977 added.insert(calcNodeID(val.masterPublic));
-
2978 }
-
2979 BEAST_EXPECT(changes.added == added);
-
2980 BEAST_EXPECT(changes.removed.empty());
-
2981
-
2982 // Expire one publisher - only trusted validator is self
-
2983 env.timeKeeper().set(publishers.back().expiry);
-
2984 changes = trustedKeys->updateTrusted(
-
2985 activeValidators,
-
2986 env.timeKeeper().now(),
-
2987 env.app().getOPs(),
-
2988 env.app().overlay(),
-
2989 env.app().getHashRouter());
-
2990 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
-
2991 BEAST_EXPECT(trustedKeys->getTrustedMasterKeys().size() == 1);
-
2992
-
2993 hash_set<NodeID> removed;
-
2994 BEAST_EXPECT(trustedKeys->trusted(self.masterPublic));
-
2995 for (auto const& val : valKeys)
-
2996 {
-
2997 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
-
2998 if (val.masterPublic != self.masterPublic)
-
2999 {
-
3000 BEAST_EXPECT(!trustedKeys->trusted(val.masterPublic));
-
3001 removed.insert(calcNodeID(val.masterPublic));
-
3002 }
-
3003 }
-
3004 BEAST_EXPECT(changes.added.empty());
-
3005 BEAST_EXPECT(changes.removed == removed);
-
3006 }
-
3007 {
-
3008 // List threshold = 3 (default), 2 publishers are revoked
-
3009 ManifestCache pubManifests;
-
3010 ManifestCache valManifests;
-
3011 std::vector<Publisher> publishers;
-
3012 // Self is a random validator
-
3013 auto const self = randomValidator();
-
3014 auto const keysTotal = valKeys.size() + 1;
-
3015 auto trustedKeys = makeValidatorList(
-
3016 5, //
-
3017 2,
-
3018 0,
-
3019 pubManifests,
-
3020 valManifests,
-
3021 self,
-
3022 publishers);
-
3023 BEAST_EXPECT(trustedKeys->getListThreshold() == 3);
-
3024 int untrustedCount = 0;
-
3025 for (auto const& p : publishers)
-
3026 {
-
3027 bool const trusted = trustedKeys->trustedPublisher(p.pubKey);
-
3028 BEAST_EXPECT(p.revoked ^ trusted);
-
3029 untrustedCount += trusted ? 0 : 1;
-
3030 }
-
3031 BEAST_EXPECT(untrustedCount == 2);
-
3032
-
3033 TrustChanges changes = trustedKeys->updateTrusted(
-
3034 activeValidators,
-
3035 env.timeKeeper().now(),
-
3036 env.app().getOPs(),
-
3037 env.app().overlay(),
-
3038 env.app().getHashRouter());
-
3039 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
-
3040 BEAST_EXPECT(
-
3041 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
-
3042
-
3043 hash_set<NodeID> added;
-
3044 added.insert(calcNodeID(self.masterPublic));
-
3045 for (auto const& val : valKeys)
-
3046 {
-
3047 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
-
3048 added.insert(calcNodeID(val.masterPublic));
-
3049 }
-
3050 BEAST_EXPECT(changes.added == added);
-
3051 BEAST_EXPECT(changes.removed.empty());
-
3052
-
3053 // Expire one publisher - no quorum, only trusted validator is self
-
3054 env.timeKeeper().set(publishers.back().expiry);
-
3055 changes = trustedKeys->updateTrusted(
-
3056 activeValidators,
-
3057 env.timeKeeper().now(),
-
3058 env.app().getOPs(),
-
3059 env.app().overlay(),
-
3060 env.app().getHashRouter());
-
3061 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
-
3062 BEAST_EXPECT(trustedKeys->getTrustedMasterKeys().size() == 1);
-
3063
-
3064 hash_set<NodeID> removed;
-
3065 BEAST_EXPECT(trustedKeys->trusted(self.masterPublic));
-
3066 for (auto const& val : valKeys)
-
3067 {
-
3068 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
-
3069 BEAST_EXPECT(!trustedKeys->trusted(val.masterPublic));
-
3070 removed.insert(calcNodeID(val.masterPublic));
-
3071 }
-
3072 BEAST_EXPECT(changes.added.empty());
-
3073 BEAST_EXPECT(changes.removed == removed);
-
3074 }
-
3075 {
-
3076 // List threshold = 3 (default), 2 publishers are revoked
-
3077 ManifestCache pubManifests;
-
3078 ManifestCache valManifests;
-
3079 std::vector<Publisher> publishers;
-
3080 // Self is in UNL
-
3081 auto const self = valKeys[5];
-
3082 auto const keysTotal = valKeys.size();
-
3083 auto trustedKeys = makeValidatorList(
-
3084 5, //
-
3085 2,
-
3086 0,
-
3087 pubManifests,
-
3088 valManifests,
-
3089 self,
-
3090 publishers);
-
3091 BEAST_EXPECT(trustedKeys->getListThreshold() == 3);
-
3092 int untrustedCount = 0;
-
3093 for (auto const& p : publishers)
-
3094 {
-
3095 bool const trusted = trustedKeys->trustedPublisher(p.pubKey);
-
3096 BEAST_EXPECT(p.revoked ^ trusted);
-
3097 untrustedCount += trusted ? 0 : 1;
-
3098 }
-
3099 BEAST_EXPECT(untrustedCount == 2);
-
3100
-
3101 TrustChanges changes = trustedKeys->updateTrusted(
-
3102 activeValidators,
-
3103 env.timeKeeper().now(),
-
3104 env.app().getOPs(),
-
3105 env.app().overlay(),
-
3106 env.app().getHashRouter());
-
3107 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
-
3108 BEAST_EXPECT(
-
3109 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
-
3110
-
3111 hash_set<NodeID> added;
-
3112 for (auto const& val : valKeys)
-
3113 {
-
3114 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
-
3115 added.insert(calcNodeID(val.masterPublic));
-
3116 }
-
3117 BEAST_EXPECT(changes.added == added);
-
3118 BEAST_EXPECT(changes.removed.empty());
-
3119
-
3120 // Expire one publisher - no quorum, only trusted validator is self
-
3121 env.timeKeeper().set(publishers.back().expiry);
-
3122 changes = trustedKeys->updateTrusted(
-
3123 activeValidators,
-
3124 env.timeKeeper().now(),
-
3125 env.app().getOPs(),
-
3126 env.app().overlay(),
-
3127 env.app().getHashRouter());
-
3128 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
-
3129 BEAST_EXPECT(trustedKeys->getTrustedMasterKeys().size() == 1);
-
3130
-
3131 hash_set<NodeID> removed;
-
3132 BEAST_EXPECT(trustedKeys->trusted(self.masterPublic));
-
3133 for (auto const& val : valKeys)
-
3134 {
-
3135 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
-
3136 if (val.masterPublic != self.masterPublic)
-
3137 {
-
3138 BEAST_EXPECT(!trustedKeys->trusted(val.masterPublic));
-
3139 removed.insert(calcNodeID(val.masterPublic));
-
3140 }
-
3141 }
-
3142 BEAST_EXPECT(changes.added.empty());
-
3143 BEAST_EXPECT(changes.removed == removed);
-
3144 }
-
3145 {
-
3146 // List threshold = 3 (default), 2 publishers are revoked
-
3147 ManifestCache pubManifests;
-
3148 ManifestCache valManifests;
-
3149 std::vector<Publisher> publishers;
-
3150 auto const keysTotal = valKeys.size();
-
3151 auto trustedKeys = makeValidatorList(
-
3152 5, //
-
3153 2,
-
3154 0,
-
3155 pubManifests,
-
3156 valManifests,
-
3157 {},
-
3158 publishers);
-
3159 BEAST_EXPECT(trustedKeys->getListThreshold() == 3);
-
3160 int untrustedCount = 0;
-
3161 for (auto const& p : publishers)
-
3162 {
-
3163 bool const trusted = trustedKeys->trustedPublisher(p.pubKey);
-
3164 BEAST_EXPECT(p.revoked ^ trusted);
-
3165 untrustedCount += trusted ? 0 : 1;
-
3166 }
-
3167 BEAST_EXPECT(untrustedCount == 2);
-
3168
-
3169 TrustChanges changes = trustedKeys->updateTrusted(
-
3170 activeValidators,
-
3171 env.timeKeeper().now(),
-
3172 env.app().getOPs(),
-
3173 env.app().overlay(),
-
3174 env.app().getHashRouter());
-
3175 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
-
3176 BEAST_EXPECT(
-
3177 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
-
3178
-
3179 hash_set<NodeID> added;
-
3180 for (auto const& val : valKeys)
-
3181 {
-
3182 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
-
3183 added.insert(calcNodeID(val.masterPublic));
-
3184 }
-
3185 BEAST_EXPECT(changes.added == added);
-
3186 BEAST_EXPECT(changes.removed.empty());
-
3187
-
3188 // Expire one publisher - no quorum, no trusted validators
-
3189 env.timeKeeper().set(publishers.back().expiry);
-
3190 changes = trustedKeys->updateTrusted(
-
3191 activeValidators,
-
3192 env.timeKeeper().now(),
-
3193 env.app().getOPs(),
-
3194 env.app().overlay(),
-
3195 env.app().getHashRouter());
-
3196 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
-
3197 BEAST_EXPECT(trustedKeys->getTrustedMasterKeys().size() == 0);
-
3198
-
3199 hash_set<NodeID> removed;
-
3200 for (auto const& val : valKeys)
-
3201 {
-
3202 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
-
3203 BEAST_EXPECT(!trustedKeys->trusted(val.masterPublic));
-
3204 removed.insert(calcNodeID(val.masterPublic));
-
3205 }
-
3206 BEAST_EXPECT(changes.added.empty());
-
3207 BEAST_EXPECT(changes.removed == removed);
-
3208 }
-
3209 {
-
3210 // List threshold = 2, 1 publisher is revoked
-
3211 ManifestCache pubManifests;
-
3212 ManifestCache valManifests;
-
3213 std::vector<Publisher> publishers;
-
3214 // Self is a random validator
-
3215 auto const self = randomValidator();
-
3216 auto const keysTotal = valKeys.size() + 1;
-
3217 auto trustedKeys = makeValidatorList(
-
3218 5, //
-
3219 1,
-
3220 2,
-
3221 pubManifests,
-
3222 valManifests,
-
3223 self,
-
3224 publishers);
-
3225 BEAST_EXPECT(trustedKeys->getListThreshold() == 2);
-
3226 int untrustedCount = 0;
-
3227 for (auto const& p : publishers)
-
3228 {
-
3229 bool const trusted = trustedKeys->trustedPublisher(p.pubKey);
-
3230 BEAST_EXPECT(p.revoked ^ trusted);
-
3231 untrustedCount += trusted ? 0 : 1;
-
3232 }
-
3233 BEAST_EXPECT(untrustedCount == 1);
-
3234
-
3235 TrustChanges changes = trustedKeys->updateTrusted(
-
3236 activeValidators,
-
3237 env.timeKeeper().now(),
-
3238 env.app().getOPs(),
-
3239 env.app().overlay(),
-
3240 env.app().getHashRouter());
-
3241 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
-
3242 BEAST_EXPECT(
-
3243 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
-
3244
-
3245 hash_set<NodeID> added;
-
3246 added.insert(calcNodeID(self.masterPublic));
-
3247 for (auto const& val : valKeys)
-
3248 {
-
3249 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
-
3250 added.insert(calcNodeID(val.masterPublic));
-
3251 }
-
3252 BEAST_EXPECT(changes.added == added);
-
3253 BEAST_EXPECT(changes.removed.empty());
-
3254
-
3255 // Expire one publisher - no quorum
-
3256 env.timeKeeper().set(publishers.back().expiry);
-
3257 changes = trustedKeys->updateTrusted(
-
3258 activeValidators,
-
3259 env.timeKeeper().now(),
-
3260 env.app().getOPs(),
-
3261 env.app().overlay(),
-
3262 env.app().getHashRouter());
-
3263 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
-
3264 BEAST_EXPECT(
-
3265 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
-
3266
-
3267 BEAST_EXPECT(trustedKeys->trusted(self.masterPublic));
-
3268 for (auto const& val : valKeys)
-
3269 {
-
3270 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
-
3271 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
-
3272 }
-
3273 BEAST_EXPECT(changes.added.empty());
-
3274 BEAST_EXPECT(changes.removed.empty());
-
3275 }
-
3276 {
-
3277 // List threshold = 1
-
3278 ManifestCache pubManifests;
-
3279 ManifestCache valManifests;
-
3280 std::vector<Publisher> publishers;
-
3281 // Self is a random validator
-
3282 auto const self = randomValidator();
-
3283 auto const keysTotal = valKeys.size() + 1;
-
3284 auto trustedKeys = makeValidatorList(
-
3285 5, //
-
3286 0,
-
3287 1,
-
3288 pubManifests,
-
3289 valManifests,
-
3290 self,
-
3291 publishers);
-
3292 BEAST_EXPECT(trustedKeys->getListThreshold() == 1);
-
3293 for (auto const& p : publishers)
-
3294 BEAST_EXPECT(trustedKeys->trustedPublisher(p.pubKey));
-
3295
-
3296 TrustChanges changes = trustedKeys->updateTrusted(
-
3297 activeValidators,
-
3298 env.timeKeeper().now(),
-
3299 env.app().getOPs(),
-
3300 env.app().overlay(),
-
3301 env.app().getHashRouter());
-
3302 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
-
3303 BEAST_EXPECT(
-
3304 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
-
3305
-
3306 hash_set<NodeID> added;
-
3307 added.insert(calcNodeID(self.masterPublic));
-
3308 for (auto const& val : valKeys)
-
3309 {
-
3310 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
-
3311 added.insert(calcNodeID(val.masterPublic));
-
3312 }
-
3313 BEAST_EXPECT(changes.added == added);
-
3314 BEAST_EXPECT(changes.removed.empty());
-
3315
-
3316 // Expire one publisher - no quorum
-
3317 env.timeKeeper().set(publishers.back().expiry);
-
3318 changes = trustedKeys->updateTrusted(
-
3319 activeValidators,
-
3320 env.timeKeeper().now(),
-
3321 env.app().getOPs(),
-
3322 env.app().overlay(),
-
3323 env.app().getHashRouter());
-
3324 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
-
3325 BEAST_EXPECT(
-
3326 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
-
3327
-
3328 BEAST_EXPECT(trustedKeys->trusted(self.masterPublic));
-
3329 for (auto const& val : valKeys)
-
3330 {
-
3331 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
-
3332 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
-
3333 }
-
3334 BEAST_EXPECT(changes.added.empty());
-
3335 BEAST_EXPECT(changes.removed.empty());
-
3336 }
-
3337 {
-
3338 // List threshold = 1
-
3339 ManifestCache pubManifests;
-
3340 ManifestCache valManifests;
-
3341 std::vector<Publisher> publishers;
-
3342 // Self is in UNL
-
3343 auto const self = valKeys[7];
-
3344 auto const keysTotal = valKeys.size();
-
3345 auto trustedKeys = makeValidatorList(
-
3346 5, //
-
3347 0,
-
3348 1,
-
3349 pubManifests,
-
3350 valManifests,
-
3351 self,
-
3352 publishers);
-
3353 BEAST_EXPECT(trustedKeys->getListThreshold() == 1);
-
3354 for (auto const& p : publishers)
-
3355 BEAST_EXPECT(trustedKeys->trustedPublisher(p.pubKey));
-
3356
-
3357 TrustChanges changes = trustedKeys->updateTrusted(
-
3358 activeValidators,
-
3359 env.timeKeeper().now(),
-
3360 env.app().getOPs(),
-
3361 env.app().overlay(),
-
3362 env.app().getHashRouter());
-
3363 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
-
3364 BEAST_EXPECT(
-
3365 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
-
3366
-
3367 hash_set<NodeID> added;
-
3368 for (auto const& val : valKeys)
-
3369 {
-
3370 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
-
3371 added.insert(calcNodeID(val.masterPublic));
-
3372 }
-
3373 BEAST_EXPECT(changes.added == added);
-
3374 BEAST_EXPECT(changes.removed.empty());
-
3375
-
3376 // Expire one publisher - no quorum
-
3377 env.timeKeeper().set(publishers.back().expiry);
-
3378 changes = trustedKeys->updateTrusted(
-
3379 activeValidators,
-
3380 env.timeKeeper().now(),
-
3381 env.app().getOPs(),
-
3382 env.app().overlay(),
-
3383 env.app().getHashRouter());
-
3384 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
-
3385 BEAST_EXPECT(
-
3386 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
-
3387
-
3388 BEAST_EXPECT(trustedKeys->trusted(self.masterPublic));
-
3389 for (auto const& val : valKeys)
-
3390 {
-
3391 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
-
3392 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
-
3393 }
-
3394 BEAST_EXPECT(changes.added.empty());
-
3395 BEAST_EXPECT(changes.removed.empty());
-
3396 }
-
3397 {
-
3398 // List threshold = 1
-
3399 ManifestCache pubManifests;
-
3400 ManifestCache valManifests;
-
3401 std::vector<Publisher> publishers;
-
3402 auto const keysTotal = valKeys.size();
-
3403 auto trustedKeys = makeValidatorList(
-
3404 5, //
-
3405 0,
-
3406 1,
-
3407 pubManifests,
-
3408 valManifests,
-
3409 {},
-
3410 publishers);
-
3411 BEAST_EXPECT(trustedKeys->getListThreshold() == 1);
-
3412 for (auto const& p : publishers)
-
3413 BEAST_EXPECT(trustedKeys->trustedPublisher(p.pubKey));
-
3414
-
3415 TrustChanges changes = trustedKeys->updateTrusted(
-
3416 activeValidators,
-
3417 env.timeKeeper().now(),
-
3418 env.app().getOPs(),
-
3419 env.app().overlay(),
-
3420 env.app().getHashRouter());
-
3421 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
-
3422 BEAST_EXPECT(
-
3423 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
-
3424
-
3425 hash_set<NodeID> added;
-
3426 for (auto const& val : valKeys)
-
3427 {
-
3428 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
-
3429 added.insert(calcNodeID(val.masterPublic));
-
3430 }
-
3431 BEAST_EXPECT(changes.added == added);
-
3432 BEAST_EXPECT(changes.removed.empty());
-
3433
-
3434 // Expire one publisher - no quorum
-
3435 env.timeKeeper().set(publishers.back().expiry);
-
3436 changes = trustedKeys->updateTrusted(
-
3437 activeValidators,
-
3438 env.timeKeeper().now(),
-
3439 env.app().getOPs(),
-
3440 env.app().overlay(),
-
3441 env.app().getHashRouter());
-
3442 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
-
3443 BEAST_EXPECT(
-
3444 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
-
3445
-
3446 for (auto const& val : valKeys)
-
3447 {
-
3448 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
-
3449 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
-
3450 }
-
3451 BEAST_EXPECT(changes.added.empty());
-
3452 BEAST_EXPECT(changes.removed.empty());
-
3453 }
-
3454
-
3455 // Test cases use 2 publishers
-
3456 {
-
3457 // List threshold = 1, 1 publisher revoked
-
3458 ManifestCache pubManifests;
-
3459 ManifestCache valManifests;
-
3460 std::vector<Publisher> publishers;
-
3461 // Self is a random validator
-
3462 auto const self = randomValidator();
-
3463 auto const keysTotal = valKeys.size() + 1;
-
3464 auto trustedKeys = makeValidatorList(
-
3465 2, //
-
3466 1,
+
2701
+
2702 void
+
+ +
2704 {
+
2705 testcase("Test quorum disabled");
+
2706
+
2707 std::string const siteUri = "testQuorumDisabled.test";
+
2708 jtx::Env env(*this);
+
2709 auto& app = env.app();
+
2710
+
2711 constexpr std::size_t maxKeys = 20;
+
2712 hash_set<NodeID> activeValidators;
+
2713 std::vector<Validator> valKeys;
+
2714 while (valKeys.size() != maxKeys)
+
2715 {
+
2716 valKeys.push_back(randomValidator());
+
2717 activeValidators.emplace(calcNodeID(valKeys.back().masterPublic));
+
2718 }
+
2719
+
2720 struct Publisher
+
2721 {
+
2722 bool revoked;
+
2723 PublicKey pubKey;
+ + +
2726 NetClock::time_point expiry = {};
+
2727 };
+
2728
+
2729 // Create ValidatorList with a set of countTotal publishers, of which
+
2730 // first countRevoked are revoked and the last one expires early
+
2731 auto makeValidatorList = [&, this](
+
2732 std::size_t countTotal,
+
2733 std::size_t countRevoked,
+
2734 std::size_t listThreshold,
+
2735 ManifestCache& pubManifests,
+
2736 ManifestCache& valManifests,
+ +
2738 std::vector<Publisher>& publishers // out
+ +
2740 auto result = std::make_unique<ValidatorList>(
+
2741 valManifests,
+
2742 pubManifests,
+
2743 env.timeKeeper(),
+
2744 app.config().legacy("database_path"),
+
2745 env.journal);
+
2746
+
2747 std::vector<std::string> cfgPublishers;
+
2748 for (std::size_t i = 0; i < countTotal; ++i)
+
2749 {
+
2750 auto const publisherSecret = randomSecretKey();
+
2751 auto const publisherPublic =
+
2752 derivePublicKey(KeyType::ed25519, publisherSecret);
+
2753 auto const pubSigningKeys = randomKeyPair(KeyType::secp256k1);
+
2754 cfgPublishers.push_back(strHex(publisherPublic));
+
2755
+
2756 constexpr auto revoked =
+ +
2758 auto const manifest = base64_encode(makeManifestString(
+
2759 publisherPublic,
+
2760 publisherSecret,
+
2761 pubSigningKeys.first,
+
2762 pubSigningKeys.second,
+
2763 i < countRevoked ? revoked : 1));
+
2764 publishers.push_back(Publisher{
+
2765 i < countRevoked,
+
2766 publisherPublic,
+
2767 pubSigningKeys,
+
2768 manifest});
+
2769 }
+
2770
+
2771 std::vector<std::string> const emptyCfgKeys;
+
2772 auto threshold =
+
2773 listThreshold > 0 ? std::optional(listThreshold) : std::nullopt;
+
2774 if (self)
+
2775 {
+
2776 valManifests.applyManifest(
+
2777 *deserializeManifest(base64_decode(self->manifest)));
+
2778 BEAST_EXPECT(result->load(
+
2779 self->signingPublic,
+
2780 emptyCfgKeys,
+
2781 cfgPublishers,
+
2782 threshold));
+
2783 }
+
2784 else
+
2785 {
+
2786 BEAST_EXPECT(
+
2787 result->load({}, emptyCfgKeys, cfgPublishers, threshold));
+
2788 }
+
2789
+
2790 for (std::size_t i = 0; i < countTotal; ++i)
+
2791 {
+
2792 using namespace std::chrono_literals;
+
2793 publishers[i].expiry = env.timeKeeper().now() +
+
2794 (i == countTotal - 1 ? 60s : 3600s);
+
2795 auto const blob = makeList(
+
2796 valKeys,
+
2797 1,
+
2798 publishers[i].expiry.time_since_epoch().count());
+
2799 auto const sig = signList(blob, publishers[i].signingKeys);
+
2800
+
2801 BEAST_EXPECT(
+
2802 result
+
2803 ->applyLists(
+
2804 publishers[i].manifest,
+
2805 1,
+
2806 {{blob, sig, {}}},
+
2807 siteUri)
+
2808 .bestDisposition() ==
+
2809 (publishers[i].revoked ? ListDisposition::untrusted
+
2810 : ListDisposition::accepted));
+
2811 }
+
2812
+
2813 return result;
+
2814 };
+
2815
+
2816 // Test cases use 5 publishers.
+
2817 constexpr auto quorumDisabled = std::numeric_limits<std::size_t>::max();
+
2818 {
+
2819 // List threshold = 5 (same as number of trusted publishers)
+
2820 ManifestCache pubManifests;
+
2821 ManifestCache valManifests;
+
2822 std::vector<Publisher> publishers;
+
2823 // Self is a random validator
+
2824 auto const self = randomValidator();
+
2825 auto const keysTotal = valKeys.size() + 1;
+
2826 auto trustedKeys = makeValidatorList(
+
2827 5, //
+
2828 0,
+
2829 5,
+
2830 pubManifests,
+
2831 valManifests,
+
2832 self,
+
2833 publishers);
+
2834 BEAST_EXPECT(trustedKeys->getListThreshold() == 5);
+
2835 for (auto const& p : publishers)
+
2836 BEAST_EXPECT(trustedKeys->trustedPublisher(p.pubKey));
+
2837
+
2838 TrustChanges changes = trustedKeys->updateTrusted(
+
2839 activeValidators,
+
2840 env.timeKeeper().now(),
+
2841 env.app().getOPs(),
+
2842 env.app().overlay(),
+
2843 env.app().getHashRouter());
+
2844 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
+
2845 BEAST_EXPECT(
+
2846 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
+
2847
+
2848 hash_set<NodeID> added;
+
2849 added.insert(calcNodeID(self.masterPublic));
+
2850 for (auto const& val : valKeys)
+
2851 {
+
2852 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
+
2853 added.insert(calcNodeID(val.masterPublic));
+
2854 }
+
2855 BEAST_EXPECT(changes.added == added);
+
2856 BEAST_EXPECT(changes.removed.empty());
+
2857
+
2858 // Expire one publisher - only trusted validator is self
+
2859 env.timeKeeper().set(publishers.back().expiry);
+
2860 changes = trustedKeys->updateTrusted(
+
2861 activeValidators,
+
2862 env.timeKeeper().now(),
+
2863 env.app().getOPs(),
+
2864 env.app().overlay(),
+
2865 env.app().getHashRouter());
+
2866 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
+
2867 BEAST_EXPECT(trustedKeys->getTrustedMasterKeys().size() == 1);
+
2868
+
2869 hash_set<NodeID> removed;
+
2870 BEAST_EXPECT(trustedKeys->trusted(self.masterPublic));
+
2871 for (auto const& val : valKeys)
+
2872 {
+
2873 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
+
2874 BEAST_EXPECT(!trustedKeys->trusted(val.masterPublic));
+
2875 removed.insert(calcNodeID(val.masterPublic));
+
2876 }
+
2877 BEAST_EXPECT(changes.added.empty());
+
2878 BEAST_EXPECT(changes.removed == removed);
+
2879 }
+
2880 {
+
2881 // List threshold = 5 (same as number of trusted publishers)
+
2882 ManifestCache pubManifests;
+
2883 ManifestCache valManifests;
+
2884 std::vector<Publisher> publishers;
+
2885 auto const keysTotal = valKeys.size();
+
2886 auto trustedKeys = makeValidatorList(
+
2887 5, //
+
2888 0,
+
2889 5,
+
2890 pubManifests,
+
2891 valManifests,
+
2892 {},
+
2893 publishers);
+
2894 BEAST_EXPECT(trustedKeys->getListThreshold() == 5);
+
2895 for (auto const& p : publishers)
+
2896 BEAST_EXPECT(trustedKeys->trustedPublisher(p.pubKey));
+
2897
+
2898 TrustChanges changes = trustedKeys->updateTrusted(
+
2899 activeValidators,
+
2900 env.timeKeeper().now(),
+
2901 env.app().getOPs(),
+
2902 env.app().overlay(),
+
2903 env.app().getHashRouter());
+
2904 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
+
2905 BEAST_EXPECT(
+
2906 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
+
2907
+
2908 hash_set<NodeID> added;
+
2909 for (auto const& val : valKeys)
+
2910 {
+
2911 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
+
2912 added.insert(calcNodeID(val.masterPublic));
+
2913 }
+
2914 BEAST_EXPECT(changes.added == added);
+
2915 BEAST_EXPECT(changes.removed.empty());
+
2916
+
2917 // Expire one publisher - no trusted validators
+
2918 env.timeKeeper().set(publishers.back().expiry);
+
2919 changes = trustedKeys->updateTrusted(
+
2920 activeValidators,
+
2921 env.timeKeeper().now(),
+
2922 env.app().getOPs(),
+
2923 env.app().overlay(),
+
2924 env.app().getHashRouter());
+
2925 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
+
2926 BEAST_EXPECT(trustedKeys->getTrustedMasterKeys().size() == 0);
+
2927
+
2928 hash_set<NodeID> removed;
+
2929 for (auto const& val : valKeys)
+
2930 {
+
2931 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
+
2932 BEAST_EXPECT(!trustedKeys->trusted(val.masterPublic));
+
2933 removed.insert(calcNodeID(val.masterPublic));
+
2934 }
+
2935 BEAST_EXPECT(changes.added.empty());
+
2936 BEAST_EXPECT(changes.removed == removed);
+
2937 }
+
2938 {
+
2939 // List threshold = 4, 1 publisher is revoked
+
2940 ManifestCache pubManifests;
+
2941 ManifestCache valManifests;
+
2942 std::vector<Publisher> publishers;
+
2943 // Self is in UNL
+
2944 auto const self = valKeys[1];
+
2945 auto const keysTotal = valKeys.size();
+
2946 auto trustedKeys = makeValidatorList(
+
2947 5, //
+
2948 1,
+
2949 4,
+
2950 pubManifests,
+
2951 valManifests,
+
2952 self,
+
2953 publishers);
+
2954 BEAST_EXPECT(trustedKeys->getListThreshold() == 4);
+
2955 int untrustedCount = 0;
+
2956 for (auto const& p : publishers)
+
2957 {
+
2958 bool const trusted = trustedKeys->trustedPublisher(p.pubKey);
+
2959 BEAST_EXPECT(p.revoked ^ trusted);
+
2960 untrustedCount += trusted ? 0 : 1;
+
2961 }
+
2962 BEAST_EXPECT(untrustedCount == 1);
+
2963
+
2964 TrustChanges changes = trustedKeys->updateTrusted(
+
2965 activeValidators,
+
2966 env.timeKeeper().now(),
+
2967 env.app().getOPs(),
+
2968 env.app().overlay(),
+
2969 env.app().getHashRouter());
+
2970 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
+
2971 BEAST_EXPECT(
+
2972 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
+
2973
+
2974 hash_set<NodeID> added;
+
2975 for (auto const& val : valKeys)
+
2976 {
+
2977 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
+
2978 added.insert(calcNodeID(val.masterPublic));
+
2979 }
+
2980 BEAST_EXPECT(changes.added == added);
+
2981 BEAST_EXPECT(changes.removed.empty());
+
2982
+
2983 // Expire one publisher - only trusted validator is self
+
2984 env.timeKeeper().set(publishers.back().expiry);
+
2985 changes = trustedKeys->updateTrusted(
+
2986 activeValidators,
+
2987 env.timeKeeper().now(),
+
2988 env.app().getOPs(),
+
2989 env.app().overlay(),
+
2990 env.app().getHashRouter());
+
2991 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
+
2992 BEAST_EXPECT(trustedKeys->getTrustedMasterKeys().size() == 1);
+
2993
+
2994 hash_set<NodeID> removed;
+
2995 BEAST_EXPECT(trustedKeys->trusted(self.masterPublic));
+
2996 for (auto const& val : valKeys)
+
2997 {
+
2998 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
+
2999 if (val.masterPublic != self.masterPublic)
+
3000 {
+
3001 BEAST_EXPECT(!trustedKeys->trusted(val.masterPublic));
+
3002 removed.insert(calcNodeID(val.masterPublic));
+
3003 }
+
3004 }
+
3005 BEAST_EXPECT(changes.added.empty());
+
3006 BEAST_EXPECT(changes.removed == removed);
+
3007 }
+
3008 {
+
3009 // List threshold = 3 (default), 2 publishers are revoked
+
3010 ManifestCache pubManifests;
+
3011 ManifestCache valManifests;
+
3012 std::vector<Publisher> publishers;
+
3013 // Self is a random validator
+
3014 auto const self = randomValidator();
+
3015 auto const keysTotal = valKeys.size() + 1;
+
3016 auto trustedKeys = makeValidatorList(
+
3017 5, //
+
3018 2,
+
3019 0,
+
3020 pubManifests,
+
3021 valManifests,
+
3022 self,
+
3023 publishers);
+
3024 BEAST_EXPECT(trustedKeys->getListThreshold() == 3);
+
3025 int untrustedCount = 0;
+
3026 for (auto const& p : publishers)
+
3027 {
+
3028 bool const trusted = trustedKeys->trustedPublisher(p.pubKey);
+
3029 BEAST_EXPECT(p.revoked ^ trusted);
+
3030 untrustedCount += trusted ? 0 : 1;
+
3031 }
+
3032 BEAST_EXPECT(untrustedCount == 2);
+
3033
+
3034 TrustChanges changes = trustedKeys->updateTrusted(
+
3035 activeValidators,
+
3036 env.timeKeeper().now(),
+
3037 env.app().getOPs(),
+
3038 env.app().overlay(),
+
3039 env.app().getHashRouter());
+
3040 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
+
3041 BEAST_EXPECT(
+
3042 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
+
3043
+
3044 hash_set<NodeID> added;
+
3045 added.insert(calcNodeID(self.masterPublic));
+
3046 for (auto const& val : valKeys)
+
3047 {
+
3048 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
+
3049 added.insert(calcNodeID(val.masterPublic));
+
3050 }
+
3051 BEAST_EXPECT(changes.added == added);
+
3052 BEAST_EXPECT(changes.removed.empty());
+
3053
+
3054 // Expire one publisher - no quorum, only trusted validator is self
+
3055 env.timeKeeper().set(publishers.back().expiry);
+
3056 changes = trustedKeys->updateTrusted(
+
3057 activeValidators,
+
3058 env.timeKeeper().now(),
+
3059 env.app().getOPs(),
+
3060 env.app().overlay(),
+
3061 env.app().getHashRouter());
+
3062 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
+
3063 BEAST_EXPECT(trustedKeys->getTrustedMasterKeys().size() == 1);
+
3064
+
3065 hash_set<NodeID> removed;
+
3066 BEAST_EXPECT(trustedKeys->trusted(self.masterPublic));
+
3067 for (auto const& val : valKeys)
+
3068 {
+
3069 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
+
3070 BEAST_EXPECT(!trustedKeys->trusted(val.masterPublic));
+
3071 removed.insert(calcNodeID(val.masterPublic));
+
3072 }
+
3073 BEAST_EXPECT(changes.added.empty());
+
3074 BEAST_EXPECT(changes.removed == removed);
+
3075 }
+
3076 {
+
3077 // List threshold = 3 (default), 2 publishers are revoked
+
3078 ManifestCache pubManifests;
+
3079 ManifestCache valManifests;
+
3080 std::vector<Publisher> publishers;
+
3081 // Self is in UNL
+
3082 auto const self = valKeys[5];
+
3083 auto const keysTotal = valKeys.size();
+
3084 auto trustedKeys = makeValidatorList(
+
3085 5, //
+
3086 2,
+
3087 0,
+
3088 pubManifests,
+
3089 valManifests,
+
3090 self,
+
3091 publishers);
+
3092 BEAST_EXPECT(trustedKeys->getListThreshold() == 3);
+
3093 int untrustedCount = 0;
+
3094 for (auto const& p : publishers)
+
3095 {
+
3096 bool const trusted = trustedKeys->trustedPublisher(p.pubKey);
+
3097 BEAST_EXPECT(p.revoked ^ trusted);
+
3098 untrustedCount += trusted ? 0 : 1;
+
3099 }
+
3100 BEAST_EXPECT(untrustedCount == 2);
+
3101
+
3102 TrustChanges changes = trustedKeys->updateTrusted(
+
3103 activeValidators,
+
3104 env.timeKeeper().now(),
+
3105 env.app().getOPs(),
+
3106 env.app().overlay(),
+
3107 env.app().getHashRouter());
+
3108 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
+
3109 BEAST_EXPECT(
+
3110 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
+
3111
+
3112 hash_set<NodeID> added;
+
3113 for (auto const& val : valKeys)
+
3114 {
+
3115 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
+
3116 added.insert(calcNodeID(val.masterPublic));
+
3117 }
+
3118 BEAST_EXPECT(changes.added == added);
+
3119 BEAST_EXPECT(changes.removed.empty());
+
3120
+
3121 // Expire one publisher - no quorum, only trusted validator is self
+
3122 env.timeKeeper().set(publishers.back().expiry);
+
3123 changes = trustedKeys->updateTrusted(
+
3124 activeValidators,
+
3125 env.timeKeeper().now(),
+
3126 env.app().getOPs(),
+
3127 env.app().overlay(),
+
3128 env.app().getHashRouter());
+
3129 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
+
3130 BEAST_EXPECT(trustedKeys->getTrustedMasterKeys().size() == 1);
+
3131
+
3132 hash_set<NodeID> removed;
+
3133 BEAST_EXPECT(trustedKeys->trusted(self.masterPublic));
+
3134 for (auto const& val : valKeys)
+
3135 {
+
3136 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
+
3137 if (val.masterPublic != self.masterPublic)
+
3138 {
+
3139 BEAST_EXPECT(!trustedKeys->trusted(val.masterPublic));
+
3140 removed.insert(calcNodeID(val.masterPublic));
+
3141 }
+
3142 }
+
3143 BEAST_EXPECT(changes.added.empty());
+
3144 BEAST_EXPECT(changes.removed == removed);
+
3145 }
+
3146 {
+
3147 // List threshold = 3 (default), 2 publishers are revoked
+
3148 ManifestCache pubManifests;
+
3149 ManifestCache valManifests;
+
3150 std::vector<Publisher> publishers;
+
3151 auto const keysTotal = valKeys.size();
+
3152 auto trustedKeys = makeValidatorList(
+
3153 5, //
+
3154 2,
+
3155 0,
+
3156 pubManifests,
+
3157 valManifests,
+
3158 {},
+
3159 publishers);
+
3160 BEAST_EXPECT(trustedKeys->getListThreshold() == 3);
+
3161 int untrustedCount = 0;
+
3162 for (auto const& p : publishers)
+
3163 {
+
3164 bool const trusted = trustedKeys->trustedPublisher(p.pubKey);
+
3165 BEAST_EXPECT(p.revoked ^ trusted);
+
3166 untrustedCount += trusted ? 0 : 1;
+
3167 }
+
3168 BEAST_EXPECT(untrustedCount == 2);
+
3169
+
3170 TrustChanges changes = trustedKeys->updateTrusted(
+
3171 activeValidators,
+
3172 env.timeKeeper().now(),
+
3173 env.app().getOPs(),
+
3174 env.app().overlay(),
+
3175 env.app().getHashRouter());
+
3176 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
+
3177 BEAST_EXPECT(
+
3178 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
+
3179
+
3180 hash_set<NodeID> added;
+
3181 for (auto const& val : valKeys)
+
3182 {
+
3183 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
+
3184 added.insert(calcNodeID(val.masterPublic));
+
3185 }
+
3186 BEAST_EXPECT(changes.added == added);
+
3187 BEAST_EXPECT(changes.removed.empty());
+
3188
+
3189 // Expire one publisher - no quorum, no trusted validators
+
3190 env.timeKeeper().set(publishers.back().expiry);
+
3191 changes = trustedKeys->updateTrusted(
+
3192 activeValidators,
+
3193 env.timeKeeper().now(),
+
3194 env.app().getOPs(),
+
3195 env.app().overlay(),
+
3196 env.app().getHashRouter());
+
3197 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
+
3198 BEAST_EXPECT(trustedKeys->getTrustedMasterKeys().size() == 0);
+
3199
+
3200 hash_set<NodeID> removed;
+
3201 for (auto const& val : valKeys)
+
3202 {
+
3203 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
+
3204 BEAST_EXPECT(!trustedKeys->trusted(val.masterPublic));
+
3205 removed.insert(calcNodeID(val.masterPublic));
+
3206 }
+
3207 BEAST_EXPECT(changes.added.empty());
+
3208 BEAST_EXPECT(changes.removed == removed);
+
3209 }
+
3210 {
+
3211 // List threshold = 2, 1 publisher is revoked
+
3212 ManifestCache pubManifests;
+
3213 ManifestCache valManifests;
+
3214 std::vector<Publisher> publishers;
+
3215 // Self is a random validator
+
3216 auto const self = randomValidator();
+
3217 auto const keysTotal = valKeys.size() + 1;
+
3218 auto trustedKeys = makeValidatorList(
+
3219 5, //
+
3220 1,
+
3221 2,
+
3222 pubManifests,
+
3223 valManifests,
+
3224 self,
+
3225 publishers);
+
3226 BEAST_EXPECT(trustedKeys->getListThreshold() == 2);
+
3227 int untrustedCount = 0;
+
3228 for (auto const& p : publishers)
+
3229 {
+
3230 bool const trusted = trustedKeys->trustedPublisher(p.pubKey);
+
3231 BEAST_EXPECT(p.revoked ^ trusted);
+
3232 untrustedCount += trusted ? 0 : 1;
+
3233 }
+
3234 BEAST_EXPECT(untrustedCount == 1);
+
3235
+
3236 TrustChanges changes = trustedKeys->updateTrusted(
+
3237 activeValidators,
+
3238 env.timeKeeper().now(),
+
3239 env.app().getOPs(),
+
3240 env.app().overlay(),
+
3241 env.app().getHashRouter());
+
3242 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
+
3243 BEAST_EXPECT(
+
3244 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
+
3245
+
3246 hash_set<NodeID> added;
+
3247 added.insert(calcNodeID(self.masterPublic));
+
3248 for (auto const& val : valKeys)
+
3249 {
+
3250 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
+
3251 added.insert(calcNodeID(val.masterPublic));
+
3252 }
+
3253 BEAST_EXPECT(changes.added == added);
+
3254 BEAST_EXPECT(changes.removed.empty());
+
3255
+
3256 // Expire one publisher - no quorum
+
3257 env.timeKeeper().set(publishers.back().expiry);
+
3258 changes = trustedKeys->updateTrusted(
+
3259 activeValidators,
+
3260 env.timeKeeper().now(),
+
3261 env.app().getOPs(),
+
3262 env.app().overlay(),
+
3263 env.app().getHashRouter());
+
3264 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
+
3265 BEAST_EXPECT(
+
3266 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
+
3267
+
3268 BEAST_EXPECT(trustedKeys->trusted(self.masterPublic));
+
3269 for (auto const& val : valKeys)
+
3270 {
+
3271 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
+
3272 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
+
3273 }
+
3274 BEAST_EXPECT(changes.added.empty());
+
3275 BEAST_EXPECT(changes.removed.empty());
+
3276 }
+
3277 {
+
3278 // List threshold = 1
+
3279 ManifestCache pubManifests;
+
3280 ManifestCache valManifests;
+
3281 std::vector<Publisher> publishers;
+
3282 // Self is a random validator
+
3283 auto const self = randomValidator();
+
3284 auto const keysTotal = valKeys.size() + 1;
+
3285 auto trustedKeys = makeValidatorList(
+
3286 5, //
+
3287 0,
+
3288 1,
+
3289 pubManifests,
+
3290 valManifests,
+
3291 self,
+
3292 publishers);
+
3293 BEAST_EXPECT(trustedKeys->getListThreshold() == 1);
+
3294 for (auto const& p : publishers)
+
3295 BEAST_EXPECT(trustedKeys->trustedPublisher(p.pubKey));
+
3296
+
3297 TrustChanges changes = trustedKeys->updateTrusted(
+
3298 activeValidators,
+
3299 env.timeKeeper().now(),
+
3300 env.app().getOPs(),
+
3301 env.app().overlay(),
+
3302 env.app().getHashRouter());
+
3303 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
+
3304 BEAST_EXPECT(
+
3305 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
+
3306
+
3307 hash_set<NodeID> added;
+
3308 added.insert(calcNodeID(self.masterPublic));
+
3309 for (auto const& val : valKeys)
+
3310 {
+
3311 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
+
3312 added.insert(calcNodeID(val.masterPublic));
+
3313 }
+
3314 BEAST_EXPECT(changes.added == added);
+
3315 BEAST_EXPECT(changes.removed.empty());
+
3316
+
3317 // Expire one publisher - no quorum
+
3318 env.timeKeeper().set(publishers.back().expiry);
+
3319 changes = trustedKeys->updateTrusted(
+
3320 activeValidators,
+
3321 env.timeKeeper().now(),
+
3322 env.app().getOPs(),
+
3323 env.app().overlay(),
+
3324 env.app().getHashRouter());
+
3325 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
+
3326 BEAST_EXPECT(
+
3327 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
+
3328
+
3329 BEAST_EXPECT(trustedKeys->trusted(self.masterPublic));
+
3330 for (auto const& val : valKeys)
+
3331 {
+
3332 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
+
3333 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
+
3334 }
+
3335 BEAST_EXPECT(changes.added.empty());
+
3336 BEAST_EXPECT(changes.removed.empty());
+
3337 }
+
3338 {
+
3339 // List threshold = 1
+
3340 ManifestCache pubManifests;
+
3341 ManifestCache valManifests;
+
3342 std::vector<Publisher> publishers;
+
3343 // Self is in UNL
+
3344 auto const self = valKeys[7];
+
3345 auto const keysTotal = valKeys.size();
+
3346 auto trustedKeys = makeValidatorList(
+
3347 5, //
+
3348 0,
+
3349 1,
+
3350 pubManifests,
+
3351 valManifests,
+
3352 self,
+
3353 publishers);
+
3354 BEAST_EXPECT(trustedKeys->getListThreshold() == 1);
+
3355 for (auto const& p : publishers)
+
3356 BEAST_EXPECT(trustedKeys->trustedPublisher(p.pubKey));
+
3357
+
3358 TrustChanges changes = trustedKeys->updateTrusted(
+
3359 activeValidators,
+
3360 env.timeKeeper().now(),
+
3361 env.app().getOPs(),
+
3362 env.app().overlay(),
+
3363 env.app().getHashRouter());
+
3364 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
+
3365 BEAST_EXPECT(
+
3366 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
+
3367
+
3368 hash_set<NodeID> added;
+
3369 for (auto const& val : valKeys)
+
3370 {
+
3371 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
+
3372 added.insert(calcNodeID(val.masterPublic));
+
3373 }
+
3374 BEAST_EXPECT(changes.added == added);
+
3375 BEAST_EXPECT(changes.removed.empty());
+
3376
+
3377 // Expire one publisher - no quorum
+
3378 env.timeKeeper().set(publishers.back().expiry);
+
3379 changes = trustedKeys->updateTrusted(
+
3380 activeValidators,
+
3381 env.timeKeeper().now(),
+
3382 env.app().getOPs(),
+
3383 env.app().overlay(),
+
3384 env.app().getHashRouter());
+
3385 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
+
3386 BEAST_EXPECT(
+
3387 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
+
3388
+
3389 BEAST_EXPECT(trustedKeys->trusted(self.masterPublic));
+
3390 for (auto const& val : valKeys)
+
3391 {
+
3392 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
+
3393 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
+
3394 }
+
3395 BEAST_EXPECT(changes.added.empty());
+
3396 BEAST_EXPECT(changes.removed.empty());
+
3397 }
+
3398 {
+
3399 // List threshold = 1
+
3400 ManifestCache pubManifests;
+
3401 ManifestCache valManifests;
+
3402 std::vector<Publisher> publishers;
+
3403 auto const keysTotal = valKeys.size();
+
3404 auto trustedKeys = makeValidatorList(
+
3405 5, //
+
3406 0,
+
3407 1,
+
3408 pubManifests,
+
3409 valManifests,
+
3410 {},
+
3411 publishers);
+
3412 BEAST_EXPECT(trustedKeys->getListThreshold() == 1);
+
3413 for (auto const& p : publishers)
+
3414 BEAST_EXPECT(trustedKeys->trustedPublisher(p.pubKey));
+
3415
+
3416 TrustChanges changes = trustedKeys->updateTrusted(
+
3417 activeValidators,
+
3418 env.timeKeeper().now(),
+
3419 env.app().getOPs(),
+
3420 env.app().overlay(),
+
3421 env.app().getHashRouter());
+
3422 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
+
3423 BEAST_EXPECT(
+
3424 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
+
3425
+
3426 hash_set<NodeID> added;
+
3427 for (auto const& val : valKeys)
+
3428 {
+
3429 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
+
3430 added.insert(calcNodeID(val.masterPublic));
+
3431 }
+
3432 BEAST_EXPECT(changes.added == added);
+
3433 BEAST_EXPECT(changes.removed.empty());
+
3434
+
3435 // Expire one publisher - no quorum
+
3436 env.timeKeeper().set(publishers.back().expiry);
+
3437 changes = trustedKeys->updateTrusted(
+
3438 activeValidators,
+
3439 env.timeKeeper().now(),
+
3440 env.app().getOPs(),
+
3441 env.app().overlay(),
+
3442 env.app().getHashRouter());
+
3443 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
+
3444 BEAST_EXPECT(
+
3445 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
+
3446
+
3447 for (auto const& val : valKeys)
+
3448 {
+
3449 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
+
3450 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
+
3451 }
+
3452 BEAST_EXPECT(changes.added.empty());
+
3453 BEAST_EXPECT(changes.removed.empty());
+
3454 }
+
3455
+
3456 // Test cases use 2 publishers
+
3457 {
+
3458 // List threshold = 1, 1 publisher revoked
+
3459 ManifestCache pubManifests;
+
3460 ManifestCache valManifests;
+
3461 std::vector<Publisher> publishers;
+
3462 // Self is a random validator
+
3463 auto const self = randomValidator();
+
3464 auto const keysTotal = valKeys.size() + 1;
+
3465 auto trustedKeys = makeValidatorList(
+
3466 2, //
3467 1,
-
3468 pubManifests,
-
3469 valManifests,
-
3470 self,
-
3471 publishers);
-
3472 BEAST_EXPECT(trustedKeys->getListThreshold() == 1);
-
3473 int untrustedCount = 0;
-
3474 for (auto const& p : publishers)
-
3475 {
-
3476 bool const trusted = trustedKeys->trustedPublisher(p.pubKey);
-
3477 BEAST_EXPECT(p.revoked ^ trusted);
-
3478 untrustedCount += trusted ? 0 : 1;
-
3479 }
-
3480 BEAST_EXPECT(untrustedCount == 1);
-
3481
-
3482 TrustChanges changes = trustedKeys->updateTrusted(
-
3483 activeValidators,
-
3484 env.timeKeeper().now(),
-
3485 env.app().getOPs(),
-
3486 env.app().overlay(),
-
3487 env.app().getHashRouter());
-
3488 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
-
3489 BEAST_EXPECT(
-
3490 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
-
3491
-
3492 hash_set<NodeID> added;
-
3493 added.insert(calcNodeID(self.masterPublic));
-
3494 for (auto const& val : valKeys)
-
3495 {
-
3496 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
-
3497 added.insert(calcNodeID(val.masterPublic));
-
3498 }
-
3499 BEAST_EXPECT(changes.added == added);
-
3500 BEAST_EXPECT(changes.removed.empty());
-
3501
-
3502 // Expire one publisher - no quorum, only trusted validator is self
-
3503 env.timeKeeper().set(publishers.back().expiry);
-
3504 changes = trustedKeys->updateTrusted(
-
3505 activeValidators,
-
3506 env.timeKeeper().now(),
-
3507 env.app().getOPs(),
-
3508 env.app().overlay(),
-
3509 env.app().getHashRouter());
-
3510 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
-
3511 BEAST_EXPECT(trustedKeys->getTrustedMasterKeys().size() == 1);
-
3512
-
3513 hash_set<NodeID> removed;
-
3514 BEAST_EXPECT(trustedKeys->trusted(self.masterPublic));
-
3515 for (auto const& val : valKeys)
-
3516 {
-
3517 BEAST_EXPECT(!trustedKeys->listed(val.masterPublic));
-
3518 BEAST_EXPECT(!trustedKeys->trusted(val.masterPublic));
-
3519 removed.insert(calcNodeID(val.masterPublic));
-
3520 }
-
3521 BEAST_EXPECT(changes.added.empty());
-
3522 BEAST_EXPECT(changes.removed == removed);
-
3523 }
-
3524 {
-
3525 // List threshold = 1, 1 publisher revoked
-
3526 ManifestCache pubManifests;
-
3527 ManifestCache valManifests;
-
3528 std::vector<Publisher> publishers;
-
3529 // Self is in UNL
-
3530 auto const self = valKeys[5];
-
3531 auto const keysTotal = valKeys.size();
-
3532 auto trustedKeys = makeValidatorList(
-
3533 2, //
-
3534 1,
+
3468 1,
+
3469 pubManifests,
+
3470 valManifests,
+
3471 self,
+
3472 publishers);
+
3473 BEAST_EXPECT(trustedKeys->getListThreshold() == 1);
+
3474 int untrustedCount = 0;
+
3475 for (auto const& p : publishers)
+
3476 {
+
3477 bool const trusted = trustedKeys->trustedPublisher(p.pubKey);
+
3478 BEAST_EXPECT(p.revoked ^ trusted);
+
3479 untrustedCount += trusted ? 0 : 1;
+
3480 }
+
3481 BEAST_EXPECT(untrustedCount == 1);
+
3482
+
3483 TrustChanges changes = trustedKeys->updateTrusted(
+
3484 activeValidators,
+
3485 env.timeKeeper().now(),
+
3486 env.app().getOPs(),
+
3487 env.app().overlay(),
+
3488 env.app().getHashRouter());
+
3489 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
+
3490 BEAST_EXPECT(
+
3491 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
+
3492
+
3493 hash_set<NodeID> added;
+
3494 added.insert(calcNodeID(self.masterPublic));
+
3495 for (auto const& val : valKeys)
+
3496 {
+
3497 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
+
3498 added.insert(calcNodeID(val.masterPublic));
+
3499 }
+
3500 BEAST_EXPECT(changes.added == added);
+
3501 BEAST_EXPECT(changes.removed.empty());
+
3502
+
3503 // Expire one publisher - no quorum, only trusted validator is self
+
3504 env.timeKeeper().set(publishers.back().expiry);
+
3505 changes = trustedKeys->updateTrusted(
+
3506 activeValidators,
+
3507 env.timeKeeper().now(),
+
3508 env.app().getOPs(),
+
3509 env.app().overlay(),
+
3510 env.app().getHashRouter());
+
3511 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
+
3512 BEAST_EXPECT(trustedKeys->getTrustedMasterKeys().size() == 1);
+
3513
+
3514 hash_set<NodeID> removed;
+
3515 BEAST_EXPECT(trustedKeys->trusted(self.masterPublic));
+
3516 for (auto const& val : valKeys)
+
3517 {
+
3518 BEAST_EXPECT(!trustedKeys->listed(val.masterPublic));
+
3519 BEAST_EXPECT(!trustedKeys->trusted(val.masterPublic));
+
3520 removed.insert(calcNodeID(val.masterPublic));
+
3521 }
+
3522 BEAST_EXPECT(changes.added.empty());
+
3523 BEAST_EXPECT(changes.removed == removed);
+
3524 }
+
3525 {
+
3526 // List threshold = 1, 1 publisher revoked
+
3527 ManifestCache pubManifests;
+
3528 ManifestCache valManifests;
+
3529 std::vector<Publisher> publishers;
+
3530 // Self is in UNL
+
3531 auto const self = valKeys[5];
+
3532 auto const keysTotal = valKeys.size();
+
3533 auto trustedKeys = makeValidatorList(
+
3534 2, //
3535 1,
-
3536 pubManifests,
-
3537 valManifests,
-
3538 self,
-
3539 publishers);
-
3540 BEAST_EXPECT(trustedKeys->getListThreshold() == 1);
-
3541 int untrustedCount = 0;
-
3542 for (auto const& p : publishers)
-
3543 {
-
3544 bool const trusted = trustedKeys->trustedPublisher(p.pubKey);
-
3545 BEAST_EXPECT(p.revoked ^ trusted);
-
3546 untrustedCount += trusted ? 0 : 1;
-
3547 }
-
3548 BEAST_EXPECT(untrustedCount == 1);
-
3549
-
3550 TrustChanges changes = trustedKeys->updateTrusted(
-
3551 activeValidators,
-
3552 env.timeKeeper().now(),
-
3553 env.app().getOPs(),
-
3554 env.app().overlay(),
-
3555 env.app().getHashRouter());
-
3556 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
-
3557 BEAST_EXPECT(
-
3558 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
-
3559
-
3560 hash_set<NodeID> added;
-
3561 for (auto const& val : valKeys)
-
3562 {
-
3563 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
-
3564 added.insert(calcNodeID(val.masterPublic));
-
3565 }
-
3566 BEAST_EXPECT(changes.added == added);
-
3567 BEAST_EXPECT(changes.removed.empty());
-
3568
-
3569 // Expire one publisher - no quorum, only trusted validator is self
-
3570 env.timeKeeper().set(publishers.back().expiry);
-
3571 changes = trustedKeys->updateTrusted(
-
3572 activeValidators,
-
3573 env.timeKeeper().now(),
-
3574 env.app().getOPs(),
-
3575 env.app().overlay(),
-
3576 env.app().getHashRouter());
-
3577 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
-
3578 BEAST_EXPECT(trustedKeys->getTrustedMasterKeys().size() == 1);
-
3579
-
3580 hash_set<NodeID> removed;
-
3581 BEAST_EXPECT(trustedKeys->trusted(self.masterPublic));
-
3582 for (auto const& val : valKeys)
-
3583 {
-
3584 if (val.masterPublic != self.masterPublic)
-
3585 {
-
3586 BEAST_EXPECT(!trustedKeys->listed(val.masterPublic));
-
3587 BEAST_EXPECT(!trustedKeys->trusted(val.masterPublic));
-
3588 removed.insert(calcNodeID(val.masterPublic));
-
3589 }
-
3590 }
-
3591 BEAST_EXPECT(changes.added.empty());
-
3592 BEAST_EXPECT(changes.removed == removed);
-
3593 }
-
3594 {
-
3595 // List threshold = 1, 1 publisher revoked
-
3596 ManifestCache pubManifests;
-
3597 ManifestCache valManifests;
-
3598 std::vector<Publisher> publishers;
-
3599 auto const keysTotal = valKeys.size();
-
3600 auto trustedKeys = makeValidatorList(
-
3601 2, //
-
3602 1,
+
3536 1,
+
3537 pubManifests,
+
3538 valManifests,
+
3539 self,
+
3540 publishers);
+
3541 BEAST_EXPECT(trustedKeys->getListThreshold() == 1);
+
3542 int untrustedCount = 0;
+
3543 for (auto const& p : publishers)
+
3544 {
+
3545 bool const trusted = trustedKeys->trustedPublisher(p.pubKey);
+
3546 BEAST_EXPECT(p.revoked ^ trusted);
+
3547 untrustedCount += trusted ? 0 : 1;
+
3548 }
+
3549 BEAST_EXPECT(untrustedCount == 1);
+
3550
+
3551 TrustChanges changes = trustedKeys->updateTrusted(
+
3552 activeValidators,
+
3553 env.timeKeeper().now(),
+
3554 env.app().getOPs(),
+
3555 env.app().overlay(),
+
3556 env.app().getHashRouter());
+
3557 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
+
3558 BEAST_EXPECT(
+
3559 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
+
3560
+
3561 hash_set<NodeID> added;
+
3562 for (auto const& val : valKeys)
+
3563 {
+
3564 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
+
3565 added.insert(calcNodeID(val.masterPublic));
+
3566 }
+
3567 BEAST_EXPECT(changes.added == added);
+
3568 BEAST_EXPECT(changes.removed.empty());
+
3569
+
3570 // Expire one publisher - no quorum, only trusted validator is self
+
3571 env.timeKeeper().set(publishers.back().expiry);
+
3572 changes = trustedKeys->updateTrusted(
+
3573 activeValidators,
+
3574 env.timeKeeper().now(),
+
3575 env.app().getOPs(),
+
3576 env.app().overlay(),
+
3577 env.app().getHashRouter());
+
3578 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
+
3579 BEAST_EXPECT(trustedKeys->getTrustedMasterKeys().size() == 1);
+
3580
+
3581 hash_set<NodeID> removed;
+
3582 BEAST_EXPECT(trustedKeys->trusted(self.masterPublic));
+
3583 for (auto const& val : valKeys)
+
3584 {
+
3585 if (val.masterPublic != self.masterPublic)
+
3586 {
+
3587 BEAST_EXPECT(!trustedKeys->listed(val.masterPublic));
+
3588 BEAST_EXPECT(!trustedKeys->trusted(val.masterPublic));
+
3589 removed.insert(calcNodeID(val.masterPublic));
+
3590 }
+
3591 }
+
3592 BEAST_EXPECT(changes.added.empty());
+
3593 BEAST_EXPECT(changes.removed == removed);
+
3594 }
+
3595 {
+
3596 // List threshold = 1, 1 publisher revoked
+
3597 ManifestCache pubManifests;
+
3598 ManifestCache valManifests;
+
3599 std::vector<Publisher> publishers;
+
3600 auto const keysTotal = valKeys.size();
+
3601 auto trustedKeys = makeValidatorList(
+
3602 2, //
3603 1,
-
3604 pubManifests,
-
3605 valManifests,
-
3606 {},
-
3607 publishers);
-
3608 BEAST_EXPECT(trustedKeys->getListThreshold() == 1);
-
3609 int untrustedCount = 0;
-
3610 for (auto const& p : publishers)
-
3611 {
-
3612 bool const trusted = trustedKeys->trustedPublisher(p.pubKey);
-
3613 BEAST_EXPECT(p.revoked ^ trusted);
-
3614 untrustedCount += trusted ? 0 : 1;
-
3615 }
-
3616 BEAST_EXPECT(untrustedCount == 1);
-
3617
-
3618 TrustChanges changes = trustedKeys->updateTrusted(
-
3619 activeValidators,
-
3620 env.timeKeeper().now(),
-
3621 env.app().getOPs(),
-
3622 env.app().overlay(),
-
3623 env.app().getHashRouter());
-
3624 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
-
3625 BEAST_EXPECT(
-
3626 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
-
3627
-
3628 hash_set<NodeID> added;
-
3629 for (auto const& val : valKeys)
-
3630 {
-
3631 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
-
3632 added.insert(calcNodeID(val.masterPublic));
-
3633 }
-
3634 BEAST_EXPECT(changes.added == added);
-
3635 BEAST_EXPECT(changes.removed.empty());
-
3636
-
3637 // Expire one publisher - no quorum, no trusted validators
-
3638 env.timeKeeper().set(publishers.back().expiry);
-
3639 changes = trustedKeys->updateTrusted(
-
3640 activeValidators,
-
3641 env.timeKeeper().now(),
-
3642 env.app().getOPs(),
-
3643 env.app().overlay(),
-
3644 env.app().getHashRouter());
-
3645 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
-
3646 BEAST_EXPECT(trustedKeys->getTrustedMasterKeys().size() == 0);
-
3647
-
3648 hash_set<NodeID> removed;
-
3649 for (auto const& val : valKeys)
-
3650 {
-
3651 BEAST_EXPECT(!trustedKeys->listed(val.masterPublic));
-
3652 BEAST_EXPECT(!trustedKeys->trusted(val.masterPublic));
-
3653 removed.insert(calcNodeID(val.masterPublic));
-
3654 }
-
3655 BEAST_EXPECT(changes.added.empty());
-
3656 BEAST_EXPECT(changes.removed == removed);
-
3657 }
-
3658 {
-
3659 // List threshold = 2 (same as number of trusted publishers)
-
3660 ManifestCache pubManifests;
-
3661 ManifestCache valManifests;
-
3662 std::vector<Publisher> publishers;
-
3663 // Self is a random validator
-
3664 auto const self = randomValidator();
-
3665 auto const keysTotal = valKeys.size() + 1;
-
3666 auto trustedKeys = makeValidatorList(
-
3667 2, //
-
3668 0,
-
3669 2,
-
3670 pubManifests,
-
3671 valManifests,
-
3672 self,
-
3673 publishers);
-
3674 BEAST_EXPECT(trustedKeys->getListThreshold() == 2);
-
3675 for (auto const& p : publishers)
-
3676 BEAST_EXPECT(trustedKeys->trustedPublisher(p.pubKey));
-
3677
-
3678 TrustChanges changes = trustedKeys->updateTrusted(
-
3679 activeValidators,
-
3680 env.timeKeeper().now(),
-
3681 env.app().getOPs(),
-
3682 env.app().overlay(),
-
3683 env.app().getHashRouter());
-
3684 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
-
3685 BEAST_EXPECT(
-
3686 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
-
3687
-
3688 hash_set<NodeID> added;
-
3689 added.insert(calcNodeID(self.masterPublic));
-
3690 for (auto const& val : valKeys)
-
3691 {
-
3692 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
-
3693 added.insert(calcNodeID(val.masterPublic));
-
3694 }
-
3695 BEAST_EXPECT(changes.added == added);
-
3696 BEAST_EXPECT(changes.removed.empty());
-
3697
-
3698 // Expire one publisher - only trusted validator is self
-
3699 env.timeKeeper().set(publishers.back().expiry);
-
3700 changes = trustedKeys->updateTrusted(
-
3701 activeValidators,
-
3702 env.timeKeeper().now(),
-
3703 env.app().getOPs(),
-
3704 env.app().overlay(),
-
3705 env.app().getHashRouter());
-
3706 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
-
3707 BEAST_EXPECT(trustedKeys->getTrustedMasterKeys().size() == 1);
-
3708
-
3709 hash_set<NodeID> removed;
-
3710 BEAST_EXPECT(trustedKeys->trusted(self.masterPublic));
-
3711 for (auto const& val : valKeys)
-
3712 {
-
3713 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
-
3714 BEAST_EXPECT(!trustedKeys->trusted(val.masterPublic));
-
3715 removed.insert(calcNodeID(val.masterPublic));
-
3716 }
-
3717 BEAST_EXPECT(changes.added.empty());
-
3718 BEAST_EXPECT(changes.removed == removed);
-
3719 }
-
3720 {
-
3721 // List threshold = 2 (same as number of trusted publishers)
-
3722 ManifestCache pubManifests;
-
3723 ManifestCache valManifests;
-
3724 std::vector<Publisher> publishers;
-
3725 // Self is in UNL
-
3726 auto const self = valKeys[5];
-
3727 auto const keysTotal = valKeys.size();
-
3728 auto trustedKeys = makeValidatorList(
-
3729 2, //
-
3730 0,
-
3731 2,
-
3732 pubManifests,
-
3733 valManifests,
-
3734 self,
-
3735 publishers);
-
3736 BEAST_EXPECT(trustedKeys->getListThreshold() == 2);
-
3737 for (auto const& p : publishers)
-
3738 BEAST_EXPECT(trustedKeys->trustedPublisher(p.pubKey));
-
3739
-
3740 TrustChanges changes = trustedKeys->updateTrusted(
-
3741 activeValidators,
-
3742 env.timeKeeper().now(),
-
3743 env.app().getOPs(),
-
3744 env.app().overlay(),
-
3745 env.app().getHashRouter());
-
3746 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
-
3747 BEAST_EXPECT(
-
3748 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
-
3749
-
3750 hash_set<NodeID> added;
-
3751 added.insert(calcNodeID(self.masterPublic));
-
3752 for (auto const& val : valKeys)
-
3753 {
-
3754 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
-
3755 added.insert(calcNodeID(val.masterPublic));
-
3756 }
-
3757 BEAST_EXPECT(changes.added == added);
-
3758 BEAST_EXPECT(changes.removed.empty());
-
3759
-
3760 // Expire one publisher - only trusted validator is self
-
3761 env.timeKeeper().set(publishers.back().expiry);
-
3762 changes = trustedKeys->updateTrusted(
-
3763 activeValidators,
-
3764 env.timeKeeper().now(),
-
3765 env.app().getOPs(),
-
3766 env.app().overlay(),
-
3767 env.app().getHashRouter());
-
3768 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
-
3769 BEAST_EXPECT(trustedKeys->getTrustedMasterKeys().size() == 1);
-
3770
-
3771 hash_set<NodeID> removed;
-
3772 BEAST_EXPECT(trustedKeys->trusted(self.masterPublic));
-
3773 for (auto const& val : valKeys)
-
3774 {
-
3775 if (val.masterPublic != self.masterPublic)
-
3776 {
-
3777 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
-
3778 BEAST_EXPECT(!trustedKeys->trusted(val.masterPublic));
-
3779 removed.insert(calcNodeID(val.masterPublic));
-
3780 }
-
3781 }
-
3782 BEAST_EXPECT(changes.added.empty());
-
3783 BEAST_EXPECT(changes.removed == removed);
-
3784 }
-
3785 {
-
3786 // List threshold = 2 (same as number of trusted publishers)
-
3787 ManifestCache pubManifests;
-
3788 ManifestCache valManifests;
-
3789 std::vector<Publisher> publishers;
-
3790 auto const keysTotal = valKeys.size();
-
3791 auto trustedKeys = makeValidatorList(
-
3792 2, //
-
3793 0,
-
3794 2,
-
3795 pubManifests,
-
3796 valManifests,
-
3797 {},
-
3798 publishers);
-
3799 BEAST_EXPECT(trustedKeys->getListThreshold() == 2);
-
3800 for (auto const& p : publishers)
-
3801 BEAST_EXPECT(trustedKeys->trustedPublisher(p.pubKey));
-
3802
-
3803 TrustChanges changes = trustedKeys->updateTrusted(
-
3804 activeValidators,
-
3805 env.timeKeeper().now(),
-
3806 env.app().getOPs(),
-
3807 env.app().overlay(),
-
3808 env.app().getHashRouter());
-
3809 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
-
3810 BEAST_EXPECT(
-
3811 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
-
3812
-
3813 hash_set<NodeID> added;
-
3814 for (auto const& val : valKeys)
-
3815 {
-
3816 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
-
3817 added.insert(calcNodeID(val.masterPublic));
-
3818 }
-
3819 BEAST_EXPECT(changes.added == added);
-
3820 BEAST_EXPECT(changes.removed.empty());
-
3821
-
3822 // Expire one publisher - no trusted validators
-
3823 env.timeKeeper().set(publishers.back().expiry);
-
3824 changes = trustedKeys->updateTrusted(
-
3825 activeValidators,
-
3826 env.timeKeeper().now(),
-
3827 env.app().getOPs(),
-
3828 env.app().overlay(),
-
3829 env.app().getHashRouter());
-
3830 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
-
3831 BEAST_EXPECT(trustedKeys->getTrustedMasterKeys().size() == 0);
-
3832
-
3833 hash_set<NodeID> removed;
-
3834 for (auto const& val : valKeys)
-
3835 {
-
3836 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
-
3837 BEAST_EXPECT(!trustedKeys->trusted(val.masterPublic));
-
3838 removed.insert(calcNodeID(val.masterPublic));
-
3839 }
-
3840 BEAST_EXPECT(changes.added.empty());
-
3841 BEAST_EXPECT(changes.removed == removed);
-
3842 }
-
3843
-
3844 // Test case for 1 publisher
-
3845 {
-
3846 // List threshold = 1 (default), no publisher revoked
-
3847 ManifestCache pubManifests;
-
3848 ManifestCache valManifests;
-
3849 std::vector<Publisher> publishers;
-
3850 // Self is a random validator
-
3851 auto const self = randomValidator();
-
3852 auto const keysTotal = valKeys.size() + 1;
-
3853 auto trustedKeys = makeValidatorList(
-
3854 1, //
-
3855 0,
+
3604 1,
+
3605 pubManifests,
+
3606 valManifests,
+
3607 {},
+
3608 publishers);
+
3609 BEAST_EXPECT(trustedKeys->getListThreshold() == 1);
+
3610 int untrustedCount = 0;
+
3611 for (auto const& p : publishers)
+
3612 {
+
3613 bool const trusted = trustedKeys->trustedPublisher(p.pubKey);
+
3614 BEAST_EXPECT(p.revoked ^ trusted);
+
3615 untrustedCount += trusted ? 0 : 1;
+
3616 }
+
3617 BEAST_EXPECT(untrustedCount == 1);
+
3618
+
3619 TrustChanges changes = trustedKeys->updateTrusted(
+
3620 activeValidators,
+
3621 env.timeKeeper().now(),
+
3622 env.app().getOPs(),
+
3623 env.app().overlay(),
+
3624 env.app().getHashRouter());
+
3625 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
+
3626 BEAST_EXPECT(
+
3627 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
+
3628
+
3629 hash_set<NodeID> added;
+
3630 for (auto const& val : valKeys)
+
3631 {
+
3632 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
+
3633 added.insert(calcNodeID(val.masterPublic));
+
3634 }
+
3635 BEAST_EXPECT(changes.added == added);
+
3636 BEAST_EXPECT(changes.removed.empty());
+
3637
+
3638 // Expire one publisher - no quorum, no trusted validators
+
3639 env.timeKeeper().set(publishers.back().expiry);
+
3640 changes = trustedKeys->updateTrusted(
+
3641 activeValidators,
+
3642 env.timeKeeper().now(),
+
3643 env.app().getOPs(),
+
3644 env.app().overlay(),
+
3645 env.app().getHashRouter());
+
3646 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
+
3647 BEAST_EXPECT(trustedKeys->getTrustedMasterKeys().size() == 0);
+
3648
+
3649 hash_set<NodeID> removed;
+
3650 for (auto const& val : valKeys)
+
3651 {
+
3652 BEAST_EXPECT(!trustedKeys->listed(val.masterPublic));
+
3653 BEAST_EXPECT(!trustedKeys->trusted(val.masterPublic));
+
3654 removed.insert(calcNodeID(val.masterPublic));
+
3655 }
+
3656 BEAST_EXPECT(changes.added.empty());
+
3657 BEAST_EXPECT(changes.removed == removed);
+
3658 }
+
3659 {
+
3660 // List threshold = 2 (same as number of trusted publishers)
+
3661 ManifestCache pubManifests;
+
3662 ManifestCache valManifests;
+
3663 std::vector<Publisher> publishers;
+
3664 // Self is a random validator
+
3665 auto const self = randomValidator();
+
3666 auto const keysTotal = valKeys.size() + 1;
+
3667 auto trustedKeys = makeValidatorList(
+
3668 2, //
+
3669 0,
+
3670 2,
+
3671 pubManifests,
+
3672 valManifests,
+
3673 self,
+
3674 publishers);
+
3675 BEAST_EXPECT(trustedKeys->getListThreshold() == 2);
+
3676 for (auto const& p : publishers)
+
3677 BEAST_EXPECT(trustedKeys->trustedPublisher(p.pubKey));
+
3678
+
3679 TrustChanges changes = trustedKeys->updateTrusted(
+
3680 activeValidators,
+
3681 env.timeKeeper().now(),
+
3682 env.app().getOPs(),
+
3683 env.app().overlay(),
+
3684 env.app().getHashRouter());
+
3685 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
+
3686 BEAST_EXPECT(
+
3687 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
+
3688
+
3689 hash_set<NodeID> added;
+
3690 added.insert(calcNodeID(self.masterPublic));
+
3691 for (auto const& val : valKeys)
+
3692 {
+
3693 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
+
3694 added.insert(calcNodeID(val.masterPublic));
+
3695 }
+
3696 BEAST_EXPECT(changes.added == added);
+
3697 BEAST_EXPECT(changes.removed.empty());
+
3698
+
3699 // Expire one publisher - only trusted validator is self
+
3700 env.timeKeeper().set(publishers.back().expiry);
+
3701 changes = trustedKeys->updateTrusted(
+
3702 activeValidators,
+
3703 env.timeKeeper().now(),
+
3704 env.app().getOPs(),
+
3705 env.app().overlay(),
+
3706 env.app().getHashRouter());
+
3707 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
+
3708 BEAST_EXPECT(trustedKeys->getTrustedMasterKeys().size() == 1);
+
3709
+
3710 hash_set<NodeID> removed;
+
3711 BEAST_EXPECT(trustedKeys->trusted(self.masterPublic));
+
3712 for (auto const& val : valKeys)
+
3713 {
+
3714 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
+
3715 BEAST_EXPECT(!trustedKeys->trusted(val.masterPublic));
+
3716 removed.insert(calcNodeID(val.masterPublic));
+
3717 }
+
3718 BEAST_EXPECT(changes.added.empty());
+
3719 BEAST_EXPECT(changes.removed == removed);
+
3720 }
+
3721 {
+
3722 // List threshold = 2 (same as number of trusted publishers)
+
3723 ManifestCache pubManifests;
+
3724 ManifestCache valManifests;
+
3725 std::vector<Publisher> publishers;
+
3726 // Self is in UNL
+
3727 auto const self = valKeys[5];
+
3728 auto const keysTotal = valKeys.size();
+
3729 auto trustedKeys = makeValidatorList(
+
3730 2, //
+
3731 0,
+
3732 2,
+
3733 pubManifests,
+
3734 valManifests,
+
3735 self,
+
3736 publishers);
+
3737 BEAST_EXPECT(trustedKeys->getListThreshold() == 2);
+
3738 for (auto const& p : publishers)
+
3739 BEAST_EXPECT(trustedKeys->trustedPublisher(p.pubKey));
+
3740
+
3741 TrustChanges changes = trustedKeys->updateTrusted(
+
3742 activeValidators,
+
3743 env.timeKeeper().now(),
+
3744 env.app().getOPs(),
+
3745 env.app().overlay(),
+
3746 env.app().getHashRouter());
+
3747 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
+
3748 BEAST_EXPECT(
+
3749 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
+
3750
+
3751 hash_set<NodeID> added;
+
3752 added.insert(calcNodeID(self.masterPublic));
+
3753 for (auto const& val : valKeys)
+
3754 {
+
3755 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
+
3756 added.insert(calcNodeID(val.masterPublic));
+
3757 }
+
3758 BEAST_EXPECT(changes.added == added);
+
3759 BEAST_EXPECT(changes.removed.empty());
+
3760
+
3761 // Expire one publisher - only trusted validator is self
+
3762 env.timeKeeper().set(publishers.back().expiry);
+
3763 changes = trustedKeys->updateTrusted(
+
3764 activeValidators,
+
3765 env.timeKeeper().now(),
+
3766 env.app().getOPs(),
+
3767 env.app().overlay(),
+
3768 env.app().getHashRouter());
+
3769 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
+
3770 BEAST_EXPECT(trustedKeys->getTrustedMasterKeys().size() == 1);
+
3771
+
3772 hash_set<NodeID> removed;
+
3773 BEAST_EXPECT(trustedKeys->trusted(self.masterPublic));
+
3774 for (auto const& val : valKeys)
+
3775 {
+
3776 if (val.masterPublic != self.masterPublic)
+
3777 {
+
3778 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
+
3779 BEAST_EXPECT(!trustedKeys->trusted(val.masterPublic));
+
3780 removed.insert(calcNodeID(val.masterPublic));
+
3781 }
+
3782 }
+
3783 BEAST_EXPECT(changes.added.empty());
+
3784 BEAST_EXPECT(changes.removed == removed);
+
3785 }
+
3786 {
+
3787 // List threshold = 2 (same as number of trusted publishers)
+
3788 ManifestCache pubManifests;
+
3789 ManifestCache valManifests;
+
3790 std::vector<Publisher> publishers;
+
3791 auto const keysTotal = valKeys.size();
+
3792 auto trustedKeys = makeValidatorList(
+
3793 2, //
+
3794 0,
+
3795 2,
+
3796 pubManifests,
+
3797 valManifests,
+
3798 {},
+
3799 publishers);
+
3800 BEAST_EXPECT(trustedKeys->getListThreshold() == 2);
+
3801 for (auto const& p : publishers)
+
3802 BEAST_EXPECT(trustedKeys->trustedPublisher(p.pubKey));
+
3803
+
3804 TrustChanges changes = trustedKeys->updateTrusted(
+
3805 activeValidators,
+
3806 env.timeKeeper().now(),
+
3807 env.app().getOPs(),
+
3808 env.app().overlay(),
+
3809 env.app().getHashRouter());
+
3810 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
+
3811 BEAST_EXPECT(
+
3812 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
+
3813
+
3814 hash_set<NodeID> added;
+
3815 for (auto const& val : valKeys)
+
3816 {
+
3817 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
+
3818 added.insert(calcNodeID(val.masterPublic));
+
3819 }
+
3820 BEAST_EXPECT(changes.added == added);
+
3821 BEAST_EXPECT(changes.removed.empty());
+
3822
+
3823 // Expire one publisher - no trusted validators
+
3824 env.timeKeeper().set(publishers.back().expiry);
+
3825 changes = trustedKeys->updateTrusted(
+
3826 activeValidators,
+
3827 env.timeKeeper().now(),
+
3828 env.app().getOPs(),
+
3829 env.app().overlay(),
+
3830 env.app().getHashRouter());
+
3831 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
+
3832 BEAST_EXPECT(trustedKeys->getTrustedMasterKeys().size() == 0);
+
3833
+
3834 hash_set<NodeID> removed;
+
3835 for (auto const& val : valKeys)
+
3836 {
+
3837 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
+
3838 BEAST_EXPECT(!trustedKeys->trusted(val.masterPublic));
+
3839 removed.insert(calcNodeID(val.masterPublic));
+
3840 }
+
3841 BEAST_EXPECT(changes.added.empty());
+
3842 BEAST_EXPECT(changes.removed == removed);
+
3843 }
+
3844
+
3845 // Test case for 1 publisher
+
3846 {
+
3847 // List threshold = 1 (default), no publisher revoked
+
3848 ManifestCache pubManifests;
+
3849 ManifestCache valManifests;
+
3850 std::vector<Publisher> publishers;
+
3851 // Self is a random validator
+
3852 auto const self = randomValidator();
+
3853 auto const keysTotal = valKeys.size() + 1;
+
3854 auto trustedKeys = makeValidatorList(
+
3855 1, //
3856 0,
-
3857 pubManifests,
-
3858 valManifests,
-
3859 self,
-
3860 publishers);
-
3861 BEAST_EXPECT(trustedKeys->getListThreshold() == 1);
-
3862 for (auto const& p : publishers)
-
3863 BEAST_EXPECT(trustedKeys->trustedPublisher(p.pubKey));
-
3864
-
3865 TrustChanges changes = trustedKeys->updateTrusted(
-
3866 activeValidators,
-
3867 env.timeKeeper().now(),
-
3868 env.app().getOPs(),
-
3869 env.app().overlay(),
-
3870 env.app().getHashRouter());
-
3871 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
-
3872 BEAST_EXPECT(
-
3873 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
-
3874
-
3875 hash_set<NodeID> added;
-
3876 added.insert(calcNodeID(self.masterPublic));
-
3877 for (auto const& val : valKeys)
-
3878 {
-
3879 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
-
3880 added.insert(calcNodeID(val.masterPublic));
-
3881 }
-
3882 BEAST_EXPECT(changes.added == added);
-
3883 BEAST_EXPECT(changes.removed.empty());
-
3884
-
3885 // Expire one publisher - no quorum, only trusted validator is self
-
3886 env.timeKeeper().set(publishers.back().expiry);
-
3887 changes = trustedKeys->updateTrusted(
-
3888 activeValidators,
-
3889 env.timeKeeper().now(),
-
3890 env.app().getOPs(),
-
3891 env.app().overlay(),
-
3892 env.app().getHashRouter());
-
3893 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
-
3894 BEAST_EXPECT(trustedKeys->getTrustedMasterKeys().size() == 1);
-
3895
-
3896 hash_set<NodeID> removed;
-
3897 BEAST_EXPECT(trustedKeys->trusted(self.masterPublic));
-
3898 for (auto const& val : valKeys)
-
3899 {
-
3900 BEAST_EXPECT(!trustedKeys->listed(val.masterPublic));
-
3901 BEAST_EXPECT(!trustedKeys->trusted(val.masterPublic));
-
3902 removed.insert(calcNodeID(val.masterPublic));
-
3903 }
-
3904 BEAST_EXPECT(changes.added.empty());
-
3905 BEAST_EXPECT(changes.removed == removed);
-
3906 }
-
3907
-
3908 // Test case for 3 publishers (for 2 is a block above)
-
3909 {
-
3910 // List threshold = 2 (default), no publisher revoked
-
3911 ManifestCache pubManifests;
-
3912 ManifestCache valManifests;
-
3913 std::vector<Publisher> publishers;
-
3914 // Self is in UNL
-
3915 auto const self = valKeys[2];
-
3916 auto const keysTotal = valKeys.size();
-
3917 auto trustedKeys = makeValidatorList(
-
3918 3, //
-
3919 0,
+
3857 0,
+
3858 pubManifests,
+
3859 valManifests,
+
3860 self,
+
3861 publishers);
+
3862 BEAST_EXPECT(trustedKeys->getListThreshold() == 1);
+
3863 for (auto const& p : publishers)
+
3864 BEAST_EXPECT(trustedKeys->trustedPublisher(p.pubKey));
+
3865
+
3866 TrustChanges changes = trustedKeys->updateTrusted(
+
3867 activeValidators,
+
3868 env.timeKeeper().now(),
+
3869 env.app().getOPs(),
+
3870 env.app().overlay(),
+
3871 env.app().getHashRouter());
+
3872 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
+
3873 BEAST_EXPECT(
+
3874 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
+
3875
+
3876 hash_set<NodeID> added;
+
3877 added.insert(calcNodeID(self.masterPublic));
+
3878 for (auto const& val : valKeys)
+
3879 {
+
3880 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
+
3881 added.insert(calcNodeID(val.masterPublic));
+
3882 }
+
3883 BEAST_EXPECT(changes.added == added);
+
3884 BEAST_EXPECT(changes.removed.empty());
+
3885
+
3886 // Expire one publisher - no quorum, only trusted validator is self
+
3887 env.timeKeeper().set(publishers.back().expiry);
+
3888 changes = trustedKeys->updateTrusted(
+
3889 activeValidators,
+
3890 env.timeKeeper().now(),
+
3891 env.app().getOPs(),
+
3892 env.app().overlay(),
+
3893 env.app().getHashRouter());
+
3894 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
+
3895 BEAST_EXPECT(trustedKeys->getTrustedMasterKeys().size() == 1);
+
3896
+
3897 hash_set<NodeID> removed;
+
3898 BEAST_EXPECT(trustedKeys->trusted(self.masterPublic));
+
3899 for (auto const& val : valKeys)
+
3900 {
+
3901 BEAST_EXPECT(!trustedKeys->listed(val.masterPublic));
+
3902 BEAST_EXPECT(!trustedKeys->trusted(val.masterPublic));
+
3903 removed.insert(calcNodeID(val.masterPublic));
+
3904 }
+
3905 BEAST_EXPECT(changes.added.empty());
+
3906 BEAST_EXPECT(changes.removed == removed);
+
3907 }
+
3908
+
3909 // Test case for 3 publishers (for 2 is a block above)
+
3910 {
+
3911 // List threshold = 2 (default), no publisher revoked
+
3912 ManifestCache pubManifests;
+
3913 ManifestCache valManifests;
+
3914 std::vector<Publisher> publishers;
+
3915 // Self is in UNL
+
3916 auto const self = valKeys[2];
+
3917 auto const keysTotal = valKeys.size();
+
3918 auto trustedKeys = makeValidatorList(
+
3919 3, //
3920 0,
-
3921 pubManifests,
-
3922 valManifests,
-
3923 self,
-
3924 publishers);
-
3925 BEAST_EXPECT(trustedKeys->getListThreshold() == 2);
-
3926 for (auto const& p : publishers)
-
3927 BEAST_EXPECT(trustedKeys->trustedPublisher(p.pubKey));
-
3928
-
3929 TrustChanges changes = trustedKeys->updateTrusted(
-
3930 activeValidators,
-
3931 env.timeKeeper().now(),
-
3932 env.app().getOPs(),
-
3933 env.app().overlay(),
-
3934 env.app().getHashRouter());
-
3935 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
-
3936 BEAST_EXPECT(
-
3937 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
-
3938
-
3939 hash_set<NodeID> added;
-
3940 for (auto const& val : valKeys)
-
3941 {
-
3942 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
-
3943 added.insert(calcNodeID(val.masterPublic));
-
3944 }
-
3945 BEAST_EXPECT(changes.added == added);
-
3946 BEAST_EXPECT(changes.removed.empty());
-
3947 }
-
3948
-
3949 // Test case for 4 publishers
-
3950 {
-
3951 // List threshold = 3 (default), no publisher revoked
-
3952 ManifestCache pubManifests;
-
3953 ManifestCache valManifests;
-
3954 std::vector<Publisher> publishers;
-
3955 auto const keysTotal = valKeys.size();
-
3956 auto trustedKeys = makeValidatorList(
-
3957 4, //
-
3958 0,
+
3921 0,
+
3922 pubManifests,
+
3923 valManifests,
+
3924 self,
+
3925 publishers);
+
3926 BEAST_EXPECT(trustedKeys->getListThreshold() == 2);
+
3927 for (auto const& p : publishers)
+
3928 BEAST_EXPECT(trustedKeys->trustedPublisher(p.pubKey));
+
3929
+
3930 TrustChanges changes = trustedKeys->updateTrusted(
+
3931 activeValidators,
+
3932 env.timeKeeper().now(),
+
3933 env.app().getOPs(),
+
3934 env.app().overlay(),
+
3935 env.app().getHashRouter());
+
3936 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
+
3937 BEAST_EXPECT(
+
3938 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
+
3939
+
3940 hash_set<NodeID> added;
+
3941 for (auto const& val : valKeys)
+
3942 {
+
3943 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
+
3944 added.insert(calcNodeID(val.masterPublic));
+
3945 }
+
3946 BEAST_EXPECT(changes.added == added);
+
3947 BEAST_EXPECT(changes.removed.empty());
+
3948 }
+
3949
+
3950 // Test case for 4 publishers
+
3951 {
+
3952 // List threshold = 3 (default), no publisher revoked
+
3953 ManifestCache pubManifests;
+
3954 ManifestCache valManifests;
+
3955 std::vector<Publisher> publishers;
+
3956 auto const keysTotal = valKeys.size();
+
3957 auto trustedKeys = makeValidatorList(
+
3958 4, //
3959 0,
-
3960 pubManifests,
-
3961 valManifests,
-
3962 {},
-
3963 publishers);
-
3964 BEAST_EXPECT(trustedKeys->getListThreshold() == 3);
-
3965 for (auto const& p : publishers)
-
3966 BEAST_EXPECT(trustedKeys->trustedPublisher(p.pubKey));
-
3967
-
3968 TrustChanges changes = trustedKeys->updateTrusted(
-
3969 activeValidators,
-
3970 env.timeKeeper().now(),
-
3971 env.app().getOPs(),
-
3972 env.app().overlay(),
-
3973 env.app().getHashRouter());
-
3974 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
-
3975 BEAST_EXPECT(
-
3976 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
-
3977
-
3978 hash_set<NodeID> added;
-
3979 for (auto const& val : valKeys)
-
3980 {
-
3981 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
-
3982 added.insert(calcNodeID(val.masterPublic));
-
3983 }
-
3984 BEAST_EXPECT(changes.added == added);
-
3985 BEAST_EXPECT(changes.removed.empty());
-
3986 }
-
3987
-
3988 // Test case for 6 publishers (for 5 is a large block above)
-
3989 {
-
3990 // List threshold = 4 (default), 2 publishers revoked
-
3991 ManifestCache pubManifests;
-
3992 ManifestCache valManifests;
-
3993 std::vector<Publisher> publishers;
-
3994 // Self is a random validator
-
3995 auto const self = randomValidator();
-
3996 auto const keysTotal = valKeys.size() + 1;
-
3997 auto trustedKeys = makeValidatorList(
-
3998 6, //
-
3999 2,
-
4000 0,
-
4001 pubManifests,
-
4002 valManifests,
-
4003 self,
-
4004 publishers);
-
4005 BEAST_EXPECT(trustedKeys->getListThreshold() == 4);
-
4006 int untrustedCount = 0;
-
4007 for (auto const& p : publishers)
-
4008 {
-
4009 bool const trusted = trustedKeys->trustedPublisher(p.pubKey);
-
4010 BEAST_EXPECT(p.revoked ^ trusted);
-
4011 untrustedCount += trusted ? 0 : 1;
-
4012 }
-
4013 BEAST_EXPECT(untrustedCount == 2);
-
4014
-
4015 TrustChanges changes = trustedKeys->updateTrusted(
-
4016 activeValidators,
-
4017 env.timeKeeper().now(),
-
4018 env.app().getOPs(),
-
4019 env.app().overlay(),
-
4020 env.app().getHashRouter());
-
4021 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
-
4022 BEAST_EXPECT(
-
4023 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
-
4024
-
4025 hash_set<NodeID> added;
-
4026 added.insert(calcNodeID(self.masterPublic));
-
4027 for (auto const& val : valKeys)
-
4028 {
-
4029 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
-
4030 added.insert(calcNodeID(val.masterPublic));
-
4031 }
-
4032 BEAST_EXPECT(changes.added == added);
-
4033 BEAST_EXPECT(changes.removed.empty());
-
4034
-
4035 // Expire one publisher - no quorum, only trusted validator is self
-
4036 env.timeKeeper().set(publishers.back().expiry);
-
4037 changes = trustedKeys->updateTrusted(
-
4038 activeValidators,
-
4039 env.timeKeeper().now(),
-
4040 env.app().getOPs(),
-
4041 env.app().overlay(),
-
4042 env.app().getHashRouter());
-
4043 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
-
4044 BEAST_EXPECT(trustedKeys->getTrustedMasterKeys().size() == 1);
-
4045
-
4046 hash_set<NodeID> removed;
-
4047 BEAST_EXPECT(trustedKeys->trusted(self.masterPublic));
-
4048 for (auto const& val : valKeys)
-
4049 {
-
4050 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
-
4051 BEAST_EXPECT(!trustedKeys->trusted(val.masterPublic));
-
4052 removed.insert(calcNodeID(val.masterPublic));
-
4053 }
-
4054 BEAST_EXPECT(changes.added.empty());
-
4055 BEAST_EXPECT(changes.removed == removed);
-
4056 }
-
4057
-
4058 // Test case for 7 publishers
-
4059 {
-
4060 // List threshold = 4 (default), 3 publishers revoked
-
4061 ManifestCache pubManifests;
-
4062 ManifestCache valManifests;
-
4063 std::vector<Publisher> publishers;
-
4064 // Self is in UNL
-
4065 auto const self = valKeys[2];
-
4066 auto const keysTotal = valKeys.size();
-
4067 auto trustedKeys = makeValidatorList(
-
4068 7, //
-
4069 3,
-
4070 0,
-
4071 pubManifests,
-
4072 valManifests,
-
4073 self,
-
4074 publishers);
-
4075 BEAST_EXPECT(trustedKeys->getListThreshold() == 4);
-
4076 int untrustedCount = 0;
-
4077 for (auto const& p : publishers)
-
4078 {
-
4079 bool const trusted = trustedKeys->trustedPublisher(p.pubKey);
-
4080 BEAST_EXPECT(p.revoked ^ trusted);
-
4081 untrustedCount += trusted ? 0 : 1;
-
4082 }
-
4083 BEAST_EXPECT(untrustedCount == 3);
-
4084
-
4085 TrustChanges changes = trustedKeys->updateTrusted(
-
4086 activeValidators,
-
4087 env.timeKeeper().now(),
-
4088 env.app().getOPs(),
-
4089 env.app().overlay(),
-
4090 env.app().getHashRouter());
-
4091 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
-
4092 BEAST_EXPECT(
-
4093 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
-
4094
-
4095 hash_set<NodeID> added;
-
4096 for (auto const& val : valKeys)
-
4097 {
-
4098 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
-
4099 added.insert(calcNodeID(val.masterPublic));
-
4100 }
-
4101 BEAST_EXPECT(changes.added == added);
-
4102 BEAST_EXPECT(changes.removed.empty());
-
4103
-
4104 // Expire one publisher - only trusted validator is self
-
4105 env.timeKeeper().set(publishers.back().expiry);
-
4106 changes = trustedKeys->updateTrusted(
-
4107 activeValidators,
-
4108 env.timeKeeper().now(),
-
4109 env.app().getOPs(),
-
4110 env.app().overlay(),
-
4111 env.app().getHashRouter());
-
4112 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
-
4113 BEAST_EXPECT(trustedKeys->getTrustedMasterKeys().size() == 1);
-
4114
-
4115 hash_set<NodeID> removed;
-
4116 BEAST_EXPECT(trustedKeys->trusted(self.masterPublic));
-
4117 for (auto const& val : valKeys)
-
4118 {
-
4119 if (val.masterPublic != self.masterPublic)
-
4120 {
-
4121 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
-
4122 BEAST_EXPECT(!trustedKeys->trusted(val.masterPublic));
-
4123 removed.insert(calcNodeID(val.masterPublic));
-
4124 }
-
4125 }
-
4126 BEAST_EXPECT(changes.added.empty());
-
4127 BEAST_EXPECT(changes.removed == removed);
-
4128 }
-
4129 }
+
3960 0,
+
3961 pubManifests,
+
3962 valManifests,
+
3963 {},
+
3964 publishers);
+
3965 BEAST_EXPECT(trustedKeys->getListThreshold() == 3);
+
3966 for (auto const& p : publishers)
+
3967 BEAST_EXPECT(trustedKeys->trustedPublisher(p.pubKey));
+
3968
+
3969 TrustChanges changes = trustedKeys->updateTrusted(
+
3970 activeValidators,
+
3971 env.timeKeeper().now(),
+
3972 env.app().getOPs(),
+
3973 env.app().overlay(),
+
3974 env.app().getHashRouter());
+
3975 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
+
3976 BEAST_EXPECT(
+
3977 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
+
3978
+
3979 hash_set<NodeID> added;
+
3980 for (auto const& val : valKeys)
+
3981 {
+
3982 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
+
3983 added.insert(calcNodeID(val.masterPublic));
+
3984 }
+
3985 BEAST_EXPECT(changes.added == added);
+
3986 BEAST_EXPECT(changes.removed.empty());
+
3987 }
+
3988
+
3989 // Test case for 6 publishers (for 5 is a large block above)
+
3990 {
+
3991 // List threshold = 4 (default), 2 publishers revoked
+
3992 ManifestCache pubManifests;
+
3993 ManifestCache valManifests;
+
3994 std::vector<Publisher> publishers;
+
3995 // Self is a random validator
+
3996 auto const self = randomValidator();
+
3997 auto const keysTotal = valKeys.size() + 1;
+
3998 auto trustedKeys = makeValidatorList(
+
3999 6, //
+
4000 2,
+
4001 0,
+
4002 pubManifests,
+
4003 valManifests,
+
4004 self,
+
4005 publishers);
+
4006 BEAST_EXPECT(trustedKeys->getListThreshold() == 4);
+
4007 int untrustedCount = 0;
+
4008 for (auto const& p : publishers)
+
4009 {
+
4010 bool const trusted = trustedKeys->trustedPublisher(p.pubKey);
+
4011 BEAST_EXPECT(p.revoked ^ trusted);
+
4012 untrustedCount += trusted ? 0 : 1;
+
4013 }
+
4014 BEAST_EXPECT(untrustedCount == 2);
+
4015
+
4016 TrustChanges changes = trustedKeys->updateTrusted(
+
4017 activeValidators,
+
4018 env.timeKeeper().now(),
+
4019 env.app().getOPs(),
+
4020 env.app().overlay(),
+
4021 env.app().getHashRouter());
+
4022 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
+
4023 BEAST_EXPECT(
+
4024 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
+
4025
+
4026 hash_set<NodeID> added;
+
4027 added.insert(calcNodeID(self.masterPublic));
+
4028 for (auto const& val : valKeys)
+
4029 {
+
4030 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
+
4031 added.insert(calcNodeID(val.masterPublic));
+
4032 }
+
4033 BEAST_EXPECT(changes.added == added);
+
4034 BEAST_EXPECT(changes.removed.empty());
+
4035
+
4036 // Expire one publisher - no quorum, only trusted validator is self
+
4037 env.timeKeeper().set(publishers.back().expiry);
+
4038 changes = trustedKeys->updateTrusted(
+
4039 activeValidators,
+
4040 env.timeKeeper().now(),
+
4041 env.app().getOPs(),
+
4042 env.app().overlay(),
+
4043 env.app().getHashRouter());
+
4044 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
+
4045 BEAST_EXPECT(trustedKeys->getTrustedMasterKeys().size() == 1);
+
4046
+
4047 hash_set<NodeID> removed;
+
4048 BEAST_EXPECT(trustedKeys->trusted(self.masterPublic));
+
4049 for (auto const& val : valKeys)
+
4050 {
+
4051 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
+
4052 BEAST_EXPECT(!trustedKeys->trusted(val.masterPublic));
+
4053 removed.insert(calcNodeID(val.masterPublic));
+
4054 }
+
4055 BEAST_EXPECT(changes.added.empty());
+
4056 BEAST_EXPECT(changes.removed == removed);
+
4057 }
+
4058
+
4059 // Test case for 7 publishers
+
4060 {
+
4061 // List threshold = 4 (default), 3 publishers revoked
+
4062 ManifestCache pubManifests;
+
4063 ManifestCache valManifests;
+
4064 std::vector<Publisher> publishers;
+
4065 // Self is in UNL
+
4066 auto const self = valKeys[2];
+
4067 auto const keysTotal = valKeys.size();
+
4068 auto trustedKeys = makeValidatorList(
+
4069 7, //
+
4070 3,
+
4071 0,
+
4072 pubManifests,
+
4073 valManifests,
+
4074 self,
+
4075 publishers);
+
4076 BEAST_EXPECT(trustedKeys->getListThreshold() == 4);
+
4077 int untrustedCount = 0;
+
4078 for (auto const& p : publishers)
+
4079 {
+
4080 bool const trusted = trustedKeys->trustedPublisher(p.pubKey);
+
4081 BEAST_EXPECT(p.revoked ^ trusted);
+
4082 untrustedCount += trusted ? 0 : 1;
+
4083 }
+
4084 BEAST_EXPECT(untrustedCount == 3);
+
4085
+
4086 TrustChanges changes = trustedKeys->updateTrusted(
+
4087 activeValidators,
+
4088 env.timeKeeper().now(),
+
4089 env.app().getOPs(),
+
4090 env.app().overlay(),
+
4091 env.app().getHashRouter());
+
4092 BEAST_EXPECT(trustedKeys->quorum() == std::ceil(keysTotal * 0.8f));
+
4093 BEAST_EXPECT(
+
4094 trustedKeys->getTrustedMasterKeys().size() == keysTotal);
+
4095
+
4096 hash_set<NodeID> added;
+
4097 for (auto const& val : valKeys)
+
4098 {
+
4099 BEAST_EXPECT(trustedKeys->trusted(val.masterPublic));
+
4100 added.insert(calcNodeID(val.masterPublic));
+
4101 }
+
4102 BEAST_EXPECT(changes.added == added);
+
4103 BEAST_EXPECT(changes.removed.empty());
+
4104
+
4105 // Expire one publisher - only trusted validator is self
+
4106 env.timeKeeper().set(publishers.back().expiry);
+
4107 changes = trustedKeys->updateTrusted(
+
4108 activeValidators,
+
4109 env.timeKeeper().now(),
+
4110 env.app().getOPs(),
+
4111 env.app().overlay(),
+
4112 env.app().getHashRouter());
+
4113 BEAST_EXPECT(trustedKeys->quorum() == quorumDisabled);
+
4114 BEAST_EXPECT(trustedKeys->getTrustedMasterKeys().size() == 1);
+
4115
+
4116 hash_set<NodeID> removed;
+
4117 BEAST_EXPECT(trustedKeys->trusted(self.masterPublic));
+
4118 for (auto const& val : valKeys)
+
4119 {
+
4120 if (val.masterPublic != self.masterPublic)
+
4121 {
+
4122 BEAST_EXPECT(trustedKeys->listed(val.masterPublic));
+
4123 BEAST_EXPECT(!trustedKeys->trusted(val.masterPublic));
+
4124 removed.insert(calcNodeID(val.masterPublic));
+
4125 }
+
4126 }
+
4127 BEAST_EXPECT(changes.added.empty());
+
4128 BEAST_EXPECT(changes.removed == removed);
+
4129 }
+
4130 }
-
4130
-
4131public:
-
4132 void
-
-
4133 run() override
-
4134 {
-
4135 testGenesisQuorum();
-
4136 testConfigLoad();
-
4137 testApplyLists();
-
4138 testGetAvailable();
-
4139 testUpdateTrusted();
-
4140 testExpires();
-
4141 testNegativeUNL();
-
4142 testSha512Hash();
-
4143 testBuildMessages();
-
4144 testQuorumDisabled();
-
4145 }
+
4131
+
4132public:
+
4133 void
+
+
4134 run() override
+
4135 {
+
4136 testGenesisQuorum();
+
4137 testConfigLoad();
+
4138 testApplyLists();
+
4139 testGetAvailable();
+
4140 testUpdateTrusted();
+
4141 testExpires();
+
4142 testNegativeUNL();
+
4143 testSha512Hash();
+
4144 testBuildMessages();
+
4145 testQuorumDisabled();
+
4146 }
-
4146}; // namespace test
+
4147}; // namespace test
-
4147
-
4148BEAST_DEFINE_TESTSUITE(ValidatorList, app, xrpl);
-
4149
-
4150} // namespace test
-
4151} // namespace xrpl
+
4148
+
4149BEAST_DEFINE_TESTSUITE(ValidatorList, app, xrpl);
+
4150
+
4151} // namespace test
+
4152} // namespace xrpl
T at(T... args)
T back(T... args)
@@ -4316,7 +4317,7 @@ $(document).ready(function() { init_codefold(0); });
std::string signList(std::string const &blob, std::pair< PublicKey, SecretKey > const &keys)
static std::string makeRevocationString(PublicKey const &pk, SecretKey const &sk)
- +
static hash_set< NodeID > asNodeIDs(std::initializer_list< PublicKey > const &pks)
@@ -4326,7 +4327,7 @@ $(document).ready(function() { init_codefold(0); });
void checkResult(ValidatorList::PublisherListStats const &result, PublicKey pubKey, ListDisposition expectedWorst, ListDisposition expectedBest)
-
void run() override
Runs the suite.
+
void run() override
Runs the suite.
static std::string makeManifestString(PublicKey const &pk, SecretKey const &sk, PublicKey const &spk, SecretKey const &ssk, int seq)
diff --git a/ValidatorSite_8cpp_source.html b/ValidatorSite_8cpp_source.html index 3ab16a0793..b793e8e19e 100644 --- a/ValidatorSite_8cpp_source.html +++ b/ValidatorSite_8cpp_source.html @@ -832,9 +832,9 @@ $(document).ready(function() { init_codefold(0); });
virtual Overlay & overlay()=0
virtual ValidatorList & validators()=0
virtual NetworkOPs & getOPs()=0
-
std::vector< std::string > loadLists()
+
std::vector< std::string > loadLists()
static std::vector< ValidatorBlobInfo > parseBlobs(std::uint32_t version, Json::Value const &body)
Pull the blob/signature/manifest information out of the appropriate Json body fields depending on the...
-
PublisherListStats applyListsAndBroadcast(std::string const &manifest, std::uint32_t version, std::vector< ValidatorBlobInfo > const &blobs, std::string siteUri, uint256 const &hash, Overlay &overlay, HashRouter &hashRouter, NetworkOPs &networkOPs)
Apply multiple published lists of public keys, then broadcast it to all peers that have not seen it o...
+
PublisherListStats applyListsAndBroadcast(std::string const &manifest, std::uint32_t version, std::vector< ValidatorBlobInfo > const &blobs, std::string siteUri, uint256 const &hash, Overlay &overlay, HashRouter &hashRouter, NetworkOPs &networkOPs)
Apply multiple published lists of public keys, then broadcast it to all peers that have not seen it o...
void onRequestTimeout(std::size_t siteIdx, error_code const &ec)
request took too long
void setTimer(std::lock_guard< std::mutex > const &, std::lock_guard< std::mutex > const &)
Queue next site to be fetched lock over site_mutex_ and state_mutex_ required.
diff --git a/Validators_8cpp_source.html b/Validators_8cpp_source.html index 33366b077e..bf6c317668 100644 --- a/Validators_8cpp_source.html +++ b/Validators_8cpp_source.html @@ -100,7 +100,7 @@ $(document).ready(function() { init_codefold(0); });
15} // namespace xrpl
Represents a JSON value.
Definition json_value.h:131
virtual ValidatorList & validators()=0
-
Json::Value getJson() const
Return a JSON representation of the state of the validator list.
+
Json::Value getJson() const
Return a JSON representation of the state of the validator list.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
Json::Value doValidators(RPC::JsonContext &)
Application & app
Definition Context.h:22
diff --git a/classxrpl_1_1ValidatorList.html b/classxrpl_1_1ValidatorList.html index 13fdd5f2b8..b10fcbac82 100644 --- a/classxrpl_1_1ValidatorList.html +++ b/classxrpl_1_1ValidatorList.html @@ -804,7 +804,7 @@ Trusted Validators List
-

Definition at line 797 of file ValidatorList.cpp.

+

Definition at line 798 of file ValidatorList.cpp.

@@ -878,7 +878,7 @@ Trusted Validators List
-

Definition at line 653 of file ValidatorList.cpp.

+

Definition at line 654 of file ValidatorList.cpp.

@@ -962,7 +962,7 @@ Trusted Validators List
Thread Safety

May be called concurrently

-

Definition at line 918 of file ValidatorList.cpp.

+

Definition at line 919 of file ValidatorList.cpp.

@@ -1025,7 +1025,7 @@ Trusted Validators List
Thread Safety

May be called concurrently

-

Definition at line 976 of file ValidatorList.cpp.

+

Definition at line 977 of file ValidatorList.cpp.

@@ -1044,7 +1044,7 @@ Trusted Validators List
-

Definition at line 1292 of file ValidatorList.cpp.

+

Definition at line 1293 of file ValidatorList.cpp.

@@ -1104,7 +1104,7 @@ Trusted Validators List
Thread Safety

May be called concurrently

-

Definition at line 1900 of file ValidatorList.cpp.

+

Definition at line 1901 of file ValidatorList.cpp.

@@ -1159,7 +1159,7 @@ Trusted Validators List
Thread Safety

May be called concurrently

-

Definition at line 1450 of file ValidatorList.cpp.

+

Definition at line 1451 of file ValidatorList.cpp.

@@ -1189,7 +1189,7 @@ Trusted Validators List
Thread Safety

May be called concurrently

-

Definition at line 1432 of file ValidatorList.cpp.

+

Definition at line 1433 of file ValidatorList.cpp.

@@ -1220,7 +1220,7 @@ Trusted Validators List
Thread Safety

May be called concurrently

-

Definition at line 1479 of file ValidatorList.cpp.

+

Definition at line 1480 of file ValidatorList.cpp.

@@ -1251,7 +1251,7 @@ Trusted Validators List
Thread Safety

May be called concurrently

-

Definition at line 1457 of file ValidatorList.cpp.

+

Definition at line 1458 of file ValidatorList.cpp.

@@ -1281,7 +1281,7 @@ Trusted Validators List
Thread Safety

May be called concurrently

-

Definition at line 1487 of file ValidatorList.cpp.

+

Definition at line 1488 of file ValidatorList.cpp.

@@ -1304,7 +1304,7 @@ Trusted Validators List
Thread Safety

May be called concurrently

-

Definition at line 1495 of file ValidatorList.cpp.

+

Definition at line 1496 of file ValidatorList.cpp.

@@ -1336,7 +1336,7 @@ Trusted Validators List
Thread Safety

May be called concurrently

-

Definition at line 1739 of file ValidatorList.cpp.

+

Definition at line 1740 of file ValidatorList.cpp.

@@ -1383,7 +1383,7 @@ Trusted Validators List
Thread Safety

May be called concurrently

-

Definition at line 1749 of file ValidatorList.cpp.

+

Definition at line 1750 of file ValidatorList.cpp.

@@ -1415,7 +1415,7 @@ Trusted Validators List

Returns the current valid list for the given publisher key, if available, as a Json object.

-

Definition at line 1778 of file ValidatorList.cpp.

+

Definition at line 1779 of file ValidatorList.cpp.

@@ -1436,7 +1436,7 @@ Trusted Validators List

Return the number of configured validator list sites.

-

Definition at line 1543 of file ValidatorList.cpp.

+

Definition at line 1544 of file ValidatorList.cpp.

@@ -1459,7 +1459,7 @@ Trusted Validators List
Note
This may be a time in the past if a published list has not been updated since its validUntil. It will be std::nullopt if any configured published list has not been fetched.
Thread Safety
May be called concurrently
-

Definition at line 1599 of file ValidatorList.cpp.

+

Definition at line 1600 of file ValidatorList.cpp.

@@ -1481,7 +1481,7 @@ Trusted Validators List

Return a JSON representation of the state of the validator list.

Thread Safety
May be called concurrently
-

Definition at line 1606 of file ValidatorList.cpp.

+

Definition at line 1607 of file ValidatorList.cpp.

@@ -1525,7 +1525,7 @@ Trusted Validators List

get the trusted master public keys

Returns
the public keys
-

Definition at line 2096 of file ValidatorList.cpp.

+

Definition at line 2097 of file ValidatorList.cpp.

@@ -1547,7 +1547,7 @@ Trusted Validators List

get the validator list threshold

Returns
the threshold
-

Definition at line 2103 of file ValidatorList.cpp.

+

Definition at line 2104 of file ValidatorList.cpp.

@@ -1569,7 +1569,7 @@ Trusted Validators List

get the master public keys of Negative UNL validators

Returns
the master public keys
-

Definition at line 2110 of file ValidatorList.cpp.

+

Definition at line 2111 of file ValidatorList.cpp.

@@ -1597,7 +1597,7 @@ Trusted Validators List -

Definition at line 2117 of file ValidatorList.cpp.

+

Definition at line 2118 of file ValidatorList.cpp.

@@ -1626,7 +1626,7 @@ Trusted Validators List
Returns
a filtered copy of the validations
-

Definition at line 2124 of file ValidatorList.cpp.

+

Definition at line 2125 of file ValidatorList.cpp.

@@ -1656,7 +1656,7 @@ Trusted Validators List

Return the number of configured validator list sites.

-

Definition at line 1537 of file ValidatorList.cpp.

+

Definition at line 1538 of file ValidatorList.cpp.

@@ -1704,7 +1704,7 @@ Trusted Validators List
Thread Safety

May be called concurrently

-

Definition at line 1441 of file ValidatorList.cpp.

+

Definition at line 1442 of file ValidatorList.cpp.

@@ -1753,7 +1753,7 @@ Trusted Validators List
Thread Safety

May be called concurrently

-

Definition at line 1468 of file ValidatorList.cpp.

+

Definition at line 1469 of file ValidatorList.cpp.

@@ -1785,7 +1785,7 @@ Trusted Validators List
Note
This may be a time in the past if a published list has not been updated since its expiration. It will be std::nullopt if any configured published list has not been fetched.
Thread Safety
May be called concurrently
-

Definition at line 1550 of file ValidatorList.cpp.

+

Definition at line 1551 of file ValidatorList.cpp.

@@ -1875,7 +1875,7 @@ Trusted Validators List
Thread Safety

May be called concurrently

-

Definition at line 1116 of file ValidatorList.cpp.

+

Definition at line 1117 of file ValidatorList.cpp.

@@ -1925,7 +1925,7 @@ Trusted Validators List
-

Definition at line 1052 of file ValidatorList.cpp.

+

Definition at line 1053 of file ValidatorList.cpp.

@@ -1963,7 +1963,7 @@ Trusted Validators List
-

Definition at line 824 of file ValidatorList.cpp.

+

Definition at line 825 of file ValidatorList.cpp.

@@ -1991,7 +1991,7 @@ Trusted Validators List
-

Definition at line 840 of file ValidatorList.cpp.

+

Definition at line 841 of file ValidatorList.cpp.

@@ -2059,7 +2059,7 @@ Trusted Validators List
-

Definition at line 850 of file ValidatorList.cpp.

+

Definition at line 851 of file ValidatorList.cpp.

@@ -2145,7 +2145,7 @@ Trusted Validators List
-

Definition at line 721 of file ValidatorList.cpp.

+

Definition at line 722 of file ValidatorList.cpp.

@@ -2384,7 +2384,7 @@ Trusted Validators List
Thread Safety

Calling public member function is expected to lock mutex

-

Definition at line 1347 of file ValidatorList.cpp.

+

Definition at line 1348 of file ValidatorList.cpp.

@@ -2439,7 +2439,7 @@ Trusted Validators List
Thread Safety

Calling public member function is expected to lock mutex

-

Definition at line 1502 of file ValidatorList.cpp.

+

Definition at line 1503 of file ValidatorList.cpp.

@@ -2493,7 +2493,7 @@ Trusted Validators List -

Definition at line 1808 of file ValidatorList.cpp.

+

Definition at line 1809 of file ValidatorList.cpp.

diff --git a/classxrpl_1_1test_1_1ValidatorList__test.html b/classxrpl_1_1test_1_1ValidatorList__test.html index 42d87de80f..720f6f2795 100644 --- a/classxrpl_1_1test_1_1ValidatorList__test.html +++ b/classxrpl_1_1test_1_1ValidatorList__test.html @@ -893,7 +893,7 @@ Private Attributes
-

Definition at line 2702 of file ValidatorList_test.cpp.

+

Definition at line 2703 of file ValidatorList_test.cpp.

@@ -924,7 +924,7 @@ Private Attributes

Implements beast::unit_test::suite.

-

Definition at line 4133 of file ValidatorList_test.cpp.

+

Definition at line 4134 of file ValidatorList_test.cpp.

diff --git a/compression__test_8cpp_source.html b/compression__test_8cpp_source.html index f685b4bf25..01c9f830b0 100644 --- a/compression__test_8cpp_source.html +++ b/compression__test_8cpp_source.html @@ -543,12 +543,12 @@ $(document).ready(function() { init_codefold(0); });
436 // 895B
437 doTest(
438 buildValidatorList(),
-
439 protocol::mtVALIDATORLIST,
+
439 protocol::mtVALIDATOR_LIST,
440 4,
441 "TMValidatorList");
442 doTest(
443 buildValidatorListCollection(),
-
444 protocol::mtVALIDATORLISTCOLLECTION,
+
444 protocol::mtVALIDATOR_LIST_COLLECTION,
445 4,
446 "TMValidatorListCollection");
447 }
diff --git a/namespacemembers_d.html b/namespacemembers_d.html index 3eff7fcf7e..b6a5127615 100644 --- a/namespacemembers_d.html +++ b/namespacemembers_d.html @@ -107,7 +107,7 @@ $(function() {
  • defaultRSAKeyBits : xrpl::openssl::detail
  • defaultseed : xrpl::test::jtx
  • del() : xrpl::test::jtx::did, xrpl::test::jtx::loan, xrpl::test::jtx::loanBroker
  • -
  • delegatable : xrpl
  • +
  • delegable : xrpl
  • delegate() : xrpl::keylet
  • Delegation : xrpl
  • deleteAMMAccount() : xrpl
  • diff --git a/namespacemembers_eval_d.html b/namespacemembers_eval_d.html index 455f209e3b..1c6702e29b 100644 --- a/namespacemembers_eval_d.html +++ b/namespacemembers_eval_d.html @@ -75,7 +75,7 @@ $(function() {
  • dataCorrupt : xrpl::NodeStore
  • decayWindowSeconds : xrpl::Resource
  • defaultMaxPeers : xrpl::PeerFinder::Tuning
  • -
  • delegatable : xrpl
  • +
  • delegable : xrpl
  • destroyMPTIssuance : xrpl
  • DirectoryPageDuplicate : xrpl::test::jtx::directory
  • DirectoryPageNotFound : xrpl::test::jtx::directory
  • diff --git a/namespacemembers_eval_n.html b/namespacemembers_eval_n.html index c161a32471..cfbab6a330 100644 --- a/namespacemembers_eval_n.html +++ b/namespacemembers_eval_n.html @@ -81,7 +81,7 @@ $(function() {
  • NO_CONDITION : xrpl::RPC
  • noPriv : xrpl
  • NORM_TIMEOUTS : xrpl
  • -
  • notDelegatable : xrpl
  • +
  • notDelegable : xrpl
  • notFound : xrpl::NodeStore
  • nullValue : Json
  • diff --git a/namespacemembers_n.html b/namespacemembers_n.html index bd8d193d3d..0705fd251e 100644 --- a/namespacemembers_n.html +++ b/namespacemembers_n.html @@ -118,7 +118,7 @@ $(function() {
  • not_an_array() : xrpl::STParsedJSONDetail
  • not_an_object() : xrpl::STParsedJSONDetail
  • not_validator_error() : xrpl::RPC
  • -
  • notDelegatable : xrpl
  • +
  • notDelegable : xrpl
  • notFound : xrpl::NodeStore
  • NotTEC : xrpl
  • notTooManyOffers() : xrpl::nft
  • diff --git a/namespacexrpl.html b/namespacexrpl.html index de0ad4890f..3fc2144e37 100644 --- a/namespacexrpl.html +++ b/namespacexrpl.html @@ -2237,8 +2237,8 @@ Enumerations enum  GranularPermissionType : std::uint32_t  We have both transaction type permissions and granular type permissions. More...
      -enum  Delegation { delegatable -, notDelegatable +enum  Delegation { delegable +, notDelegable }   enum class  ECDSACanonicality { canonical @@ -9558,8 +9558,8 @@ ledger.
    - - + +
    Enumerator
    delegatable 
    notDelegatable 
    Enumerator
    delegable 
    notDelegable 

    Definition at line 32 of file Permissions.h.

    @@ -60947,8 +60947,8 @@ template<class T >
    {protocol::mtMANIFESTS, TrafficCount::category::manifests},
    {protocol::mtENDPOINTS, TrafficCount::category::overlay},
    {protocol::mtTRANSACTION, TrafficCount::category::transaction},
    -
    {protocol::mtVALIDATORLIST, TrafficCount::category::validatorlist},
    -
    {protocol::mtVALIDATORLISTCOLLECTION,
    +
    {protocol::mtVALIDATOR_LIST, TrafficCount::category::validatorlist},
    +
    {protocol::mtVALIDATOR_LIST_COLLECTION,
    TrafficCount::category::validatorlist},
    {protocol::mtVALIDATION, TrafficCount::category::validation},
    {protocol::mtPROPOSE_LEDGER, TrafficCount::category::proposal},
    diff --git a/search/all_15.js b/search/all_15.js index 3fcbecbb65..e236bb31af 100644 --- a/search/all_15.js +++ b/search/all_15.js @@ -273,7 +273,7 @@ var searchData= ['not_5fvalidator_5ferror_270',['not_validator_error',['../namespacexrpl_1_1RPC.html#a915a3c38339e80c63b1332953410ed8a',1,'xrpl::RPC']]], ['notcleaning_271',['notCleaning',['../classxrpl_1_1LedgerCleanerImp.html#a28cf927f76d8996023f38d227c8cf66ca843890c5d122c26b4aa77186dc893031',1,'xrpl::LedgerCleanerImp']]], ['notconvertible_272',['NotConvertible',['../classxrpl_1_1TER__test_1_1NotConvertible.html',1,'xrpl::TER_test']]], - ['notdelegatable_273',['notDelegatable',['../namespacexrpl.html#af02fc40fb59be7e5f8ee0c33efc7148dae4d385d0b511f8e1312f4e6d732f5a65',1,'xrpl']]], + ['notdelegable_273',['notDelegable',['../namespacexrpl.html#af02fc40fb59be7e5f8ee0c33efc7148dae04ac43f4434f148243ca3ed541ce828',1,'xrpl']]], ['notdone_274',['NotDone',['../namespacexrpl_1_1test.html#a6d9208205417cdf71e669e08e0042870a71b56450c5e1ce9ce5f10422f47beb06',1,'xrpl::test']]], ['notenabled_275',['notEnabled',['../structxrpl_1_1metrics_1_1TxMetrics.html#a23dd376613809323824172df5dce0846',1,'xrpl::metrics::TxMetrics']]], ['notexist_276',['NotExist',['../namespacexrpl_1_1test.html#a6d9208205417cdf71e669e08e0042870ac30e98851cafc795dbe00917b7c4ccf8',1,'xrpl::test']]], diff --git a/search/all_b.js b/search/all_b.js index 29a720d882..4230c9c9a9 100644 --- a/search/all_b.js +++ b/search/all_b.js @@ -135,8 +135,8 @@ var searchData= ['del_132',['del',['../namespacexrpl_1_1test_1_1jtx_1_1loanBroker.html#a356a504c7d6a431398e71e9b121fb087',1,'xrpl::test::jtx::loanBroker::del()'],['../structxrpl_1_1test_1_1jtx_1_1Vault.html#aafdd42ee5927f07fc2d8cd2802316400',1,'xrpl::test::jtx::Vault::del()'],['../classxrpl_1_1TaggedCache.html#a1087558655076b0e7441974bdecd77e5',1,'xrpl::TaggedCache::del()'],['../namespacexrpl_1_1test_1_1jtx_1_1did.html#a0879880fc2bb7f24f38ac422451a818b',1,'xrpl::test::jtx::did::del()'],['../namespacexrpl_1_1test_1_1jtx_1_1loan.html#af5c876ad2066cdfc9be935a8eb9e0d8e',1,'xrpl::test::jtx::loan::del()'],['../namespacexrpl_1_1test_1_1jtx_1_1loanBroker.html#a74744ce4d8db166f8ffd292c8f9f922e',1,'xrpl::test::jtx::loanBroker::del()']]], ['delay_133',['delay',['../structxrpl_1_1test_1_1Consensus__test_1_1Disruptor.html#a2d288eae0672b3ba1eabe1cbbf18b3e3',1,'xrpl::test::Consensus_test::Disruptor::delay'],['../structxrpl_1_1test_1_1csf_1_1BasicNetwork_1_1link__type.html#ac9cbba5a0e5ecdbd3b0a89bae67496fa',1,'xrpl::test::csf::BasicNetwork::link_type::delay']]], ['delays_134',['delays',['../structxrpl_1_1test_1_1csf_1_1Peer.html#acb5ab9829c83399a60b6b58099baa9e1',1,'xrpl::test::csf::Peer']]], - ['delegabletx_5f_135',['delegableTx_',['../classxrpl_1_1Permission.html#a29ecb01a083e77d477aea3050b4af3d7',1,'xrpl::Permission']]], - ['delegatable_136',['delegatable',['../namespacexrpl.html#af02fc40fb59be7e5f8ee0c33efc7148daf708354f10e0c20bc6e8af971f0b0bd7',1,'xrpl']]], + ['delegable_135',['delegable',['../namespacexrpl.html#af02fc40fb59be7e5f8ee0c33efc7148dae1a6b2acbf70d302b99c789e9f6f65c4',1,'xrpl']]], + ['delegabletx_5f_136',['delegableTx_',['../classxrpl_1_1Permission.html#a29ecb01a083e77d477aea3050b4af3d7',1,'xrpl::Permission']]], ['delegate_137',['delegate',['../namespacexrpl_1_1keylet.html#ac3f0f170756c48ccc7d68d01cd94e538',1,'xrpl::keylet::delegate()'],['../namespacexrpl.html#aa040fac78e4975614b31771a1bc5f7ada728f601ddf976d05ffa0d99cc27e8366',1,'xrpl::DELEGATE'],['../structxrpl_1_1test_1_1jtx_1_1MPTSet.html#af8c9a91b898ad41bb8e1a85eab90fbb2',1,'xrpl::test::jtx::MPTSet::delegate']]], ['delegate_5f_138',['delegate_',['../structxrpl_1_1test_1_1jtx_1_1delegate_1_1as.html#a04b3a10e2c10898274c89b10eb74f66e',1,'xrpl::test::jtx::delegate::as']]], ['delegate_5ftest_139',['Delegate_test',['../classxrpl_1_1test_1_1Delegate__test.html',1,'xrpl::test']]], diff --git a/search/enumvalues_4.js b/search/enumvalues_4.js index 001dccd55c..8a924e2fca 100644 --- a/search/enumvalues_4.js +++ b/search/enumvalues_4.js @@ -6,7 +6,7 @@ var searchData= ['defaultmaxpeers_3',['defaultMaxPeers',['../namespacexrpl_1_1PeerFinder_1_1Tuning.html#addf8bda62b973c4f4c2e73de15da7793a93978bfc67cb666da9046161988357b7',1,'xrpl::PeerFinder::Tuning']]], ['defaultno_4',['DefaultNo',['../namespacexrpl.html#a3d02416a71398d8466f19a6515c944fea3fcbd083035206240ef4d4488ac18498',1,'xrpl']]], ['defaultyes_5',['DefaultYes',['../namespacexrpl.html#a3d02416a71398d8466f19a6515c944fea7edd41da231424c2a5df0cffd15af6bf',1,'xrpl']]], - ['delegatable_6',['delegatable',['../namespacexrpl.html#af02fc40fb59be7e5f8ee0c33efc7148daf708354f10e0c20bc6e8af971f0b0bd7',1,'xrpl']]], + ['delegable_6',['delegable',['../namespacexrpl.html#af02fc40fb59be7e5f8ee0c33efc7148dae1a6b2acbf70d302b99c789e9f6f65c4',1,'xrpl']]], ['delegate_7',['DELEGATE',['../namespacexrpl.html#aa040fac78e4975614b31771a1bc5f7ada728f601ddf976d05ffa0d99cc27e8366',1,'xrpl']]], ['delete_8',['Delete',['../classxrpl_1_1test_1_1LoanBroker__test.html#a4a1c657bf0942fde0eb150bf2c826905a25c2f81a72fe38bfd5d629f0bca7f714',1,'xrpl::test::LoanBroker_test']]], ['deposit_5fpreauth_9',['DEPOSIT_PREAUTH',['../namespacexrpl.html#aa040fac78e4975614b31771a1bc5f7ada3327bcb6bb4b74aec018c7cf6efa8b3a',1,'xrpl']]], diff --git a/search/enumvalues_e.js b/search/enumvalues_e.js index 4dbafca0ea..06a7dc7e4b 100644 --- a/search/enumvalues_e.js +++ b/search/enumvalues_e.js @@ -28,7 +28,7 @@ var searchData= ['norm_5ftimeouts_25',['NORM_TIMEOUTS',['../namespacexrpl.html#aebb8809071647c939a34479537299e1fa79e1407e1ee5f4eee6715f98c61aac17',1,'xrpl']]], ['normal_26',['normal',['../classxrpl_1_1Transactor.html#a9420945fd34d224b81b68fd3dcc9fed6a325a214ee7e0a8b0a0ceb47477d57221',1,'xrpl::Transactor::Normal'],['../classxrpl_1_1TxConsequences.html#a33f37210f363c069e6faa24cbdfd2231a38ad0167dc0ce3a5664949640fa2f2a2',1,'xrpl::TxConsequences::normal'],['../classxrpl_1_1Config.html#ac137fe70fc805bad953335f4f1cc1f4aa32d51abcd21da284870b703f557977ed',1,'xrpl::Config::NORMAL']]], ['notcleaning_27',['notCleaning',['../classxrpl_1_1LedgerCleanerImp.html#a28cf927f76d8996023f38d227c8cf66ca843890c5d122c26b4aa77186dc893031',1,'xrpl::LedgerCleanerImp']]], - ['notdelegatable_28',['notDelegatable',['../namespacexrpl.html#af02fc40fb59be7e5f8ee0c33efc7148dae4d385d0b511f8e1312f4e6d732f5a65',1,'xrpl']]], + ['notdelegable_28',['notDelegable',['../namespacexrpl.html#af02fc40fb59be7e5f8ee0c33efc7148dae04ac43f4434f148243ca3ed541ce828',1,'xrpl']]], ['notdone_29',['NotDone',['../namespacexrpl_1_1test.html#a6d9208205417cdf71e669e08e0042870a71b56450c5e1ce9ce5f10422f47beb06',1,'xrpl::test']]], ['notexist_30',['NotExist',['../namespacexrpl_1_1test.html#a6d9208205417cdf71e669e08e0042870ac30e98851cafc795dbe00917b7c4ccf8',1,'xrpl::test']]], ['notfound_31',['notFound',['../namespacexrpl_1_1NodeStore.html#a4883b8bc797bf7591fde489676a6e96ba42539583967afeb33b55afda69c39b09',1,'xrpl::NodeStore']]],