From d57db1f6d24f41f46f2320198db663e8ebed4e0a Mon Sep 17 00:00:00 2001 From: Devon White Date: Wed, 10 Nov 2021 17:58:45 -0600 Subject: [PATCH] Specify source type for stored UNLs --- src/ripple/app/misc/ValidatorList.h | 30 +++++++++----- src/ripple/app/misc/impl/ValidatorList.cpp | 47 +++++++++++++++++----- src/ripple/protocol/jss.h | 2 + src/ripple/rpc/handlers/Validators.cpp | 2 +- src/test/app/ValidatorList_test.cpp | 8 ++-- 5 files changed, 64 insertions(+), 25 deletions(-) diff --git a/src/ripple/app/misc/ValidatorList.h b/src/ripple/app/misc/ValidatorList.h index 0d7605fc09d..03b0df876c8 100644 --- a/src/ripple/app/misc/ValidatorList.h +++ b/src/ripple/app/misc/ValidatorList.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -180,7 +181,10 @@ class ValidatorList std::size_t sequence; TimeKeeper::time_point validFrom; TimeKeeper::time_point validUntil; - std::string siteUri; + // the peer that provided the list, if applicable + std::string sourcePeer; + // the website or filesystem uri that provided the list, if applicable + std::string sourceUri; // base-64 encoded JSON containing the validator list. std::string rawBlob; // hex-encoded signature of the blob using the publisher's signing key @@ -382,7 +386,9 @@ class ValidatorList @param blobs Vector of BlobInfos representing one or more encoded validator lists and signatures (and optional manifests) - @param siteUri Uri of the site from which the list was validated + @param source The peer address, or site/file uri that provided the + lists. The formatting of this parameter is important as it is + used to determine the source type @param hash Hash of the data parameters @@ -406,7 +412,7 @@ class ValidatorList std::string const& manifest, std::uint32_t version, std::vector const& blobs, - std::string siteUri, + std::string source, uint256 const& hash, Overlay& overlay, HashRouter& hashRouter, @@ -419,14 +425,16 @@ class ValidatorList @param version Version of published list format @param blobs Vector of BlobInfos representing one or more encoded - validator lists and signatures (and optional manifests) + validator lists and signatures (and optional manifests) - @param siteUri Uri of the site from which the list was validated + @param source The peer address, or site/file uri that provided the + lists. The formatting of this parameter is important as it is + used to determine the source type @param hash Optional hash of the data parameters @return `ListDisposition::accepted`, plus some of the publisher - information, if list was successfully applied + information, if list was successfully applied @par Thread Safety @@ -437,7 +445,7 @@ class ValidatorList std::string const& manifest, std::uint32_t version, std::vector const& blobs, - std::string siteUri, + std::string source, std::optional const& hash = {}); /* Attempt to read previously stored list files. Expected to only be @@ -647,7 +655,7 @@ class ValidatorList May be called concurrently */ Json::Value - getJson() const; + getJson(std::optional context = std::nullopt) const; using QuorumKeys = std::pair>; /** Get the quorum and all of the trusted keys. @@ -743,7 +751,9 @@ class ValidatorList @param version Version of published list format - @param siteUri Uri of the site from which the list was validated + @param source The peer address, or site/file uri that provided the + lists. The formatting of this parameter is important as it is + used to determine the source type @param hash Optional hash of the data parameters. Defaults to uninitialized @@ -762,7 +772,7 @@ class ValidatorList std::string const& blob, std::string const& signature, std::uint32_t version, - std::string siteUri, + std::string source, std::optional const& hash, lock_guard const&); diff --git a/src/ripple/app/misc/impl/ValidatorList.cpp b/src/ripple/app/misc/impl/ValidatorList.cpp index 09f774f8af9..784f2a8ebc2 100644 --- a/src/ripple/app/misc/impl/ValidatorList.cpp +++ b/src/ripple/app/misc/impl/ValidatorList.cpp @@ -39,6 +39,23 @@ namespace ripple { +bool +isSite(std::string const& source) +{ + parsedURL parsed; + if (!parseUrl(parsed, source)) + // Assume that the source is a peer address in the + // event that parsing fails. + return false; + + const std::unordered_set schemes{"file", "http", "https"}; + + if (schemes.find(parsed.scheme) != schemes.end()) + return true; + + return false; +} + std::string to_string(ListDisposition disposition) { @@ -870,14 +887,14 @@ ValidatorList::applyListsAndBroadcast( std::string const& manifest, std::uint32_t version, std::vector const& blobs, - std::string siteUri, + std::string source, uint256 const& hash, Overlay& overlay, HashRouter& hashRouter, NetworkOPs& networkOPs) { auto const result = - applyLists(manifest, version, blobs, std::move(siteUri), hash); + applyLists(manifest, version, blobs, std::move(source), hash); auto const disposition = result.bestDisposition(); if (disposition == ListDisposition::accepted) @@ -923,7 +940,7 @@ ValidatorList::applyLists( std::string const& manifest, std::uint32_t version, std::vector const& blobs, - std::string siteUri, + std::string source, std::optional const& hash /* = {} */) { if (std::count( @@ -943,7 +960,7 @@ ValidatorList::applyLists( blobInfo.blob, blobInfo.signature, version, - siteUri, + source, hash, lock); @@ -1063,7 +1080,7 @@ ValidatorList::applyList( std::string const& blob, std::string const& signature, std::uint32_t version, - std::string siteUri, + std::string source, std::optional const& hash, ValidatorList::lock_guard const& lock) { @@ -1137,7 +1154,9 @@ ValidatorList::applyList( list.isMember(jss::effective) ? list[jss::effective].asUInt() : 0}}; publisher.validUntil = TimeKeeper::time_point{ TimeKeeper::duration{list[jss::expiration].asUInt()}}; - publisher.siteUri = std::move(siteUri); + auto& sourceField = + isSite(source) ? publisher.sourceUri : publisher.sourcePeer; + sourceField = std::move(source); publisher.rawBlob = blob; publisher.rawSignature = signature; publisher.rawManifest = localManifest; @@ -1504,7 +1523,7 @@ ValidatorList::expires() const } Json::Value -ValidatorList::getJson() const +ValidatorList::getJson(std::optional context) const { Json::Value res(Json::objectValue); @@ -1563,9 +1582,17 @@ ValidatorList::getJson() const curr[jss::available] = pubCollection.status == PublisherStatus::available; - auto appendList = [](PublisherList const& publisherList, - Json::Value& target) { - target[jss::uri] = publisherList.siteUri; + auto appendList = [&context]( + PublisherList const& publisherList, + Json::Value& target) { + if ((context && context->apiVersion == 1) || !context) + target[jss::uri] = publisherList.sourceUri.empty() + ? publisherList.sourcePeer + : publisherList.sourceUri; + if (!publisherList.sourceUri.empty()) + target[jss::source_uri] = publisherList.sourceUri; + if (!publisherList.sourcePeer.empty()) + target[jss::source_peer] = publisherList.sourcePeer; if (publisherList.validUntil != TimeKeeper::time_point{}) { target[jss::seq] = diff --git a/src/ripple/protocol/jss.h b/src/ripple/protocol/jss.h index 7283f16c97b..7a89163fc08 100644 --- a/src/ripple/protocol/jss.h +++ b/src/ripple/protocol/jss.h @@ -518,7 +518,9 @@ JSS(snapshot); // in: Subscribe JSS(source_account); // in: PathRequest, RipplePathFind JSS(source_amount); // in: PathRequest, RipplePathFind JSS(source_currencies); // in: PathRequest, RipplePathFind +JSS(source_peer); // out: ValidatorSites JSS(source_tag); // out: AccountChannels +JSS(source_uri); // out: ValidatorSites JSS(stand_alone); // out: NetworkOPs JSS(start); // in: TxHistory JSS(started); diff --git a/src/ripple/rpc/handlers/Validators.cpp b/src/ripple/rpc/handlers/Validators.cpp index bce9a311d13..7d1e350a032 100644 --- a/src/ripple/rpc/handlers/Validators.cpp +++ b/src/ripple/rpc/handlers/Validators.cpp @@ -31,7 +31,7 @@ doValidators(RPC::JsonContext& context) if (context.app.config().reporting()) return rpcError(rpcREPORTING_UNSUPPORTED); - return context.app.validators().getJson(); + return context.app.validators().getJson(context); } } // namespace ripple diff --git a/src/test/app/ValidatorList_test.cpp b/src/test/app/ValidatorList_test.cpp index 860b8fc1701..af381d278e2 100644 --- a/src/test/app/ValidatorList_test.cpp +++ b/src/test/app/ValidatorList_test.cpp @@ -476,7 +476,7 @@ class ValidatorList_test : public beast::unit_test::suite testcase("Apply list"); using namespace std::chrono_literals; - std::string const siteUri = "testApplyList.test"; + std::string const siteUri = "http://testApplyList.test"; auto checkAvailable = [this]( @@ -926,7 +926,7 @@ class ValidatorList_test : public beast::unit_test::suite testcase("GetAvailable"); using namespace std::chrono_literals; - std::string const siteUri = "testApplyList.test"; + std::string const siteUri = "http://testApplyList.test"; ManifestCache manifests; jtx::Env env(*this); @@ -1062,7 +1062,7 @@ class ValidatorList_test : public beast::unit_test::suite { testcase("Update trusted"); - std::string const siteUri = "testUpdateTrusted.test"; + std::string const siteUri = "http://testUpdateTrusted.test"; PublicKey emptyLocalKeyOuter; ManifestCache manifestsOuter; @@ -1615,7 +1615,7 @@ class ValidatorList_test : public beast::unit_test::suite { testcase("Expires"); - std::string const siteUri = "testExpires.test"; + std::string const siteUri = "http://testExpires.test"; jtx::Env env(*this); auto& app = env.app();