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
300
318 bool
319 load(
320 std::optional<PublicKey> const& localSigningKey,
321 std::vector<std::string> const& configKeys,
322 std::vector<std::string> const& publisherKeys,
323 std::optional<std::size_t> listThreshold = {});
324
331 parseBlobs(std::uint32_t version, Json::Value const& body);
332
334 parseBlobs(protocol::TMValidatorList const& body);
335
337 parseBlobs(protocol::TMValidatorListCollection const& body);
338
339 static void
341 Peer& peer,
342 std::uint64_t peerSequence,
343 PublicKey const& publisherKey,
344 std::size_t maxSequence,
345 std::uint32_t rawVersion,
346 std::string const& rawManifest,
348 HashRouter& hashRouter,
350
351 [[nodiscard]] static std::pair<std::size_t, std::size_t>
353 std::size_t messageVersion,
354 std::uint64_t peerSequence,
355 std::size_t maxSequence,
356 std::uint32_t rawVersion,
357 std::string const& rawManifest,
361
391 PublisherListStats
393 std::string const& manifest,
394 std::uint32_t version,
396 std::string siteUri,
397 uint256 const& hash,
398 Overlay& overlay,
399 HashRouter& hashRouter,
400 NetworkOPs& networkOPs);
401
422 PublisherListStats
424 std::string const& manifest,
425 std::uint32_t version,
427 std::string siteUri,
428 std::optional<uint256> const& hash = {});
429
430 /* Attempt to read previously stored list files. Expected to only be
431 called when loading from URL fails.
432
433 @return A list of valid file:// URLs, if any.
434
435 @par Thread Safety
436
437 May be called concurrently
438 */
440 loadLists();
441
457 TrustChanges
459 hash_set<NodeID> const& seenValidators,
460 NetClock::time_point closeTime,
461 NetworkOPs& ops,
462 Overlay& overlay,
463 HashRouter& hashRouter);
464
479 quorum() const
480 {
481 return quorum_;
482 }
483
492 bool
493 trusted(PublicKey const& identity) const;
494
503 bool
504 listed(PublicKey const& identity) const;
505
517 getTrustedKey(PublicKey const& identity) const;
518
530 getListedKey(PublicKey const& identity) const;
531
540 bool
541 trustedPublisher(PublicKey const& identity) const;
542
551 localPublicKey() const;
552
568 void
569 for_each_listed(std::function<void(PublicKey const&, bool)> func) const;
570
598 void
600 std::string const& manifest,
601 std::uint32_t version,
603 PublicKey const& pubKey,
604 std::size_t maxSequence,
605 uint256 const& hash)> func) const;
606
612
615 count() const;
616
627 expires() const;
628
635 getJson() const;
636
644 {
645 shared_lock read_lock{mutex_};
647 }
648
654 getTrustedMasterKeys() const;
655
661 getListThreshold() const;
662
668 getNegativeUNL() const;
669
674 void
675 setNegativeUNL(hash_set<PublicKey> const& negUnl);
676
685
686private:
689 count(shared_lock const&) const;
690
699 bool
700 trusted(shared_lock const&, PublicKey const& identity) const;
701
713 getTrustedKey(shared_lock const&, PublicKey const& identity) const;
714
725 expires(shared_lock const&) const;
726
749 PublisherListStats
750 applyList(
751 std::string const& globalManifest,
752 std::optional<std::string> const& localManifest,
753 std::string const& blob,
754 std::string const& signature,
755 std::uint32_t version,
756 std::string siteUri,
757 std::optional<uint256> const& hash,
758 lock_guard const&);
759
760 // This function updates the keyListings_ counts for all the trusted
761 // master keys
762 void
764 PublicKey const& pubKey,
765 PublisherList const& current,
766 std::vector<PublicKey> const& oldList,
767 lock_guard const&);
768
769 static void
770 buildBlobInfos(std::map<std::size_t, ValidatorBlobInfo>& blobInfos, PublisherListCollection const& lists);
771
773 buildBlobInfos(PublisherListCollection const& lists);
774
775 static void
777 PublicKey const& publisherKey,
778 PublisherListCollection const& lists,
779 std::size_t maxSequence,
780 uint256 const& hash,
781 Overlay& overlay,
782 HashRouter& hashRouter,
784
785 static void
787 Peer& peer,
788 std::uint64_t peerSequence,
789 PublicKey const& publisherKey,
790 std::size_t maxSequence,
791 std::uint32_t rawVersion,
792 std::string const& rawManifest,
795 HashRouter& hashRouter,
797
800 boost::filesystem::path
801 getCacheFileName(lock_guard const&, PublicKey const& pubKey) const;
802
806 static Json::Value
807 buildFileData(std::string const& pubKey, PublisherListCollection const& pubCollection, beast::Journal j);
808
812 static Json::Value
814 std::string const& pubKey,
815 PublisherListCollection const& pubCollection,
816 std::optional<std::uint32_t> forceVersion,
818
819 template <class Hasher>
820 friend void
826
829 void
830 cacheValidatorFile(lock_guard const& lock, PublicKey const& pubKey) const;
831
841 verify(
842 lock_guard const&,
843 Json::Value& list,
845 std::string const& blob,
846 std::string const& signature);
847
858 bool
859 removePublisherList(lock_guard const&, PublicKey const& publisherKey, PublisherStatus reason);
860
872 calculateQuorum(std::size_t unlSize, std::size_t effectiveUnlSize, std::size_t seenSize);
873};
874
875// hashing helpers
876template <class Hasher>
877void
878hash_append(Hasher& h, ValidatorBlobInfo const& blobInfo)
879{
880 using beast::hash_append;
881 hash_append(h, blobInfo.blob, blobInfo.signature);
882 if (blobInfo.manifest)
883 {
884 hash_append(h, *blobInfo.manifest);
885 }
886}
887
888template <class Hasher>
889void
891{
892 for (auto const& item : blobs)
893 hash_append(h, item);
894}
895
896template <class Hasher>
897void
899{
900 for (auto const& [_, item] : blobs)
901 {
902 (void)_;
903 hash_append(h, item);
904 }
905}
906
907} // namespace xrpl
908
909namespace protocol {
910
911template <class Hasher>
912void
913hash_append(Hasher& h, TMValidatorList const& msg)
914{
915 using beast::hash_append;
916 hash_append(h, msg.manifest(), msg.blob(), msg.signature(), msg.version());
917}
918
919template <class Hasher>
920void
921hash_append(Hasher& h, TMValidatorListCollection const& msg)
922{
923 using beast::hash_append;
924 hash_append(h, msg.manifest(), xrpl::ValidatorList::parseBlobs(msg), msg.version());
925}
926
927} // 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:224
std::chrono::time_point< NetClock > time_point
Definition chrono.h:45
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:597
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:174
@ 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