rippled
Loading...
Searching...
No Matches
ValidatorList.h
1#ifndef XRPL_APP_MISC_VALIDATORLIST_H_INCLUDED
2#define XRPL_APP_MISC_VALIDATORLIST_H_INCLUDED
3
4#include <xrpld/app/misc/Manifest.h>
5#include <xrpld/core/TimeKeeper.h>
6#include <xrpld/overlay/Message.h>
7
8#include <xrpl/basics/Log.h>
9#include <xrpl/basics/UnorderedContainers.h>
10#include <xrpl/crypto/csprng.h>
11#include <xrpl/json/json_value.h>
12#include <xrpl/protocol/PublicKey.h>
13
14#include <boost/thread/shared_mutex.hpp>
15
16#include <mutex>
17#include <shared_mutex>
18
19namespace protocol {
20class TMValidatorList;
21class TMValidatorListCollection;
22} // namespace protocol
23
24namespace ripple {
25
26class Overlay;
27class HashRouter;
28class Message;
29class NetworkOPs;
30class Peer;
31class STValidation;
32
33/* Entries in this enum are ordered by "desirability".
34 The "better" dispositions have lower values than the
35 "worse" dispositions */
36enum class ListDisposition {
38 accepted = 0,
39
41 expired,
42
44 pending,
45
48
51
53 stale,
54
57
60
63};
64
65/* Entries in this enum are ordered by "desirability".
66 The "better" dispositions have lower values than the
67 "worse" dispositions */
68enum class PublisherStatus {
69 // Publisher has provided a valid file
70 available = 0,
71
72 // Current list is expired without replacement
73 expired,
74
75 // No file seen yet
77
78 // Publisher has revoked their manifest key
79 revoked,
80
81};
82
84to_string(ListDisposition disposition);
85
95
98{
99 // base-64 encoded JSON containing the validator list.
101 // hex-encoded signature of the blob using the publisher's signing key
103 // base-64 or hex-encoded manifest containing the publisher's master and
104 // signing public keys
106};
107
154{
156 {
157 explicit PublisherList() = default;
158
165 // base-64 encoded JSON containing the validator list.
167 // hex-encoded signature of the blob using the publisher's signing key
169 // base-64 or hex-encoded manifest containing the publisher's master and
170 // signing public keys
173 };
174
176 {
178 /*
179 The `current` VL is the one which
180 1. Has the largest sequence number that
181 2. Has ever been effective (the effective date is absent or in the
182 past).
183 If this VL has expired, all VLs with previous sequence numbers
184 will also be considered expired, and thus there will be no valid VL
185 until one with a larger sequence number becomes effective. This is to
186 prevent allowing old VLs to reactivate.
187 */
189 /*
190 The `remaining` list holds any relevant VLs which have a larger sequence
191 number than current. By definition they will all have an effective date
192 in the future. Relevancy will be determined by sorting the VLs by
193 sequence number, then iterating over the list and removing any VLs for
194 which the following VL (ignoring gaps) has the same or earlier effective
195 date.
196 */
199 // The hash of the full set if sent in a single message
203 };
204
208 boost::filesystem::path const dataPath_;
213
216
217 // Published lists stored by publisher master public key
219
220 // Listed master public keys with the number of lists they appear on
222
223 // The current list of trusted master keys
225
226 // Minimum number of lists on which a trusted validator must appear on
228
229 // The current list of trusted signing keys. For those validators using
230 // a manifest, the signing key is the ephemeral key. For the ones using
231 // a seed, the signing key is the same as the master key.
233
235
236 // The below variable contains the Publisher list specified in the local
237 // config file under the title of SECTION_VALIDATORS or [validators].
238 // This list is not associated with the masterKey of any publisher.
239
240 // Appropos PublisherListCollection fields, localPublisherList does not
241 // have any "remaining" manifests. It is assumed to be perennially
242 // "available". The "validUntil" field is set to the highest possible
243 // value of the field, hence this list is always valid.
245
246 // The master public keys of the current negative UNL
248
249 // Currently supported versions of publisher list format
250 static constexpr std::uint32_t supportedListVersions[]{1, 2};
251 // In the initial release, to prevent potential abuse and attacks, any VL
252 // collection with more than 5 entries will be considered malformed.
253 static constexpr std::size_t maxSupportedBlobs = 5;
254 // Prefix of the file name used to store cache files.
256
257public:
259 ManifestCache& validatorManifests,
260 ManifestCache& publisherManifests,
261 TimeKeeper& timeKeeper,
262 std::string const& databasePath,
265 ~ValidatorList() = default;
266
273 {
274 explicit PublisherListStats() = default;
278 PublicKey key,
279 PublisherStatus stat,
280 std::size_t seq);
281
283 bestDisposition() const;
285 worstDisposition() const;
286 void
288
289 // Tracks the dispositions of each processed list and how many times it
290 // occurred
295 };
296
298 {
299 explicit MessageWithHash() = default;
300 explicit MessageWithHash(
301 std::shared_ptr<Message> const& message_,
302 uint256 hash_,
303 std::size_t num_);
307 };
308
326 bool
327 load(
328 std::optional<PublicKey> const& localSigningKey,
329 std::vector<std::string> const& configKeys,
330 std::vector<std::string> const& publisherKeys,
331 std::optional<std::size_t> listThreshold = {});
332
339 parseBlobs(std::uint32_t version, Json::Value const& body);
340
342 parseBlobs(protocol::TMValidatorList const& body);
343
345 parseBlobs(protocol::TMValidatorListCollection const& body);
346
347 static void
349 Peer& peer,
350 std::uint64_t peerSequence,
351 PublicKey const& publisherKey,
352 std::size_t maxSequence,
353 std::uint32_t rawVersion,
354 std::string const& rawManifest,
356 HashRouter& hashRouter,
358
359 [[nodiscard]] static std::pair<std::size_t, std::size_t>
361 std::size_t messageVersion,
362 std::uint64_t peerSequence,
363 std::size_t maxSequence,
364 std::uint32_t rawVersion,
365 std::string const& rawManifest,
369
399 PublisherListStats
401 std::string const& manifest,
402 std::uint32_t version,
404 std::string siteUri,
405 uint256 const& hash,
406 Overlay& overlay,
407 HashRouter& hashRouter,
408 NetworkOPs& networkOPs);
409
430 PublisherListStats
432 std::string const& manifest,
433 std::uint32_t version,
435 std::string siteUri,
436 std::optional<uint256> const& hash = {});
437
438 /* Attempt to read previously stored list files. Expected to only be
439 called when loading from URL fails.
440
441 @return A list of valid file:// URLs, if any.
442
443 @par Thread Safety
444
445 May be called concurrently
446 */
448 loadLists();
449
465 TrustChanges
467 hash_set<NodeID> const& seenValidators,
468 NetClock::time_point closeTime,
469 NetworkOPs& ops,
470 Overlay& overlay,
471 HashRouter& hashRouter);
472
487 quorum() const
488 {
489 return quorum_;
490 }
491
500 bool
501 trusted(PublicKey const& identity) const;
502
511 bool
512 listed(PublicKey const& identity) const;
513
525 getTrustedKey(PublicKey const& identity) const;
526
538 getListedKey(PublicKey const& identity) const;
539
548 bool
549 trustedPublisher(PublicKey const& identity) const;
550
559 localPublicKey() const;
560
576 void
577 for_each_listed(std::function<void(PublicKey const&, bool)> func) const;
578
606 void
608 std::function<void(
609 std::string const& manifest,
610 std::uint32_t version,
612 PublicKey const& pubKey,
613 std::size_t maxSequence,
614 uint256 const& hash)> func) const;
615
621 std::string_view pubKey,
622 std::optional<std::uint32_t> forceVersion = {});
623
626 count() const;
627
638 expires() const;
639
646 getJson() const;
647
655 {
656 shared_lock read_lock{mutex_};
658 }
659
665 getTrustedMasterKeys() const;
666
672 getListThreshold() const;
673
679 getNegativeUNL() const;
680
685 void
686 setNegativeUNL(hash_set<PublicKey> const& negUnl);
687
696 std::vector<std::shared_ptr<STValidation>>&& validations) const;
697
698private:
701 count(shared_lock const&) const;
702
711 bool
712 trusted(shared_lock const&, PublicKey const& identity) const;
713
725 getTrustedKey(shared_lock const&, PublicKey const& identity) const;
726
737 expires(shared_lock const&) const;
738
761 PublisherListStats
762 applyList(
763 std::string const& globalManifest,
764 std::optional<std::string> const& localManifest,
765 std::string const& blob,
766 std::string const& signature,
767 std::uint32_t version,
768 std::string siteUri,
769 std::optional<uint256> const& hash,
770 lock_guard const&);
771
772 // This function updates the keyListings_ counts for all the trusted
773 // master keys
774 void
776 PublicKey const& pubKey,
777 PublisherList const& current,
778 std::vector<PublicKey> const& oldList,
779 lock_guard const&);
780
781 static void
784 PublisherListCollection const& lists);
785
787 buildBlobInfos(PublisherListCollection const& lists);
788
789 static void
791 PublicKey const& publisherKey,
792 PublisherListCollection const& lists,
793 std::size_t maxSequence,
794 uint256 const& hash,
795 Overlay& overlay,
796 HashRouter& hashRouter,
798
799 static void
801 Peer& peer,
802 std::uint64_t peerSequence,
803 PublicKey const& publisherKey,
804 std::size_t maxSequence,
805 std::uint32_t rawVersion,
806 std::string const& rawManifest,
809 HashRouter& hashRouter,
811
814 boost::filesystem::path
815 getCacheFileName(lock_guard const&, PublicKey const& pubKey) const;
816
820 static Json::Value
822 std::string const& pubKey,
823 PublisherListCollection const& pubCollection,
825
829 static Json::Value
831 std::string const& pubKey,
832 PublisherListCollection const& pubCollection,
833 std::optional<std::uint32_t> forceVersion,
835
836 template <class Hasher>
837 friend void
843
846 void
847 cacheValidatorFile(lock_guard const& lock, PublicKey const& pubKey) const;
848
858 verify(
859 lock_guard const&,
860 Json::Value& list,
862 std::string const& blob,
863 std::string const& signature);
864
875 bool
877 lock_guard const&,
878 PublicKey const& publisherKey,
879 PublisherStatus reason);
880
893 std::size_t unlSize,
894 std::size_t effectiveUnlSize,
895 std::size_t seenSize);
896};
897
898// hashing helpers
899template <class Hasher>
900void
901hash_append(Hasher& h, ValidatorBlobInfo const& blobInfo)
902{
903 using beast::hash_append;
904 hash_append(h, blobInfo.blob, blobInfo.signature);
905 if (blobInfo.manifest)
906 {
907 hash_append(h, *blobInfo.manifest);
908 }
909}
910
911template <class Hasher>
912void
914{
915 for (auto const& item : blobs)
916 hash_append(h, item);
917}
918
919template <class Hasher>
920void
922{
923 for (auto const& [_, item] : blobs)
924 {
925 (void)_;
926 hash_append(h, item);
927 }
928}
929
930} // namespace ripple
931
932namespace protocol {
933
934template <class Hasher>
935void
936hash_append(Hasher& h, TMValidatorList const& msg)
937{
938 using beast::hash_append;
939 hash_append(h, msg.manifest(), msg.blob(), msg.signature(), msg.version());
940}
941
942template <class Hasher>
943void
944hash_append(Hasher& h, TMValidatorListCollection const& msg)
945{
946 using beast::hash_append;
948 h,
949 msg.manifest(),
951 msg.version());
952}
953
954} // namespace protocol
955
956#endif
Represents a JSON value.
Definition json_value.h:131
A generic endpoint for log messages.
Definition Journal.h:41
typename Clock::time_point time_point
Routing table for objects identified by hash.
Definition HashRouter.h:78
Remembers manifests with the highest sequence number.
Definition Manifest.h:237
std::chrono::time_point< NetClock > time_point
Definition chrono.h:50
Provides server functionality for clients.
Definition NetworkOPs.h:70
Manages the set of connected peers.
Definition Overlay.h:30
Represents a peer connection in the overlay.
A public key.
Definition PublicKey.h:43
Manages various times used by the server.
Definition TimeKeeper.h:13
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.
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 void broadcastBlobs(PublicKey const &publisherKey, PublisherListCollection const &lists, std::size_t maxSequence, uint256 const &hash, Overlay &overlay, HashRouter &hashRouter, beast::Journal j)
boost::filesystem::path getCacheFileName(lock_guard const &, PublicKey const &pubKey) const
Get the filename used for caching UNLs.
std::vector< std::string > loadLists()
PublisherList localPublisherList
std::optional< PublicKey > localPublicKey() const
This function returns the local validator public key or a std::nullopt.
ManifestCache & validatorManifests_
hash_set< PublicKey > getTrustedMasterKeys() const
get the trusted master public keys
std::atomic< std::size_t > quorum_
void updatePublisherList(PublicKey const &pubKey, PublisherList const &current, std::vector< PublicKey > const &oldList, lock_guard const &)
void setNegativeUNL(hash_set< PublicKey > const &negUnl)
set the Negative UNL with validators' master public keys
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,...
static void buildBlobInfos(std::map< std::size_t, ValidatorBlobInfo > &blobInfos, PublisherListCollection const &lists)
hash_map< PublicKey, std::size_t > keyListings_
bool listed(PublicKey const &identity) const
Returns true 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.
hash_set< PublicKey > trustedMasterKeys_
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.
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.
hash_set< PublicKey > negativeUNL_
Json::Value getJson() const
Return a JSON representation of the state of the validator 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::optional< TimeKeeper::time_point > expires() const
Return the time when the validator list will expire.
std::size_t calculateQuorum(std::size_t unlSize, std::size_t effectiveUnlSize, std::size_t seenSize)
Return quorum for trusted validator set.
std::shared_mutex mutex_
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...
std::lock_guard< decltype(mutex_)> lock_guard
beast::Journal const j_
bool trustedPublisher(PublicKey const &identity) const
Returns true if public key is a trusted publisher.
std::optional< PublicKey > getListedKey(PublicKey const &identity) const
Returns listed master public if public key is included on any lists.
boost::filesystem::path const dataPath_
bool removePublisherList(lock_guard const &, PublicKey const &publisherKey, PublisherStatus reason)
Stop trusting publisher's list of keys.
bool trusted(PublicKey const &identity) const
Returns true if public key is trusted.
static constexpr std::size_t maxSupportedBlobs
TrustChanges updateTrusted(hash_set< NodeID > const &seenValidators, NetClock::time_point closeTime, NetworkOPs &ops, Overlay &overlay, HashRouter &hashRouter)
Update trusted nodes.
std::size_t getListThreshold() const
get the validator list threshold
void for_each_listed(std::function< void(PublicKey const &, bool)> func) const
Invokes the callback once for every listed validation public key.
std::optional< PublicKey > localPubKey_
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 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.
std::optional< std::size_t > minimumQuorum_
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.
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...
std::size_t quorum() const
Get quorum value for current trusted key set.
static std::string const filePrefix_
hash_set< PublicKey > trustedSigningKeys_
hash_map< PublicKey, PublisherListCollection > publisherLists_
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.
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=maximiumMessageSize)
QuorumKeys getQuorumKeys() const
Get the quorum and all of the trusted keys.
std::shared_lock< decltype(mutex_)> shared_lock
ManifestCache & publisherManifests_
static constexpr std::uint32_t supportedListVersions[]
hash_set< PublicKey > getNegativeUNL() const
get the master public keys of Negative UNL validators
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:6
void hash_append(Hasher &h, Slice const &v)
Definition Slice.h:180
@ current
This was a new validation and was added.
@ 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.
@ stale
Sequence is too old.
@ accepted
Manifest is valid.
@ invalid
Timely, but invalid signature.
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:611
constexpr std::size_t maximiumMessageSize
Definition Message.h:15
@ manifest
Manifest.
Changes in trusted nodes after updating validator list.
hash_set< NodeID > added
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::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::map< ListDisposition, std::size_t > dispositions
std::optional< PublicKey > publisherKey
std::optional< std::string > rawManifest
std::vector< std::string > manifests