mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Dynamize trusted validator list and quorum (RIPD-1220):
Instead of specifying a static list of trusted validators in the config or validators file, the configuration can now include trusted validator list publisher keys. The trusted validator list and quorum are now reset each consensus round using the latest validator lists and the list of recent validations seen. The minimum validation quorum is now only configurable via the command line.
This commit is contained in:
@@ -285,9 +285,9 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
std::string valFileContents (boost::optional<int> const& quorum)
|
||||
std::string valFileContents ()
|
||||
{
|
||||
static boost::format configContentsTemplate (R"rippleConfig(
|
||||
std::string configContents (R"rippleConfig(
|
||||
[validators]
|
||||
n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7
|
||||
n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj
|
||||
@@ -300,14 +300,11 @@ nHUhG1PgAG8H8myUENypM35JgfqXAKNQvRVVAFDRzJrny5eZN8d5
|
||||
nHBu9PTL9dn2GuZtdW4U2WzBwffyX9qsQCd9CNU4Z5YG3PQfViM8
|
||||
nHUPDdcdb2Y5DZAJne4c2iabFuAP3F34xZUgYQT2NH7qfkdapgnz
|
||||
|
||||
%1%
|
||||
|
||||
[validator_list_keys]
|
||||
03E74EE14CB525AFBB9F1B7D86CD58ECC4B91452294B42AB4E78F260BD905C091D
|
||||
030775A669685BD6ABCEBD80385921C7851783D991A8055FD21D2F3966C96F1B56
|
||||
)rippleConfig");
|
||||
|
||||
std::string quorumSection =
|
||||
quorum ? "[validation_quorum]\n" + to_string(*quorum) : "";
|
||||
return boost::str (
|
||||
configContentsTemplate % quorumSection);
|
||||
return configContents;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -321,7 +318,7 @@ private:
|
||||
public:
|
||||
ValidatorsTxtGuard (beast::unit_test::suite& test,
|
||||
path subDir, path const& validatorsFileName,
|
||||
boost::optional<int> const& quorum, bool useCounter = true)
|
||||
bool useCounter = true)
|
||||
: ConfigGuard (test, std::move (subDir), useCounter)
|
||||
{
|
||||
using namespace boost::filesystem;
|
||||
@@ -332,7 +329,7 @@ public:
|
||||
if (!exists (validatorsFile_))
|
||||
{
|
||||
std::ofstream o (validatorsFile_.string ());
|
||||
o << valFileContents (quorum);
|
||||
o << valFileContents ();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -392,9 +389,6 @@ port_wss_admin
|
||||
|
||||
[ssl_verify]
|
||||
0
|
||||
|
||||
[validation_quorum]
|
||||
3
|
||||
)rippleConfig");
|
||||
|
||||
c.loadFromString (toLoad);
|
||||
@@ -499,9 +493,8 @@ port_wss_admin
|
||||
}
|
||||
{
|
||||
// load should throw for invalid [validators_file]
|
||||
int const quorum = 3;
|
||||
detail::ValidatorsTxtGuard const vtg (
|
||||
*this, "test_cfg", "validators.cfg", quorum);
|
||||
*this, "test_cfg", "validators.cfg");
|
||||
path const invalidFile = current_path () / vtg.subdir ();
|
||||
boost::format cc ("[validators_file]\n%1%\n");
|
||||
std::string error;
|
||||
@@ -517,7 +510,7 @@ port_wss_admin
|
||||
BEAST_EXPECT(error == expectedError);
|
||||
}
|
||||
{
|
||||
// load validators and quorum from config
|
||||
// load validators from config into single section
|
||||
Config c;
|
||||
std::string toLoad(R"rippleConfig(
|
||||
[validators]
|
||||
@@ -528,53 +521,59 @@ n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C
|
||||
[validator_keys]
|
||||
nHUhG1PgAG8H8myUENypM35JgfqXAKNQvRVVAFDRzJrny5eZN8d5
|
||||
nHBu9PTL9dn2GuZtdW4U2WzBwffyX9qsQCd9CNU4Z5YG3PQfViM8
|
||||
|
||||
[validation_quorum]
|
||||
4
|
||||
)rippleConfig");
|
||||
c.loadFromString (toLoad);
|
||||
BEAST_EXPECT(c.legacy ("validators_file").empty ());
|
||||
BEAST_EXPECT(c.section (SECTION_VALIDATORS).values ().size () == 3);
|
||||
BEAST_EXPECT(c.section (SECTION_VALIDATOR_KEYS).values ().size () == 2);
|
||||
BEAST_EXPECT(c.VALIDATION_QUORUM == 4);
|
||||
BEAST_EXPECT(c.section (SECTION_VALIDATORS).values ().size () == 5);
|
||||
}
|
||||
{
|
||||
// load validator list keys from config
|
||||
Config c;
|
||||
std::string toLoad(R"rippleConfig(
|
||||
[validator_list_keys]
|
||||
021A99A537FDEBC34E4FCA03B39BEADD04299BB19E85097EC92B15A3518801E566
|
||||
)rippleConfig");
|
||||
c.loadFromString (toLoad);
|
||||
BEAST_EXPECT(
|
||||
c.section (SECTION_VALIDATOR_LIST_KEYS).values ().size () == 1);
|
||||
BEAST_EXPECT(
|
||||
c.section (SECTION_VALIDATOR_LIST_KEYS).values ()[0] ==
|
||||
"021A99A537FDEBC34E4FCA03B39BEADD04299BB19E85097EC92B15A3518801E566");
|
||||
}
|
||||
{
|
||||
// load from specified [validators_file] absolute path
|
||||
int const quorum = 3;
|
||||
detail::ValidatorsTxtGuard const vtg (
|
||||
*this, "test_cfg", "validators.cfg", quorum);
|
||||
*this, "test_cfg", "validators.cfg");
|
||||
BEAST_EXPECT(vtg.validatorsFileExists ());
|
||||
Config c;
|
||||
boost::format cc ("[validators_file]\n%1%\n");
|
||||
c.loadFromString (boost::str (cc % vtg.validatorsFile ()));
|
||||
BEAST_EXPECT(c.legacy ("validators_file") == vtg.validatorsFile ());
|
||||
BEAST_EXPECT(c.section (SECTION_VALIDATORS).values ().size () == 5);
|
||||
BEAST_EXPECT(c.section (SECTION_VALIDATOR_KEYS).values ().size () == 3);
|
||||
BEAST_EXPECT(c.VALIDATION_QUORUM == quorum);
|
||||
BEAST_EXPECT(c.section (SECTION_VALIDATORS).values ().size () == 8);
|
||||
BEAST_EXPECT(
|
||||
c.section (SECTION_VALIDATOR_LIST_KEYS).values ().size () == 2);
|
||||
}
|
||||
{
|
||||
// load from specified [validators_file] file name
|
||||
// in config directory
|
||||
int const quorum = 3;
|
||||
std::string const valFileName = "validators.txt";
|
||||
detail::ValidatorsTxtGuard const vtg (
|
||||
*this, "test_cfg", valFileName, quorum);
|
||||
*this, "test_cfg", valFileName);
|
||||
detail::RippledCfgGuard const rcg (
|
||||
*this, vtg.subdir (), "", valFileName, false);
|
||||
BEAST_EXPECT(vtg.validatorsFileExists ());
|
||||
BEAST_EXPECT(rcg.configFileExists ());
|
||||
auto const& c (rcg.config ());
|
||||
BEAST_EXPECT(c.legacy ("validators_file") == valFileName);
|
||||
BEAST_EXPECT(c.section (SECTION_VALIDATORS).values ().size () == 5);
|
||||
BEAST_EXPECT(c.section (SECTION_VALIDATOR_KEYS).values ().size () == 3);
|
||||
BEAST_EXPECT(c.VALIDATION_QUORUM == quorum);
|
||||
BEAST_EXPECT(c.section (SECTION_VALIDATORS).values ().size () == 8);
|
||||
BEAST_EXPECT(
|
||||
c.section (SECTION_VALIDATOR_LIST_KEYS).values ().size () == 2);
|
||||
}
|
||||
{
|
||||
// load from specified [validators_file] relative path
|
||||
// to config directory
|
||||
int const quorum = 3;
|
||||
detail::ValidatorsTxtGuard const vtg (
|
||||
*this, "test_cfg", "validators.txt", quorum);
|
||||
*this, "test_cfg", "validators.txt");
|
||||
auto const valFilePath = ".." / vtg.subdir() / "validators.txt";
|
||||
detail::RippledCfgGuard const rcg (
|
||||
*this, vtg.subdir (), "", valFilePath, false);
|
||||
@@ -582,63 +581,41 @@ nHBu9PTL9dn2GuZtdW4U2WzBwffyX9qsQCd9CNU4Z5YG3PQfViM8
|
||||
BEAST_EXPECT(rcg.configFileExists ());
|
||||
auto const& c (rcg.config ());
|
||||
BEAST_EXPECT(c.legacy ("validators_file") == valFilePath);
|
||||
BEAST_EXPECT(c.section (SECTION_VALIDATORS).values ().size () == 5);
|
||||
BEAST_EXPECT(c.section (SECTION_VALIDATOR_KEYS).values ().size () == 3);
|
||||
BEAST_EXPECT(c.VALIDATION_QUORUM == quorum);
|
||||
BEAST_EXPECT(c.section (SECTION_VALIDATORS).values ().size () == 8);
|
||||
BEAST_EXPECT(
|
||||
c.section (SECTION_VALIDATOR_LIST_KEYS).values ().size () == 2);
|
||||
}
|
||||
{
|
||||
// load from validators file in default location
|
||||
int const quorum = 3;
|
||||
detail::ValidatorsTxtGuard const vtg (
|
||||
*this, "test_cfg", "validators.txt", quorum);
|
||||
*this, "test_cfg", "validators.txt");
|
||||
detail::RippledCfgGuard const rcg (*this, vtg.subdir (),
|
||||
"", "", false);
|
||||
BEAST_EXPECT(vtg.validatorsFileExists ());
|
||||
BEAST_EXPECT(rcg.configFileExists ());
|
||||
auto const& c (rcg.config ());
|
||||
BEAST_EXPECT(c.legacy ("validators_file").empty ());
|
||||
BEAST_EXPECT(c.section (SECTION_VALIDATORS).values ().size () == 5);
|
||||
BEAST_EXPECT(c.section (SECTION_VALIDATOR_KEYS).values ().size () == 3);
|
||||
BEAST_EXPECT(c.VALIDATION_QUORUM == quorum);
|
||||
BEAST_EXPECT(c.section (SECTION_VALIDATORS).values ().size () == 8);
|
||||
BEAST_EXPECT(
|
||||
c.section (SECTION_VALIDATOR_LIST_KEYS).values ().size () == 2);
|
||||
}
|
||||
{
|
||||
// load from specified [validators_file] instead
|
||||
// of default location
|
||||
int const quorum = 3;
|
||||
detail::ValidatorsTxtGuard const vtg (
|
||||
*this, "test_cfg", "validators.cfg", quorum);
|
||||
*this, "test_cfg", "validators.cfg");
|
||||
BEAST_EXPECT(vtg.validatorsFileExists ());
|
||||
detail::ValidatorsTxtGuard const vtgDefault (
|
||||
*this, vtg.subdir (), "validators.txt", 4, false);
|
||||
*this, vtg.subdir (), "validators.txt", false);
|
||||
BEAST_EXPECT(vtgDefault.validatorsFileExists ());
|
||||
detail::RippledCfgGuard const rcg (
|
||||
*this, vtg.subdir (), "", vtg.validatorsFile (), false);
|
||||
BEAST_EXPECT(rcg.configFileExists ());
|
||||
auto const& c (rcg.config ());
|
||||
BEAST_EXPECT(c.legacy ("validators_file") == vtg.validatorsFile ());
|
||||
BEAST_EXPECT(c.section (SECTION_VALIDATORS).values ().size () == 5);
|
||||
BEAST_EXPECT(c.section (SECTION_VALIDATOR_KEYS).values ().size () == 3);
|
||||
BEAST_EXPECT(c.VALIDATION_QUORUM == quorum);
|
||||
}
|
||||
{
|
||||
// do not load quorum from validators file if in config
|
||||
boost::format cc (R"rippleConfig(
|
||||
[validators_file]
|
||||
%1%
|
||||
|
||||
[validation_quorum]
|
||||
4
|
||||
)rippleConfig");
|
||||
int const quorum = 3;
|
||||
detail::ValidatorsTxtGuard const vtg (
|
||||
*this, "test_cfg", "validators.cfg", quorum);
|
||||
BEAST_EXPECT(vtg.validatorsFileExists ());
|
||||
Config c;
|
||||
c.loadFromString (boost::str (cc % vtg.validatorsFile ()));
|
||||
BEAST_EXPECT(c.legacy ("validators_file") == vtg.validatorsFile ());
|
||||
BEAST_EXPECT(c.section (SECTION_VALIDATORS).values ().size () == 5);
|
||||
BEAST_EXPECT(c.section (SECTION_VALIDATOR_KEYS).values ().size () == 3);
|
||||
BEAST_EXPECT(c.VALIDATION_QUORUM == 4);
|
||||
BEAST_EXPECT(c.section (SECTION_VALIDATORS).values ().size () == 8);
|
||||
BEAST_EXPECT(
|
||||
c.section (SECTION_VALIDATOR_LIST_KEYS).values ().size () == 2);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -658,51 +635,34 @@ n9LdgEtkmGB9E2h3K4Vp7iGUaKuq23Zr32ehxiU8FWY7xoxbWTSA
|
||||
nHB1X37qrniVugfQcuBTAjswphC1drx7QjFFojJPZwKHHnt8kU7v
|
||||
nHUkAWDR4cB8AgPg7VXMX6et8xRTQb2KJfgv1aBEXozwrawRKgMB
|
||||
|
||||
[validator_list_keys]
|
||||
021A99A537FDEBC34E4FCA03B39BEADD04299BB19E85097EC92B15A3518801E566
|
||||
)rippleConfig");
|
||||
int const quorum = 3;
|
||||
detail::ValidatorsTxtGuard const vtg (
|
||||
*this, "test_cfg", "validators.cfg", quorum);
|
||||
*this, "test_cfg", "validators.cfg");
|
||||
BEAST_EXPECT(vtg.validatorsFileExists ());
|
||||
Config c;
|
||||
c.loadFromString (boost::str (cc % vtg.validatorsFile ()));
|
||||
BEAST_EXPECT(c.legacy ("validators_file") == vtg.validatorsFile ());
|
||||
BEAST_EXPECT(c.section (SECTION_VALIDATORS).values ().size () == 10);
|
||||
BEAST_EXPECT(c.section (SECTION_VALIDATOR_KEYS).values ().size () == 5);
|
||||
BEAST_EXPECT(c.VALIDATION_QUORUM == quorum);
|
||||
BEAST_EXPECT(c.section (SECTION_VALIDATORS).values ().size () == 15);
|
||||
BEAST_EXPECT(
|
||||
c.section (SECTION_VALIDATOR_LIST_KEYS).values ().size () == 3);
|
||||
}
|
||||
{
|
||||
// load should throw if [validators] and [validator_keys] are
|
||||
// missing from rippled cfg and validators file
|
||||
// load should throw if [validators], [validator_keys] and
|
||||
// [validator_list_keys] are missing from rippled cfg and
|
||||
// validators file
|
||||
Config c;
|
||||
boost::format cc ("[validators_file]\n%1%\n");
|
||||
std::string error;
|
||||
detail::ValidatorsTxtGuard const vtg (
|
||||
*this, "test_cfg", "validators.cfg", boost::none);
|
||||
*this, "test_cfg", "validators.cfg");
|
||||
BEAST_EXPECT(vtg.validatorsFileExists ());
|
||||
auto const expectedError =
|
||||
"The file specified in [validators_file] does not contain a "
|
||||
"[validators] or [validator_keys] section: " +
|
||||
"[validators], [validator_keys] or [validator_list_keys] section: " +
|
||||
vtg.validatorsFile ();
|
||||
std::ofstream o (vtg.validatorsFile ());
|
||||
o << "[validation_quorum]\n3\n";
|
||||
try {
|
||||
Config c;
|
||||
c.loadFromString (boost::str (cc % vtg.validatorsFile ()));
|
||||
} catch (std::runtime_error& e) {
|
||||
error = e.what();
|
||||
}
|
||||
BEAST_EXPECT(error == expectedError);
|
||||
}
|
||||
{
|
||||
// load should throw if [validation_quorum] is
|
||||
// missing from rippled cfg and validators file
|
||||
boost::format cc ("[validators_file]\n%1%\n");
|
||||
std::string error;
|
||||
detail::ValidatorsTxtGuard const vtg (
|
||||
*this, "test_cfg", "validators.cfg", boost::none);
|
||||
BEAST_EXPECT(vtg.validatorsFileExists ());
|
||||
auto const expectedError =
|
||||
"The file specified in [validators_file] does not contain a "
|
||||
"[validation_quorum] section: " + vtg.validatorsFile ();
|
||||
try {
|
||||
Config c;
|
||||
c.loadFromString (boost::str (cc % vtg.validatorsFile ()));
|
||||
|
||||
Reference in New Issue
Block a user