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
27#include <xrpl/basics/Log.h>
28#include <xrpl/basics/UnorderedContainers.h>
29#include <xrpl/crypto/csprng.h>
30#include <xrpl/json/json_value.h>
31#include <xrpl/protocol/PublicKey.h>
32
33#include <boost/thread/shared_mutex.hpp>
34
35#include <mutex>
36#include <shared_mutex>
37
38namespace protocol {
39class TMValidatorList;
40class TMValidatorListCollection;
41} // namespace protocol
42
43namespace ripple {
44
45class Overlay;
46class HashRouter;
47class Message;
48class NetworkOPs;
49class Peer;
50class STValidation;
51
52/* Entries in this enum are ordered by "desirability".
53 The "better" dispositions have lower values than the
54 "worse" dispositions */
55enum class ListDisposition {
57 accepted = 0,
58
60 expired,
61
63 pending,
64
67
70
72 stale,
73
76
79
82};
83
84/* Entries in this enum are ordered by "desirability".
85 The "better" dispositions have lower values than the
86 "worse" dispositions */
87enum class PublisherStatus {
88 // Publisher has provided a valid file
89 available = 0,
90
91 // Current list is expired without replacement
92 expired,
93
94 // No file seen yet
96
97 // Publisher has revoked their manifest key
98 revoked,
99
100};
101
103to_string(ListDisposition disposition);
104
114
117{
118 // base-64 encoded JSON containing the validator list.
120 // hex-encoded signature of the blob using the publisher's signing key
122 // base-64 or hex-encoded manifest containing the publisher's master and
123 // signing public keys
125};
126
173{
175 {
176 explicit PublisherList() = default;
177
184 // base-64 encoded JSON containing the validator list.
186 // hex-encoded signature of the blob using the publisher's signing key
188 // base-64 or hex-encoded manifest containing the publisher's master and
189 // signing public keys
192 };
193
195 {
197 /*
198 The `current` VL is the one which
199 1. Has the largest sequence number that
200 2. Has ever been effective (the effective date is absent or in the
201 past).
202 If this VL has expired, all VLs with previous sequence numbers
203 will also be considered expired, and thus there will be no valid VL
204 until one with a larger sequence number becomes effective. This is to
205 prevent allowing old VLs to reactivate.
206 */
208 /*
209 The `remaining` list holds any relevant VLs which have a larger sequence
210 number than current. By definition they will all have an effective date
211 in the future. Relevancy will be determined by sorting the VLs by
212 sequence number, then iterating over the list and removing any VLs for
213 which the following VL (ignoring gaps) has the same or earlier effective
214 date.
215 */
218 // The hash of the full set if sent in a single message
222 };
223
227 boost::filesystem::path const dataPath_;
232
235
236 // Published lists stored by publisher master public key
238
239 // Listed master public keys with the number of lists they appear on
241
242 // The current list of trusted master keys
244
245 // Minimum number of lists on which a trusted validator must appear on
247
248 // The current list of trusted signing keys. For those validators using
249 // a manifest, the signing key is the ephemeral key. For the ones using
250 // a seed, the signing key is the same as the master key.
252
254
255 // The below variable contains the Publisher list specified in the local
256 // config file under the title of SECTION_VALIDATORS or [validators].
257 // This list is not associated with the masterKey of any publisher.
258
259 // Appropos PublisherListCollection fields, localPublisherList does not
260 // have any "remaining" manifests. It is assumed to be perennially
261 // "available". The "validUntil" field is set to the highest possible
262 // value of the field, hence this list is always valid.
264
265 // The master public keys of the current negative UNL
267
268 // Currently supported versions of publisher list format
269 static constexpr std::uint32_t supportedListVersions[]{1, 2};
270 // In the initial release, to prevent potential abuse and attacks, any VL
271 // collection with more than 5 entries will be considered malformed.
272 static constexpr std::size_t maxSupportedBlobs = 5;
273 // Prefix of the file name used to store cache files.
275
276public:
278 ManifestCache& validatorManifests,
279 ManifestCache& publisherManifests,
280 TimeKeeper& timeKeeper,
281 std::string const& databasePath,
284 ~ValidatorList() = default;
285
292 {
293 explicit PublisherListStats() = default;
297 PublicKey key,
298 PublisherStatus stat,
299 std::size_t seq);
300
302 bestDisposition() const;
304 worstDisposition() const;
305 void
307
308 // Tracks the dispositions of each processed list and how many times it
309 // occurred
314 };
315
317 {
318 explicit MessageWithHash() = default;
319 explicit MessageWithHash(
320 std::shared_ptr<Message> const& message_,
321 uint256 hash_,
322 std::size_t num_);
326 };
327
345 bool
346 load(
347 std::optional<PublicKey> const& localSigningKey,
348 std::vector<std::string> const& configKeys,
349 std::vector<std::string> const& publisherKeys,
350 std::optional<std::size_t> listThreshold = {});
351
358 parseBlobs(std::uint32_t version, Json::Value const& body);
359
361 parseBlobs(protocol::TMValidatorList const& body);
362
364 parseBlobs(protocol::TMValidatorListCollection const& body);
365
366 static void
368 Peer& peer,
369 std::uint64_t peerSequence,
370 PublicKey const& publisherKey,
371 std::size_t maxSequence,
372 std::uint32_t rawVersion,
373 std::string const& rawManifest,
375 HashRouter& hashRouter,
377
378 [[nodiscard]] static std::pair<std::size_t, std::size_t>
380 std::size_t messageVersion,
381 std::uint64_t peerSequence,
382 std::size_t maxSequence,
383 std::uint32_t rawVersion,
384 std::string const& rawManifest,
388
418 PublisherListStats
420 std::string const& manifest,
421 std::uint32_t version,
423 std::string siteUri,
424 uint256 const& hash,
425 Overlay& overlay,
426 HashRouter& hashRouter,
427 NetworkOPs& networkOPs);
428
449 PublisherListStats
451 std::string const& manifest,
452 std::uint32_t version,
454 std::string siteUri,
455 std::optional<uint256> const& hash = {});
456
457 /* Attempt to read previously stored list files. Expected to only be
458 called when loading from URL fails.
459
460 @return A list of valid file:// URLs, if any.
461
462 @par Thread Safety
463
464 May be called concurrently
465 */
467 loadLists();
468
484 TrustChanges
486 hash_set<NodeID> const& seenValidators,
487 NetClock::time_point closeTime,
488 NetworkOPs& ops,
489 Overlay& overlay,
490 HashRouter& hashRouter);
491
506 quorum() const
507 {
508 return quorum_;
509 }
510
519 bool
520 trusted(PublicKey const& identity) const;
521
530 bool
531 listed(PublicKey const& identity) const;
532
544 getTrustedKey(PublicKey const& identity) const;
545
557 getListedKey(PublicKey const& identity) const;
558
567 bool
568 trustedPublisher(PublicKey const& identity) const;
569
578 localPublicKey() const;
579
595 void
596 for_each_listed(std::function<void(PublicKey const&, bool)> func) const;
597
625 void
627 std::function<void(
628 std::string const& manifest,
629 std::uint32_t version,
631 PublicKey const& pubKey,
632 std::size_t maxSequence,
633 uint256 const& hash)> func) const;
634
640 std::string_view pubKey,
641 std::optional<std::uint32_t> forceVersion = {});
642
645 count() const;
646
657 expires() const;
658
665 getJson() const;
666
674 {
675 shared_lock read_lock{mutex_};
677 }
678
684 getTrustedMasterKeys() const;
685
691 getListThreshold() const;
692
698 getNegativeUNL() const;
699
704 void
705 setNegativeUNL(hash_set<PublicKey> const& negUnl);
706
715 std::vector<std::shared_ptr<STValidation>>&& validations) const;
716
717private:
720 count(shared_lock const&) const;
721
730 bool
731 trusted(shared_lock const&, PublicKey const& identity) const;
732
744 getTrustedKey(shared_lock const&, PublicKey const& identity) const;
745
756 expires(shared_lock const&) const;
757
780 PublisherListStats
781 applyList(
782 std::string const& globalManifest,
783 std::optional<std::string> const& localManifest,
784 std::string const& blob,
785 std::string const& signature,
786 std::uint32_t version,
787 std::string siteUri,
788 std::optional<uint256> const& hash,
789 lock_guard const&);
790
791 // This function updates the keyListings_ counts for all the trusted
792 // master keys
793 void
795 PublicKey const& pubKey,
796 PublisherList const& current,
797 std::vector<PublicKey> const& oldList,
798 lock_guard const&);
799
800 static void
803 PublisherListCollection const& lists);
804
806 buildBlobInfos(PublisherListCollection const& lists);
807
808 static void
810 PublicKey const& publisherKey,
811 PublisherListCollection const& lists,
812 std::size_t maxSequence,
813 uint256 const& hash,
814 Overlay& overlay,
815 HashRouter& hashRouter,
817
818 static void
820 Peer& peer,
821 std::uint64_t peerSequence,
822 PublicKey const& publisherKey,
823 std::size_t maxSequence,
824 std::uint32_t rawVersion,
825 std::string const& rawManifest,
828 HashRouter& hashRouter,
830
833 boost::filesystem::path
834 getCacheFileName(lock_guard const&, PublicKey const& pubKey) const;
835
839 static Json::Value
841 std::string const& pubKey,
842 PublisherListCollection const& pubCollection,
844
848 static Json::Value
850 std::string const& pubKey,
851 PublisherListCollection const& pubCollection,
852 std::optional<std::uint32_t> forceVersion,
854
855 template <class Hasher>
856 friend void
862
865 void
866 cacheValidatorFile(lock_guard const& lock, PublicKey const& pubKey) const;
867
877 verify(
878 lock_guard const&,
879 Json::Value& list,
881 std::string const& blob,
882 std::string const& signature);
883
894 bool
896 lock_guard const&,
897 PublicKey const& publisherKey,
898 PublisherStatus reason);
899
912 std::size_t unlSize,
913 std::size_t effectiveUnlSize,
914 std::size_t seenSize);
915};
916
917// hashing helpers
918template <class Hasher>
919void
920hash_append(Hasher& h, ValidatorBlobInfo const& blobInfo)
921{
922 using beast::hash_append;
923 hash_append(h, blobInfo.blob, blobInfo.signature);
924 if (blobInfo.manifest)
925 {
926 hash_append(h, *blobInfo.manifest);
927 }
928}
929
930template <class Hasher>
931void
933{
934 for (auto const& item : blobs)
935 hash_append(h, item);
936}
937
938template <class Hasher>
939void
941{
942 for (auto const& [_, item] : blobs)
943 {
944 (void)_;
945 hash_append(h, item);
946 }
947}
948
949} // namespace ripple
950
951namespace protocol {
952
953template <class Hasher>
954void
955hash_append(Hasher& h, TMValidatorList const& msg)
956{
957 using beast::hash_append;
958 hash_append(h, msg.manifest(), msg.blob(), msg.signature(), msg.version());
959}
960
961template <class Hasher>
962void
963hash_append(Hasher& h, TMValidatorListCollection const& msg)
964{
965 using beast::hash_append;
967 h,
968 msg.manifest(),
970 msg.version());
971}
972
973} // namespace protocol
974
975#endif
Represents a JSON value.
Definition json_value.h:149
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:97
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:89
Manages the set of connected peers.
Definition Overlay.h:49
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
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:25
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:34
@ 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