mirror of
https://github.com/Xahau/xahaud.git
synced 2026-07-29 18:10:12 +00:00
fix(consensus): apply negative unl to sidecar validator view
This commit is contained in:
120
src/test/consensus/ConsensusExtensions_test.cpp
Normal file
120
src/test/consensus/ConsensusExtensions_test.cpp
Normal file
@@ -0,0 +1,120 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <test/jtx.h>
|
||||
#include <xrpld/app/consensus/ConsensusExtensions.h>
|
||||
#include <xrpld/app/ledger/Ledger.h>
|
||||
#include <xrpl/basics/StringUtilities.h>
|
||||
#include <xrpl/beast/unit_test.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace test {
|
||||
|
||||
class ConsensusExtensions_test : public beast::unit_test::suite
|
||||
{
|
||||
std::vector<PublicKey>
|
||||
makeValidatorKeys() const
|
||||
{
|
||||
std::vector<std::string> const rawKeys = {
|
||||
"0388935426E0D08083314842EDFBB2D517BD47699F9A4527318A8E10468C97C05"
|
||||
"2",
|
||||
"02691AC5AE1C4C333AE5DF8A93BDC495F0EEBFC6DB0DA7EB6EF808F3AFC006E3F"
|
||||
"E"};
|
||||
|
||||
std::vector<PublicKey> keys;
|
||||
keys.reserve(rawKeys.size());
|
||||
for (auto const& rawKey : rawKeys)
|
||||
{
|
||||
auto const pkHex = strUnHex(rawKey);
|
||||
keys.emplace_back(makeSlice(*pkHex));
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
||||
void
|
||||
testActiveValidatorViewAppliesNegativeUNL()
|
||||
{
|
||||
testcase("Active validator view applies NegativeUNL");
|
||||
|
||||
using namespace jtx;
|
||||
Env env{
|
||||
*this,
|
||||
envconfig(),
|
||||
supported_amendments() | featureNegativeUNL,
|
||||
nullptr};
|
||||
|
||||
auto const vlKeys = makeValidatorKeys();
|
||||
auto const genesis = std::make_shared<Ledger>(
|
||||
create_genesis,
|
||||
env.app().config(),
|
||||
std::vector<uint256>{},
|
||||
env.app().getNodeFamily());
|
||||
auto l = std::make_shared<Ledger>(
|
||||
*genesis, env.app().timeKeeper().closeTime());
|
||||
BEAST_EXPECT(l->rules().enabled(featureNegativeUNL));
|
||||
|
||||
auto report = std::make_shared<SLE>(keylet::UNLReport());
|
||||
std::vector<STObject> activeValidators;
|
||||
for (auto const& pk : vlKeys)
|
||||
{
|
||||
activeValidators.push_back(
|
||||
STObject::makeInnerObject(sfActiveValidator));
|
||||
activeValidators.back().setFieldVL(sfPublicKey, pk);
|
||||
}
|
||||
report->setFieldArray(
|
||||
sfActiveValidators, STArray(activeValidators, sfActiveValidators));
|
||||
|
||||
auto negUnl = std::make_shared<SLE>(keylet::negativeUNL());
|
||||
std::vector<STObject> disabledValidators;
|
||||
disabledValidators.push_back(
|
||||
STObject::makeInnerObject(sfDisabledValidator));
|
||||
disabledValidators.back().setFieldVL(sfPublicKey, vlKeys[0]);
|
||||
disabledValidators.back().setFieldU32(sfFirstLedgerSequence, l->seq());
|
||||
negUnl->setFieldArray(
|
||||
sfDisabledValidators,
|
||||
STArray(disabledValidators, sfDisabledValidators));
|
||||
OpenView accum(&*l);
|
||||
accum.rawInsert(report);
|
||||
accum.rawInsert(negUnl);
|
||||
accum.apply(*l);
|
||||
|
||||
ConsensusExtensions ce{env.app(), env.journal};
|
||||
auto const view = ce.makeActiveValidatorView(l);
|
||||
|
||||
BEAST_EXPECT(view->fromUNLReport);
|
||||
BEAST_EXPECT(view->size() == 1);
|
||||
BEAST_EXPECT(!view->containsMaster(vlKeys[0]));
|
||||
BEAST_EXPECT(!view->containsNode(calcNodeID(vlKeys[0])));
|
||||
BEAST_EXPECT(view->containsMaster(vlKeys[1]));
|
||||
BEAST_EXPECT(view->containsNode(calcNodeID(vlKeys[1])));
|
||||
}
|
||||
|
||||
public:
|
||||
void
|
||||
run() override
|
||||
{
|
||||
testActiveValidatorViewAppliesNegativeUNL();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(ConsensusExtensions, consensus, ripple);
|
||||
|
||||
} // namespace test
|
||||
} // namespace ripple
|
||||
@@ -92,22 +92,29 @@ buildActiveValidatorView(
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: If this fork still supports Negative UNL, fold that policy into
|
||||
// this active view before quorum sizing or sidecar eligibility decisions.
|
||||
if (!view.masterKeys.empty())
|
||||
return view;
|
||||
if (view.masterKeys.empty())
|
||||
{
|
||||
// Fallback exists for early ledgers and dev/test networks before the
|
||||
// report object is available. It is deliberately the configured trusted
|
||||
// master-key set so manifest signing keys still resolve through trust.
|
||||
for (auto const& masterKey : app.validators().getTrustedMasterKeys())
|
||||
view.insertMaster(masterKey);
|
||||
|
||||
// Fallback exists for early ledgers and dev/test networks before the
|
||||
// report object is available. It is deliberately the configured trusted
|
||||
// master-key set so manifest signing keys still resolve through trust.
|
||||
for (auto const& masterKey : app.validators().getTrustedMasterKeys())
|
||||
view.insertMaster(masterKey);
|
||||
// Some standalone/dev configurations trust local validation implicitly.
|
||||
// insertMaster() makes this idempotent if self is already trusted.
|
||||
auto const& valKeys = app.getValidatorKeys();
|
||||
if (valKeys.keys && valKeys.nodeID != beast::zero)
|
||||
view.insertMaster(valKeys.keys->masterPublicKey);
|
||||
}
|
||||
|
||||
// Some standalone/dev configurations trust local validation implicitly.
|
||||
// insertMaster() makes this idempotent if self is already trusted.
|
||||
auto const& valKeys = app.getValidatorKeys();
|
||||
if (valKeys.keys && valKeys.nodeID != beast::zero)
|
||||
view.insertMaster(valKeys.keys->masterPublicKey);
|
||||
if (sourceLedger && sourceLedger->rules().enabled(featureNegativeUNL))
|
||||
{
|
||||
// UNLReport records recently active validators; NegativeUNL is the
|
||||
// separate ledger policy overlay that core consensus applies to quorum.
|
||||
// Apply it to either source so sidecar quorum matches that policy.
|
||||
for (auto const& masterKey : sourceLedger->negativeUNL())
|
||||
view.eraseMaster(masterKey);
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@@ -58,6 +58,13 @@ public:
|
||||
nodeIds.insert(calcNodeID(masterKey));
|
||||
}
|
||||
|
||||
void
|
||||
eraseMaster(PublicKey const& masterKey)
|
||||
{
|
||||
masterKeys.erase(masterKey);
|
||||
nodeIds.erase(calcNodeID(masterKey));
|
||||
}
|
||||
|
||||
std::size_t
|
||||
size() const
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user