rippled
Loading...
Searching...
No Matches
ValidatorList.h
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2015 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#ifndef RIPPLE_APP_MISC_VALIDATORLIST_H_INCLUDED
21#define RIPPLE_APP_MISC_VALIDATORLIST_H_INCLUDED
22
23#include <xrpld/app/misc/Manifest.h>
24#include <xrpld/core/TimeKeeper.h>
25#include <xrpld/overlay/Message.h>
26#include <xrpl/basics/Log.h>
27#include <xrpl/basics/UnorderedContainers.h>
28#include <xrpl/crypto/csprng.h>
29#include <xrpl/json/json_value.h>
30#include <xrpl/protocol/PublicKey.h>
31
32#include <boost/thread/shared_mutex.hpp>
33
34#include <mutex>
35#include <shared_mutex>
36
37namespace protocol {
38class TMValidatorList;
39class TMValidatorListCollection;
40} // namespace protocol
41
42namespace ripple {
43
44class Overlay;
45class HashRouter;
46class Message;
47class NetworkOPs;
48class Peer;
49class STValidation;
50
51/* Entries in this enum are ordered by "desirability".
52 The "better" dispositions have lower values than the
53 "worse" dispositions */
54enum class ListDisposition {
56 accepted = 0,
57
59 expired,
60
62 pending,
63
66
69
71 stale,
72
75
78
81};
82
83/* Entries in this enum are ordered by "desirability".
84 The "better" dispositions have lower values than the
85 "worse" dispositions */
86enum class PublisherStatus {
87 // Publisher has provided a valid file
88 available = 0,
89
90 // Current list is expired without replacement
91 expired,
92
93 // No file seen yet
95
96 // Publisher has revoked their manifest key
97 revoked,
98
99};
100
102to_string(ListDisposition disposition);
103
107{
108 explicit TrustChanges() = default;
109
112};
113
116{
117 // base-64 encoded JSON containing the validator list.
119 // hex-encoded signature of the blob using the publisher's signing key
121 // base-64 or hex-encoded manifest containing the publisher's master and
122 // signing public keys
124};
125
172{
174 {
175 explicit PublisherList() = default;
176
183 // base-64 encoded JSON containing the validator list.
185 // hex-encoded signature of the blob using the publisher's signing key
187 // base-64 or hex-encoded manifest containing the publisher's master and
188 // signing public keys
191 };
192
194 {
196 /*
197 The `current` VL is the one which
198 1. Has the largest sequence number that
199 2. Has ever been effective (the effective date is absent or in the
200 past).
201 If this VL has expired, all VLs with previous sequence numbers
202 will also be considered expired, and thus there will be no valid VL
203 until one with a larger sequence number becomes effective. This is to
204 prevent allowing old VLs to reactivate.
205 */
207 /*
208 The `remaining` list holds any relevant VLs which have a larger sequence
209 number than current. By definition they will all have an effective date
210 in the future. Relevancy will be determined by sorting the VLs by
211 sequence number, then iterating over the list and removing any VLs for
212 which the following VL (ignoring gaps) has the same or earlier effective
213 date.
214 */
217 // The hash of the full set if sent in a single message
221 };
222
226 boost::filesystem::path const dataPath_;
228 boost::shared_mutex mutable mutex_;
231
234
235 // Published lists stored by publisher master public key
237
238 // Listed master public keys with the number of lists they appear on
240
241 // The current list of trusted master keys
243
244 // Minimum number of lists on which a trusted validator must appear on
246
247 // The current list of trusted signing keys. For those validators using
248 // a manifest, the signing key is the ephemeral key. For the ones using
249 // a seed, the signing key is the same as the master key.
251
253
254 // The below variable contains the Publisher list specified in the local
255 // config file under the title of SECTION_VALIDATORS or [validators].
256 // This list is not associated with the masterKey of any publisher.
257
258 // Appropos PublisherListCollection fields, localPublisherList does not
259 // have any "remaining" manifests. It is assumed to be perennially
260 // "available". The "validUntil" field is set to the highest possible
261 // value of the field, hence this list is always valid.
263
264 // The master public keys of the current negative UNL
266
267 // Currently supported versions of publisher list format
268 static constexpr std::uint32_t supportedListVersions[]{1, 2};
269 // In the initial release, to prevent potential abuse and attacks, any VL
270 // collection with more than 5 entries will be considered malformed.
271 static constexpr std::size_t maxSupportedBlobs = 5;
272 // Prefix of the file name used to store cache files.
274
275public:
277 ManifestCache& validatorManifests,
278 ManifestCache& publisherManifests,
279 TimeKeeper& timeKeeper,
280 std::string const& databasePath,
282 std::optional<std::size_t> minimumQuorum = std::nullopt);
283 ~ValidatorList() = default;
284
291 {
292 explicit PublisherListStats() = default;
296 PublicKey key,
297 PublisherStatus stat,
298 std::size_t seq);
299
301 bestDisposition() const;
303 worstDisposition() const;
304 void
306
307 // Tracks the dispositions of each processed list and how many times it
308 // occurred
313 };
314
316 {
317 explicit MessageWithHash() = default;
318 explicit MessageWithHash(
319 std::shared_ptr<Message> const& message_,
320 uint256 hash_,
321 std::size_t num_);
325 };
326
344 bool
345 load(
346 std::optional<PublicKey> const& localSigningKey,
347 std::vector<std::string> const& configKeys,
348 std::vector<std::string> const& publisherKeys,
349 std::optional<std::size_t> listThreshold = {});
350
357 parseBlobs(std::uint32_t version, Json::Value const& body);
358
360 parseBlobs(protocol::TMValidatorList const& body);
361
363 parseBlobs(protocol::TMValidatorListCollection const& body);
364
365 static void
367 Peer& peer,
368 std::uint64_t peerSequence,
369 PublicKey const& publisherKey,
370 std::size_t maxSequence,
371 std::uint32_t rawVersion,
372 std::string const& rawManifest,
374 HashRouter& hashRouter,
376
377 [[nodiscard]] static std::pair<std::size_t, std::size_t>
379 std::size_t messageVersion,
380 std::uint64_t peerSequence,
381 std::size_t maxSequence,
382 std::uint32_t rawVersion,
383 std::string const& rawManifest,
387
417 PublisherListStats
419 std::string const& manifest,
420 std::uint32_t version,
422 std::string siteUri,
423 uint256 const& hash,
424 Overlay& overlay,
425 HashRouter& hashRouter,
426 NetworkOPs& networkOPs);
427
448 PublisherListStats
450 std::string const& manifest,
451 std::uint32_t version,
453 std::string siteUri,
454 std::optional<uint256> const& hash = {});
455
456 /* Attempt to read previously stored list files. Expected to only be
457 called when loading from URL fails.
458
459 @return A list of valid file:// URLs, if any.
460
461 @par Thread Safety
462
463 May be called concurrently
464 */
466 loadLists();
467
483 TrustChanges
485 hash_set<NodeID> const& seenValidators,
486 NetClock::time_point closeTime,
487 NetworkOPs& ops,
488 Overlay& overlay,
489 HashRouter& hashRouter);
490
505 quorum() const
506 {
507 return quorum_;
508 }
509
518 bool
519 trusted(PublicKey const& identity) const;
520
529 bool
530 listed(PublicKey const& identity) const;
531
543 getTrustedKey(PublicKey const& identity) const;
544
556 getListedKey(PublicKey const& identity) const;
557
566 bool
567 trustedPublisher(PublicKey const& identity) const;
568
577 localPublicKey() const;
578
594 void
595 for_each_listed(std::function<void(PublicKey const&, bool)> func) const;
596
624 void
626 std::function<void(
627 std::string const& manifest,
628 std::uint32_t version,
630 PublicKey const& pubKey,
631 std::size_t maxSequence,
632 uint256 const& hash)> func) const;
633
639 std::string_view pubKey,
640 std::optional<std::uint32_t> forceVersion = {});
641
644 count() const;
645
656 expires() const;
657
664 getJson() const;
665
673 {
674 shared_lock read_lock{mutex_};
676 }
677
683 getTrustedMasterKeys() const;
684
690 getListThreshold() const;
691
697 getNegativeUNL() const;
698
703 void
704 setNegativeUNL(hash_set<PublicKey> const& negUnl);
705
714 std::vector<std::shared_ptr<STValidation>>&& validations) const;
715
716private:
719 count(shared_lock const&) const;
720
729 bool
730 trusted(shared_lock const&, PublicKey const& identity) const;
731
743 getTrustedKey(shared_lock const&, PublicKey const& identity) const;
744
755 expires(shared_lock const&) const;
756
779 PublisherListStats
780 applyList(
781 std::string const& globalManifest,
782 std::optional<std::string> const& localManifest,
783 std::string const& blob,
784 std::string const& signature,
785 std::uint32_t version,
786 std::string siteUri,
787 std::optional<uint256> const& hash,
788 lock_guard const&);
789
790 // This function updates the keyListings_ counts for all the trusted
791 // master keys
792 void
794 PublicKey const& pubKey,
795 PublisherList const& current,
796 std::vector<PublicKey> const& oldList,
797 lock_guard const&);
798
799 static void
802 PublisherListCollection const& lists);
803
805 buildBlobInfos(PublisherListCollection const& lists);
806
807 static void
809 PublicKey const& publisherKey,
810 PublisherListCollection const& lists,
811 std::size_t maxSequence,
812 uint256 const& hash,
813 Overlay& overlay,
814 HashRouter& hashRouter,
816
817 static void
819 Peer& peer,
820 std::uint64_t peerSequence,
821 PublicKey const& publisherKey,
822 std::size_t maxSequence,
823 std::uint32_t rawVersion,
824 std::string const& rawManifest,
827 HashRouter& hashRouter,
829
832 boost::filesystem::path
833 getCacheFileName(lock_guard const&, PublicKey const& pubKey) const;
834
838 static Json::Value
840 std::string const& pubKey,
841 PublisherListCollection const& pubCollection,
843
847 static Json::Value
849 std::string const& pubKey,
850 PublisherListCollection const& pubCollection,
851 std::optional<std::uint32_t> forceVersion,
853
854 template <class Hasher>
855 friend void
857 {
858 using beast::hash_append;
860 }
861
864 void
865 cacheValidatorFile(lock_guard const& lock, PublicKey const& pubKey) const;
866
876 verify(
877 lock_guard const&,
878 Json::Value& list,
879 std::string const& manifest,
880 std::string const& blob,
881 std::string const& signature);
882
893 bool
895 lock_guard const&,
896 PublicKey const& publisherKey,
897 PublisherStatus reason);
898
911 std::size_t unlSize,
912 std::size_t effectiveUnlSize,
913 std::size_t seenSize);
914};
915
916// hashing helpers
917template <class Hasher>
918void
919hash_append(Hasher& h, ValidatorBlobInfo const& blobInfo)
920{
921 using beast::hash_append;
922 hash_append(h, blobInfo.blob, blobInfo.signature);
923 if (blobInfo.manifest)
924 {
925 hash_append(h, *blobInfo.manifest);
926 }
927}
928
929template <class Hasher>
930void
932{
933 for (auto const& item : blobs)
934 hash_append(h, item);
935}
936
937template <class Hasher>
938void
940{
941 for (auto const& [_, item] : blobs)
942 {
943 (void)_;
944 hash_append(h, item);
945 }
946}
947
948} // namespace ripple
949
950namespace protocol {
951
952template <class Hasher>
953void
954hash_append(Hasher& h, TMValidatorList const& msg)
955{
956 using beast::hash_append;
957 hash_append(h, msg.manifest(), msg.blob(), msg.signature(), msg.version());
958}
959
960template <class Hasher>
961void
962hash_append(Hasher& h, TMValidatorListCollection const& msg)
963{
964 using beast::hash_append;
966 h,
967 msg.manifest(),
969 msg.version());
970}
971
972} // namespace protocol
973
974#endif
Represents a JSON value.
Definition: json_value.h:148
A generic endpoint for log messages.
Definition: Journal.h:60
typename Clock::time_point time_point
Routing table for objects identified by hash.
Definition: HashRouter.h:54
Remembers manifests with the highest sequence number.
Definition: Manifest.h:256
std::chrono::time_point< NetClock > time_point
Definition: chrono.h:69
Provides server functionality for clients.
Definition: NetworkOPs.h:87
Manages the set of connected peers.
Definition: Overlay.h:48
Represents a peer connection in the overlay.
A public key.
Definition: PublicKey.h:62
Manages various times used by the server.
Definition: TimeKeeper.h:32
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
TimeKeeper & timeKeeper_
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.
std::size_t listThreshold_
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.
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_
boost::shared_mutex mutex_
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::pair< ListDisposition, std::optional< PublicKey > > verify(lock_guard const &, Json::Value &list, std::string const &manifest, std::string const &blob, std::string const &signature)
Check response for trusted valid published list.
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_
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.
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.
static const std::string filePrefix_
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)
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.
Definition: hash_append.h:237
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:26
void hash_append(Hasher &h, Slice const &v)
Definition: Slice.h:199
@ 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:630
constexpr std::size_t maximiumMessageSize
Definition: Message.h:33
@ 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
std::optional< std::size_t > maxSequence
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::vector< PublicKey > list
std::optional< std::string > rawManifest
TimeKeeper::time_point validUntil
TimeKeeper::time_point validFrom
std::vector< std::string > manifests