mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-04 11:15:56 +00:00
Use correct manifest cache when loading ValidatorList
This commit is contained in:
committed by
Nik Bougalis
parent
c71eb45240
commit
6bdc9e7b30
@@ -107,7 +107,7 @@ ValidatorList::load (
|
||||
|
||||
auto id = PublicKey(makeSlice(ret.first));
|
||||
|
||||
if (validatorManifests_.revoked (id))
|
||||
if (publisherManifests_.revoked (id))
|
||||
{
|
||||
JLOG (j_.warn()) <<
|
||||
"Configured validator list publisher key is revoked: " << key;
|
||||
|
||||
@@ -383,68 +383,72 @@ ValidatorSite::onSiteFetch(
|
||||
detail::response_type&& res,
|
||||
std::size_t siteIdx)
|
||||
{
|
||||
bool shouldRetry = false;
|
||||
{
|
||||
std::lock_guard <std::mutex> lock_sites{sites_mutex_};
|
||||
try
|
||||
auto onError = [&](std::string const& errMsg, bool retry)
|
||||
{
|
||||
if (ec)
|
||||
{
|
||||
JLOG (j_.warn()) <<
|
||||
sites_[siteIdx].lastRefreshStatus.emplace(
|
||||
Site::Status{clock_type::now(),
|
||||
ListDisposition::invalid,
|
||||
errMsg});
|
||||
if (retry)
|
||||
sites_[siteIdx].nextRefresh =
|
||||
clock_type::now() + ERROR_RETRY_INTERVAL;
|
||||
};
|
||||
if (ec)
|
||||
{
|
||||
JLOG (j_.warn()) <<
|
||||
"Problem retrieving from " <<
|
||||
sites_[siteIdx].activeResource->uri <<
|
||||
" " <<
|
||||
ec.value() <<
|
||||
":" <<
|
||||
ec.message();
|
||||
shouldRetry = true;
|
||||
throw std::runtime_error{"fetch error"};
|
||||
}
|
||||
|
||||
using namespace boost::beast::http;
|
||||
switch (res.result())
|
||||
{
|
||||
case status::ok:
|
||||
parseJsonResponse(res, siteIdx, lock_sites);
|
||||
break;
|
||||
case status::moved_permanently :
|
||||
case status::permanent_redirect :
|
||||
case status::found :
|
||||
case status::temporary_redirect :
|
||||
{
|
||||
auto newLocation = processRedirect (res, siteIdx, lock_sites);
|
||||
assert(newLocation);
|
||||
// for perm redirects, also update our starting URI
|
||||
if (res.result() == status::moved_permanently ||
|
||||
res.result() == status::permanent_redirect)
|
||||
{
|
||||
sites_[siteIdx].startingResource = newLocation;
|
||||
}
|
||||
makeRequest(newLocation, siteIdx, lock_sites);
|
||||
return; // we are still fetching, so skip
|
||||
// state update/notify below
|
||||
}
|
||||
default:
|
||||
{
|
||||
JLOG (j_.warn()) <<
|
||||
"Request for validator list at " <<
|
||||
sites_[siteIdx].activeResource->uri <<
|
||||
" returned bad status: " <<
|
||||
res.result_int();
|
||||
shouldRetry = true;
|
||||
throw std::runtime_error{"bad result code"};
|
||||
}
|
||||
}
|
||||
onError("fetch error", true);
|
||||
}
|
||||
catch (std::exception& ex)
|
||||
else
|
||||
{
|
||||
sites_[siteIdx].lastRefreshStatus.emplace(
|
||||
Site::Status{clock_type::now(),
|
||||
ListDisposition::invalid,
|
||||
ex.what()});
|
||||
if (shouldRetry)
|
||||
sites_[siteIdx].nextRefresh =
|
||||
clock_type::now() + ERROR_RETRY_INTERVAL;
|
||||
try
|
||||
{
|
||||
using namespace boost::beast::http;
|
||||
switch (res.result())
|
||||
{
|
||||
case status::ok:
|
||||
parseJsonResponse(res, siteIdx, lock_sites);
|
||||
break;
|
||||
case status::moved_permanently :
|
||||
case status::permanent_redirect :
|
||||
case status::found :
|
||||
case status::temporary_redirect :
|
||||
{
|
||||
auto newLocation =
|
||||
processRedirect (res, siteIdx, lock_sites);
|
||||
assert(newLocation);
|
||||
// for perm redirects, also update our starting URI
|
||||
if (res.result() == status::moved_permanently ||
|
||||
res.result() == status::permanent_redirect)
|
||||
{
|
||||
sites_[siteIdx].startingResource = newLocation;
|
||||
}
|
||||
makeRequest(newLocation, siteIdx, lock_sites);
|
||||
return; // we are still fetching, so skip
|
||||
// state update/notify below
|
||||
}
|
||||
default:
|
||||
{
|
||||
JLOG (j_.warn()) <<
|
||||
"Request for validator list at " <<
|
||||
sites_[siteIdx].activeResource->uri <<
|
||||
" returned bad status: " <<
|
||||
res.result_int();
|
||||
onError("bad result code", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception& ex)
|
||||
{
|
||||
onError(ex.what(), false);
|
||||
}
|
||||
}
|
||||
sites_[siteIdx].activeResource.reset();
|
||||
}
|
||||
|
||||
@@ -355,6 +355,40 @@ private:
|
||||
for (auto const& key : keys)
|
||||
BEAST_EXPECT(trustedKeys->trustedPublisher (key));
|
||||
}
|
||||
{
|
||||
// Attempt to load a publisher key that has been revoked.
|
||||
// Should fail
|
||||
ManifestCache valManifests;
|
||||
ManifestCache pubManifests;
|
||||
auto trustedKeys = std::make_unique <ValidatorList> (
|
||||
valManifests, pubManifests, env.timeKeeper(), env.journal);
|
||||
|
||||
auto const pubRevokedSecret = randomSecretKey();
|
||||
auto const pubRevokedPublic =
|
||||
derivePublicKey(KeyType::ed25519, pubRevokedSecret);
|
||||
auto const pubRevokedSigning = randomKeyPair(KeyType::secp256k1);
|
||||
// make this manifest revoked (seq num = max)
|
||||
// -- thus should not be loaded
|
||||
pubManifests.applyManifest (*Manifest::make_Manifest (
|
||||
makeManifestString (
|
||||
pubRevokedPublic,
|
||||
pubRevokedSecret,
|
||||
pubRevokedSigning.first,
|
||||
pubRevokedSigning.second,
|
||||
std::numeric_limits<std::uint32_t>::max ())));
|
||||
|
||||
// this one is not revoked (and not in manifest cache at all.)
|
||||
auto legitKey = randomMasterKey();
|
||||
|
||||
std::vector<std::string> cfgPublishers = {
|
||||
strHex(pubRevokedPublic),
|
||||
strHex(legitKey) };
|
||||
BEAST_EXPECT(trustedKeys->load (
|
||||
emptyLocalKey, emptyCfgKeys, cfgPublishers));
|
||||
|
||||
BEAST_EXPECT(!trustedKeys->trustedPublisher (pubRevokedPublic));
|
||||
BEAST_EXPECT(trustedKeys->trustedPublisher (legitKey));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <test/jtx/TrustedPublisherServer.h>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <chrono>
|
||||
|
||||
namespace ripple {
|
||||
namespace test {
|
||||
@@ -165,6 +166,7 @@ private:
|
||||
std::string uri;
|
||||
std::string expectMsg;
|
||||
bool shouldFail;
|
||||
bool isRetry;
|
||||
};
|
||||
std::vector<publisher> servers;
|
||||
|
||||
@@ -191,6 +193,7 @@ private:
|
||||
servers.push_back({});
|
||||
auto& item = servers.back();
|
||||
item.shouldFail = ! cfg.second.empty();
|
||||
item.isRetry = cfg.first == "/bad-resource";
|
||||
item.expectMsg = cfg.second;
|
||||
item.list.reserve (listSize);
|
||||
while (item.list.size () < listSize)
|
||||
@@ -243,11 +246,21 @@ private:
|
||||
!= u.shouldFail, to_string(myStatus));
|
||||
if (u.shouldFail)
|
||||
{
|
||||
using namespace std::chrono;
|
||||
BEAST_EXPECTS(
|
||||
sink.strm_.str().find(u.expectMsg) != std::string::npos,
|
||||
sink.strm_.str());
|
||||
log << " -- Msg: " <<
|
||||
myStatus[jss::last_refresh_message].asString() << std::endl;
|
||||
std::stringstream nextRefreshStr
|
||||
{myStatus[jss::next_refresh_time].asString()};
|
||||
system_clock::time_point nextRefresh;
|
||||
date::from_stream (nextRefreshStr, "%Y-%b-%d %T", nextRefresh);
|
||||
BEAST_EXPECT(!nextRefreshStr.fail());
|
||||
auto now = system_clock::now();
|
||||
BEAST_EXPECTS(
|
||||
nextRefresh <= now + (u.isRetry ? seconds{30} : minutes{5}),
|
||||
"Now: " + to_string(now) + ", NR: " + nextRefreshStr.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user