mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
List all trusted validator keys under single config section:
Trusted master public keys can be listed under either [validators] or [validator_keys] config sections. All keys listed under [validators] are added to permanent trusted keys list regardless of key type. A master public key is moved from permanent key list to manifest cache when one of its manifests is received. This allows rippled operators to list all trusted keys under the [validators] config section.
This commit is contained in:
@@ -38,6 +38,15 @@ private:
|
||||
randomSecretKey());
|
||||
}
|
||||
|
||||
static
|
||||
PublicKey
|
||||
randomMasterKey ()
|
||||
{
|
||||
return derivePublicKey (
|
||||
KeyType::ed25519,
|
||||
randomSecretKey());
|
||||
}
|
||||
|
||||
static
|
||||
bool
|
||||
isPresent (
|
||||
@@ -60,6 +69,7 @@ private:
|
||||
auto validators = std::make_unique <ValidatorList> (beast::Journal ());
|
||||
|
||||
std::vector<PublicKey> network;
|
||||
network.reserve(8);
|
||||
|
||||
while (network.size () != 8)
|
||||
network.push_back (randomNode());
|
||||
@@ -86,13 +96,13 @@ private:
|
||||
|
||||
// Correct configuration
|
||||
s1.append (format (network[0]));
|
||||
s1.append (format (network[1]) + " Comment");
|
||||
s1.append (format (network[2]) + " Multi Word Comment");
|
||||
s1.append (format (network[3]) + " Leading Whitespace");
|
||||
s1.append (format (network[4]) + " Trailing Whitespace ");
|
||||
s1.append (format (network[5]) + " Leading & Trailing Whitespace ");
|
||||
s1.append (format (network[6]) + " Leading, Trailing & Internal Whitespace ");
|
||||
s1.append (format (network[7]) + " ");
|
||||
s1.append (format (network[1], " Comment"));
|
||||
s1.append (format (network[2], " Multi Word Comment"));
|
||||
s1.append (format (network[3], " Leading Whitespace"));
|
||||
s1.append (format (network[4], " Trailing Whitespace "));
|
||||
s1.append (format (network[5], " Leading & Trailing Whitespace "));
|
||||
s1.append (format (network[6], " Leading, Trailing & Internal Whitespace "));
|
||||
s1.append (format (network[7], " "));
|
||||
|
||||
expect (validators->load (s1));
|
||||
|
||||
@@ -123,6 +133,17 @@ private:
|
||||
expect (!validators->load (s5));
|
||||
expect (!validators->trusted (node1));
|
||||
expect (!validators->trusted (node2));
|
||||
|
||||
// Add Ed25519 master public keys to permanent validators list
|
||||
auto const masterNode1 = randomMasterKey ();
|
||||
auto const masterNode2 = randomMasterKey ();
|
||||
|
||||
Section s6;
|
||||
s6.append (format (masterNode1));
|
||||
s6.append (format (masterNode2, " Comment"));
|
||||
expect (validators->load (s6));
|
||||
expect (validators->trusted (masterNode1));
|
||||
expect (validators->trusted (masterNode2));
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -206,6 +206,12 @@ ManifestCache::configManifest (
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ManifestCache::trusted (PublicKey const& identity) const
|
||||
{
|
||||
return map_.count(identity);
|
||||
}
|
||||
|
||||
void
|
||||
ManifestCache::addTrustedKey (PublicKey const& pk, std::string comment)
|
||||
{
|
||||
@@ -222,6 +228,13 @@ ManifestCache::addTrustedKey (PublicKey const& pk, std::string comment)
|
||||
value.comment = std::move(comment);
|
||||
}
|
||||
|
||||
std::size_t
|
||||
ManifestCache::size () const
|
||||
{
|
||||
std::lock_guard <std::mutex> lock (mutex_);
|
||||
return map_.size ();
|
||||
}
|
||||
|
||||
ManifestDisposition
|
||||
ManifestCache::canApply (PublicKey const& pk, std::uint32_t seq,
|
||||
beast::Journal journal) const
|
||||
@@ -263,6 +276,16 @@ ManifestDisposition
|
||||
ManifestCache::applyManifest (
|
||||
Manifest m, ValidatorList& unl, beast::Journal journal)
|
||||
{
|
||||
/*
|
||||
Move master public key from permanent trusted key list
|
||||
to manifest cache.
|
||||
*/
|
||||
if (auto unlComment = unl.member (m.masterKey))
|
||||
{
|
||||
addTrustedKey (m.masterKey, *unlComment);
|
||||
unl.removePermanentKey (m.masterKey);
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (mutex_);
|
||||
|
||||
@@ -388,6 +411,11 @@ void ManifestCache::load (
|
||||
{
|
||||
Throw<std::runtime_error> ("Unverifiable manifest in db");
|
||||
}
|
||||
|
||||
// Remove master public key from permanent trusted key list
|
||||
if (unl.trusted(mo->masterKey))
|
||||
unl.removePermanentKey (mo->masterKey);
|
||||
|
||||
// add trusted key
|
||||
map_[mo->masterKey];
|
||||
|
||||
|
||||
@@ -168,8 +168,17 @@ public:
|
||||
|
||||
void configManifest (Manifest m, ValidatorList& unl, beast::Journal journal);
|
||||
|
||||
/** Determines whether a node is in the trusted master key list */
|
||||
bool
|
||||
trusted (
|
||||
PublicKey const& identity) const;
|
||||
|
||||
void addTrustedKey (PublicKey const& pk, std::string comment);
|
||||
|
||||
/** The number of installed trusted master keys */
|
||||
std::size_t
|
||||
size () const;
|
||||
|
||||
ManifestDisposition
|
||||
applyManifest (
|
||||
Manifest m, ValidatorList& unl, beast::Journal journal);
|
||||
|
||||
@@ -438,7 +438,8 @@ OverlayImpl::setupValidatorKeyManifests (BasicConfig const& config,
|
||||
journal_);
|
||||
|
||||
if (!loaded)
|
||||
Throw<std::runtime_error> ("Unable to load validator keys");
|
||||
Throw<std::runtime_error> (
|
||||
"Unable to load keys from [validator_keys]");
|
||||
|
||||
auto const validation_manifest =
|
||||
config.section ("validation_manifest");
|
||||
|
||||
@@ -36,6 +36,20 @@ namespace tests {
|
||||
class manifest_test : public ripple::TestSuite
|
||||
{
|
||||
private:
|
||||
static PublicKey randomNode ()
|
||||
{
|
||||
return derivePublicKey (
|
||||
KeyType::secp256k1,
|
||||
randomSecretKey());
|
||||
}
|
||||
|
||||
static PublicKey randomMasterKey ()
|
||||
{
|
||||
return derivePublicKey (
|
||||
KeyType::ed25519,
|
||||
randomSecretKey());
|
||||
}
|
||||
|
||||
static void cleanupDatabaseDir (boost::filesystem::path const& dbPath)
|
||||
{
|
||||
using namespace boost::filesystem;
|
||||
@@ -122,7 +136,95 @@ public:
|
||||
return Manifest (m.serialized, m.masterKey, m.signingKey, m.sequence);
|
||||
}
|
||||
|
||||
void testLoadStore (ManifestCache const& m, ValidatorList& unl)
|
||||
|
||||
void
|
||||
testConfigLoad ()
|
||||
{
|
||||
testcase ("Config Load");
|
||||
|
||||
ManifestCache cache;
|
||||
beast::Journal journal;
|
||||
|
||||
std::vector<PublicKey> network;
|
||||
network.reserve(8);
|
||||
|
||||
while (network.size () != 8)
|
||||
network.push_back (randomMasterKey());
|
||||
|
||||
auto format = [](
|
||||
PublicKey const &publicKey,
|
||||
char const* comment = nullptr)
|
||||
{
|
||||
auto ret = toBase58(
|
||||
TokenType::TOKEN_NODE_PUBLIC,
|
||||
publicKey);
|
||||
|
||||
if (comment)
|
||||
ret += comment;
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
Section s1;
|
||||
|
||||
// Correct (empty) configuration
|
||||
expect (cache.loadValidatorKeys (s1, journal));
|
||||
expect (cache.size() == 0);
|
||||
|
||||
// Correct configuration
|
||||
s1.append (format (network[0]));
|
||||
s1.append (format (network[1], " Comment"));
|
||||
s1.append (format (network[2], " Multi Word Comment"));
|
||||
s1.append (format (network[3], " Leading Whitespace"));
|
||||
s1.append (format (network[4], " Trailing Whitespace "));
|
||||
s1.append (format (network[5], " Leading & Trailing Whitespace "));
|
||||
s1.append (format (network[6], " Leading, Trailing & Internal Whitespace "));
|
||||
s1.append (format (network[7], " "));
|
||||
|
||||
expect (cache.loadValidatorKeys (s1, journal));
|
||||
|
||||
for (auto const& n : network)
|
||||
expect (cache.trusted (n));
|
||||
|
||||
// Incorrect configurations:
|
||||
Section s2;
|
||||
s2.append ("NotAPublicKey");
|
||||
expect (!cache.loadValidatorKeys (s2, journal));
|
||||
|
||||
Section s3;
|
||||
s3.append (format (network[0], "!"));
|
||||
expect (!cache.loadValidatorKeys (s3, journal));
|
||||
|
||||
Section s4;
|
||||
s4.append (format (network[0], "! Comment"));
|
||||
expect (!cache.loadValidatorKeys (s4, journal));
|
||||
|
||||
// Check if we properly terminate when we encounter
|
||||
// a malformed or unparseable entry:
|
||||
auto const masterKey1 = randomMasterKey();
|
||||
auto const masterKey2 = randomMasterKey ();
|
||||
|
||||
Section s5;
|
||||
s5.append (format (masterKey1, "XXX"));
|
||||
s5.append (format (masterKey2));
|
||||
expect (!cache.loadValidatorKeys (s5, journal));
|
||||
expect (!cache.trusted (masterKey1));
|
||||
expect (!cache.trusted (masterKey2));
|
||||
|
||||
// Reject secp256k1 permanent validator keys
|
||||
auto const node1 = randomNode ();
|
||||
auto const node2 = randomNode ();
|
||||
|
||||
Section s6;
|
||||
s6.append (format (node1));
|
||||
s6.append (format (node2, " Comment"));
|
||||
expect (!cache.loadValidatorKeys (s6, journal));
|
||||
expect (!cache.trusted (node1));
|
||||
expect (!cache.trusted (node2));
|
||||
}
|
||||
|
||||
void testLoadStore (ManifestCache const& m, ValidatorList& unl,
|
||||
PublicKey& pk)
|
||||
{
|
||||
testcase ("load/store");
|
||||
|
||||
@@ -138,7 +240,14 @@ public:
|
||||
|
||||
ManifestCache loaded;
|
||||
beast::Journal journal;
|
||||
|
||||
// load should remove master key from permanent key list
|
||||
expect (m.trusted(pk));
|
||||
expect (unl.insertPermanentKey(pk, "trusted key"));
|
||||
expect (unl.trusted(pk));
|
||||
loaded.load (dbCon, unl, journal);
|
||||
expect (!unl.trusted(pk));
|
||||
expect (loaded.trusted(pk));
|
||||
|
||||
auto getPopulatedManifests =
|
||||
[](ManifestCache const& cache) -> std::vector<Manifest const*>
|
||||
@@ -206,6 +315,7 @@ public:
|
||||
ManifestCache cache;
|
||||
beast::Journal journal;
|
||||
auto unl = std::make_unique<ValidatorList> (journal);
|
||||
PublicKey pk;
|
||||
{
|
||||
testcase ("apply");
|
||||
auto const accepted = ManifestDisposition::accepted;
|
||||
@@ -246,8 +356,22 @@ public:
|
||||
|
||||
expect (!ripple::make_Manifest(fake));
|
||||
expect (cache.applyManifest (clone (s_b2), *unl, journal) == invalid);
|
||||
|
||||
// When trusted permanent key is found as manifest master key
|
||||
// move to manifest cache
|
||||
auto const sk_c = randomSecretKey();
|
||||
pk = derivePublicKey(KeyType::ed25519, sk_c);
|
||||
auto const kp_c = randomKeyPair(KeyType::secp256k1);
|
||||
auto const s_c0 = make_Manifest (KeyType::ed25519, sk_c, kp_c.first, 0);
|
||||
expect (unl->insertPermanentKey(pk, "trusted key"));
|
||||
expect (unl->trusted(pk));
|
||||
expect (!cache.trusted(pk));
|
||||
expect (cache.applyManifest(clone (s_c0), *unl, journal) == accepted);
|
||||
expect (!unl->trusted(pk));
|
||||
expect (cache.trusted(pk));
|
||||
}
|
||||
testLoadStore (cache, *unl);
|
||||
testConfigLoad();
|
||||
testLoadStore (cache, *unl, pk);
|
||||
testGetSignature ();
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user