rippled
Loading...
Searching...
No Matches
ValidatorList.h
1#pragma once
2
3#include <xrpld/core/TimeKeeper.h>
4#include <xrpld/overlay/Message.h>
5
6#include <xrpl/basics/Log.h>
7#include <xrpl/basics/UnorderedContainers.h>
8#include <xrpl/crypto/csprng.h>
9#include <xrpl/json/json_value.h>
10#include <xrpl/protocol/PublicKey.h>
11#include <xrpl/server/Manifest.h>
12
13#include <boost/thread/shared_mutex.hpp>
14
15#include <mutex>
16#include <shared_mutex>
17
18namespace protocol {
19class TMValidatorList;
20class TMValidatorListCollection;
21} // namespace protocol
22
23namespace xrpl {
24
25class Overlay;
26class HashRouter;
27class Message;
28class NetworkOPs;
29class Peer;
30class STValidation;
31
32/* Entries in this enum are ordered by "desirability".
33 The "better" dispositions have lower values than the
34 "worse" dispositions */
35enum class ListDisposition {
37 accepted = 0,
38
40 expired,
41
43 pending,
44
47
50
52 stale,
53
56
59
62};
63
64/* Entries in this enum are ordered by "desirability".
65 The "better" dispositions have lower values than the
66 "worse" dispositions */
67enum class PublisherStatus {
68 // Publisher has provided a valid file
69 available = 0,
70
71 // Current list is expired without replacement
72 expired,
73
74 // No file seen yet
76
77 // Publisher has revoked their manifest key
78 revoked,
79
80};
81
83to_string(ListDisposition disposition);
84
94
97{
98 // base-64 encoded JSON containing the validator list.
100 // hex-encoded signature of the blob using the publisher's signing key
102 // base-64 or hex-encoded manifest containing the publisher's master and
103 // signing public keys
105};
106
153{
155 {
156 explicit PublisherList() = default;
157
164 // base-64 encoded JSON containing the validator list.
166 // hex-encoded signature of the blob using the publisher's signing key
168 // base-64 or hex-encoded manifest containing the publisher's master and
169 // signing public keys
172 };
173
175 {
177 /*
178 The `current` VL is the one which
179 1. Has the largest sequence number that
180 2. Has ever been effective (the effective date is absent or in the
181 past).
182 If this VL has expired, all VLs with previous sequence numbers
183 will also be considered expired, and thus there will be no valid VL
184 until one with a larger sequence number becomes effective. This is to
185 prevent allowing old VLs to reactivate.
186 */
188 /*
189 The `remaining` list holds any relevant VLs which have a larger sequence
190 number than current. By definition they will all have an effective date
191 in the future. Relevancy will be determined by sorting the VLs by
192 sequence number, then iterating over the list and removing any VLs for
193 which the following VL (ignoring gaps) has the same or earlier effective
194 date.
195 */
198 // The hash of the full set if sent in a single message
202 };
203
207 boost::filesystem::path const dataPath_;
212
215
216 // Published lists stored by publisher master public key
218
219 // Listed master public keys with the number of lists they appear on
221
222 // The current list of trusted master keys
224
225 // Minimum number of lists on which a trusted validator must appear on
227
228 // The current list of trusted signing keys. For those validators using
229 // a manifest, the signing key is the ephemeral key. For the ones using
230 // a seed, the signing key is the same as the master key.
232
234
235 // The below variable contains the Publisher list specified in the local
236 // config file under the title of SECTION_VALIDATORS or [validators].
237 // This list is not associated with the masterKey of any publisher.
238
239 // Apropos PublisherListCollection fields, localPublisherList does not
240 // have any "remaining" manifests. It is assumed to be perennially
241 // "available". The "validUntil" field is set to the highest possible
242 // value of the field, hence this list is always valid.
244
245 // The master public keys of the current negative UNL
247
248 // Currently supported versions of publisher list format
249 static constexpr std::uint32_t supportedListVersions[]{1, 2};
250 // In the initial release, to prevent potential abuse and attacks, any VL
251 // collection with more than 5 entries will be considered malformed.
252 static constexpr std::size_t maxSupportedBlobs = 5;
253 // Prefix of the file name used to store cache files.
255
256public:
258 ManifestCache& validatorManifests,
259 ManifestCache& publisherManifests,
260 TimeKeeper& timeKeeper,
261 std::string const& databasePath,
264 ~ValidatorList() = default;
265
272 {
273 explicit PublisherListStats() = default;
276
278 bestDisposition() const;
280 worstDisposition() const;
281 void
283
284 // Tracks the dispositions of each processed list and how many times it
285 // occurred
290 };
291
293 {
294 explicit MessageWithHash() = default;
295 explicit MessageWithHash(
296 std::shared_ptr<Message> const& message_,
297 uint256 hash_,
298 std::size_t num_);
302 };
303
321 bool
322 load(
323 std::optional<PublicKey> const& localSigningKey,
324 std::vector<std::string> const& configKeys,
325 std::vector<std::string> const& publisherKeys,
326 std::optional<std::size_t> listThreshold = {});
327
334 parseBlobs(std::uint32_t version, Json::Value const& body);
335
337 parseBlobs(protocol::TMValidatorList const& body);
338
340 parseBlobs(protocol::TMValidatorListCollection const& body);
341
342 static void
344 Peer& peer,
345 std::uint64_t peerSequence,
346 PublicKey const& publisherKey,
347 std::size_t maxSequence,
348 std::uint32_t rawVersion,
349 std::string const& rawManifest,
351 HashRouter& hashRouter,
353
354 [[nodiscard]] static std::pair<std::size_t, std::size_t>
356 std::size_t messageVersion,
357 std::uint64_t peerSequence,
358 std::size_t maxSequence,
359 std::uint32_t rawVersion,
360 std::string const& rawManifest,
364
394 PublisherListStats
396 std::string const& manifest,
397 std::uint32_t version,
399 std::string siteUri,
400 uint256 const& hash,
401 Overlay& overlay,
402 HashRouter& hashRouter,
403 NetworkOPs& networkOPs);
404
425 PublisherListStats
427 std::string const& manifest,
428 std::uint32_t version,
430 std::string siteUri,
431 std::optional<uint256> const& hash = {});
432
433 /* Attempt to read previously stored list files. Expected to only be
434 called when loading from URL fails.
435
436 @return A list of valid file:// URLs, if any.
437
438 @par Thread Safety
439
440 May be called concurrently
441 */
443 loadLists();
444
460 TrustChanges
462 hash_set<NodeID> const& seenValidators,
463 NetClock::time_point closeTime,
464 NetworkOPs& ops,
465 Overlay& overlay,
466 HashRouter& hashRouter);
467
482 quorum() const
483 {
484 return quorum_;
485 }
486
495 bool
496 trusted(PublicKey const& identity) const;
497
506 bool
507 listed(PublicKey const& identity) const;
508
520 getTrustedKey(PublicKey const& identity) const;
521
533 getListedKey(PublicKey const& identity) const;
534
543 bool
544 trustedPublisher(PublicKey const& identity) const;
545
554 localPublicKey() const;
555
571 void
572 for_each_listed(std::function<void(PublicKey const&, bool)> func) const;
573
601 void
603 std::function<void(
604 std::string const& manifest,
605 std::uint32_t version,
607 PublicKey const& pubKey,
608 std::size_t maxSequence,
609 uint256 const& hash)> func) const;
610
616
619 count() const;
620
631 expires() const;
632
639 getJson() const;
640
648 {
649 shared_lock const read_lock{mutex_};
651 }
652
658 getTrustedMasterKeys() const;
659
665 getListThreshold() const;
666
672 getNegativeUNL() const;
673
678 void
679 setNegativeUNL(hash_set<PublicKey> const& negUnl);
680
689
690private:
693 count(shared_lock const&) const;
694
703 bool
704 trusted(shared_lock const&, PublicKey const& identity) const;
705
717 getTrustedKey(shared_lock const&, PublicKey const& identity) const;
718
729 expires(shared_lock const&) const;
730
753 PublisherListStats
754 applyList(
755 std::string const& globalManifest,
756 std::optional<std::string> const& localManifest,
757 std::string const& blob,
758 std::string const& signature,
759 std::uint32_t version,
760 std::string siteUri,
761 std::optional<uint256> const& hash,
762 lock_guard const&);
763
764 // This function updates the keyListings_ counts for all the trusted
765 // master keys
766 void
768 PublicKey const& pubKey,
769 PublisherList const& current,
770 std::vector<PublicKey> const& oldList,
771 lock_guard const&);
772
773 static void
776 PublisherListCollection const& lists);
777
779 buildBlobInfos(PublisherListCollection const& lists);
780
781 static void
783 PublicKey const& publisherKey,
784 PublisherListCollection const& lists,
785 std::size_t maxSequence,
786 uint256 const& hash,
787 Overlay& overlay,
788 HashRouter& hashRouter,
790
791 static void
793 Peer& peer,
794 std::uint64_t peerSequence,
795 PublicKey const& publisherKey,
796 std::size_t maxSequence,
797 std::uint32_t rawVersion,
798 std::string const& rawManifest,
801 HashRouter& hashRouter,
803
806 boost::filesystem::path
807 getCacheFileName(lock_guard const&, PublicKey const& pubKey) const;
808
812 static Json::Value
814 std::string const& pubKey,
815 PublisherListCollection const& pubCollection,
817
821 static Json::Value
823 std::string const& pubKey,
824 PublisherListCollection const& pubCollection,
825 std::optional<std::uint32_t> forceVersion,
827
828 template <class Hasher>
829 friend void
835
838 void
839 cacheValidatorFile(lock_guard const& lock, PublicKey const& pubKey) const;
840
850 verify(
851 lock_guard const&,
852 Json::Value& list,
854 std::string const& blob,
855 std::string const& signature);
856
867 bool
868 removePublisherList(lock_guard const&, PublicKey const& publisherKey, PublisherStatus reason);
869
881 calculateQuorum(std::size_t unlSize, std::size_t effectiveUnlSize, std::size_t seenSize);
882};
883
884// hashing helpers
885template <class Hasher>
886void
887hash_append(Hasher& h, ValidatorBlobInfo const& blobInfo)
888{
889 using beast::hash_append;
890 hash_append(h, blobInfo.blob, blobInfo.signature);
891 if (blobInfo.manifest)
892 {
893 hash_append(h, *blobInfo.manifest);
894 }
895}
896
897template <class Hasher>
898void
900{
901 for (auto const& item : blobs)
902 hash_append(h, item);
903}
904
905template <class Hasher>
906void
908{
909 for (auto const& [_, item] : blobs)
910 {
911 (void)_;
912 hash_append(h, item);
913 }
914}
915
916} // namespace xrpl
917
918namespace protocol {
919
920template <class Hasher>
921void
922hash_append(Hasher& h, TMValidatorList const& msg)
923{
924 using beast::hash_append;
925 hash_append(h, msg.manifest(), msg.blob(), msg.signature(), msg.version());
926}
927
928template <class Hasher>
929void
930hash_append(Hasher& h, TMValidatorListCollection const& msg)
931{
932 using beast::hash_append;
933 hash_append(h, msg.manifest(), xrpl::ValidatorList::parseBlobs(msg), msg.version());
934}
935
936} // namespace protocol
Represents a JSON value.
Definition json_value.h:130
A generic endpoint for log messages.
Definition Journal.h:40
typename Clock::time_point time_point
Routing table for objects identified by hash.
Definition HashRouter.h:77
Remembers manifests with the highest sequence number.
Definition Manifest.h:235
std::chrono::time_point< NetClock > time_point
Definition chrono.h:46
Provides server functionality for clients.
Definition NetworkOPs.h:71
Manages the set of connected peers.
Definition Overlay.h:29
Represents a peer connection in the overlay.
A public key.
Definition PublicKey.h:42
Manages various times used by the server.
Definition TimeKeeper.h:12
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.
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.
~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::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.
beast::Journal const j_
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.
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.
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
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)
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...
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.
static std::string const filePrefix_
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)
T is_same_v
std::enable_if_t< is_contiguously_hashable< T, Hasher >::value > hash_append(Hasher &h, T const &t) noexcept
Logically concatenate input data to a Hasher.
void hash_append(Hasher &h, TMValidatorList const &msg)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:602
ListDisposition
@ unsupported_version
List version is not supported.
@ untrusted
List signed by untrusted publisher key.
@ same_sequence
Same sequence as current list.
@ pending
List will be valid in the future.
@ known_sequence
Future sequence already seen.
@ expired
List is expired, but has the largest non-pending sequence seen so far.
@ current
This was a new validation and was added.
PublisherStatus
constexpr std::size_t maximumMessageSize
Definition Message.h:14
void hash_append(Hasher &h, Slice const &v)
Definition Slice.h:175
@ manifest
Manifest.
@ stale
Sequence is too old.
@ accepted
Manifest is valid.
@ invalid
Timely, but invalid signature.
Changes in trusted nodes after updating validator list.
hash_set< NodeID > added
TrustChanges()=default
hash_set< NodeID > removed
Used to represent the information stored in the blobs_v2 Json array.
std::optional< std::string > manifest
std::shared_ptr< Message > message
std::optional< std::size_t > maxSequence
std::map< std::size_t, PublisherList > remaining
Describes the result of processing a Validator List (UNL), including some of the information from the...
void mergeDispositions(PublisherListStats const &src)
std::optional< PublicKey > publisherKey
std::map< ListDisposition, std::size_t > dispositions
std::vector< PublicKey > list
TimeKeeper::time_point validFrom
TimeKeeper::time_point validUntil
std::vector< std::string > manifests
std::optional< std::string > rawManifest