mirror of
https://github.com/Xahau/xahaud.git
synced 2025-11-04 10:45:50 +00:00
Use LedgerTrie for preferred ledger (RIPD-1551):
These changes augment the Validations class with a LedgerTrie to better track the history of support for validated ledgers. This improves the selection of the preferred working ledger for consensus. The Validations class now tracks both full and partial validations. Partial validations are only used to determine the working ledger; full validations are required for any quorum related function. Validators are also now explicitly restricted to sending validations with increasing ledger sequence number.
This commit is contained in:
@@ -1273,84 +1273,39 @@ bool NetworkOPsImp::checkLastClosedLedger (
|
||||
JLOG(m_journal.trace()) << "OurClosed: " << closedLedger;
|
||||
JLOG(m_journal.trace()) << "PrevClosed: " << prevClosedLedger;
|
||||
|
||||
struct ValidationCount
|
||||
{
|
||||
std::uint32_t trustedValidations = 0;
|
||||
std::uint32_t nodesUsing = 0;
|
||||
};
|
||||
//-------------------------------------------------------------------------
|
||||
// Determine preferred last closed ledger
|
||||
|
||||
hash_map<uint256, ValidationCount> ledgers;
|
||||
{
|
||||
hash_map<uint256, std::uint32_t> current =
|
||||
app_.getValidations().currentTrustedDistribution(
|
||||
closedLedger,
|
||||
prevClosedLedger,
|
||||
m_ledgerMaster.getValidLedgerIndex());
|
||||
|
||||
for (auto& it: current)
|
||||
ledgers[it.first].trustedValidations += it.second;
|
||||
}
|
||||
|
||||
auto& ourVC = ledgers[closedLedger];
|
||||
auto & validations = app_.getValidations();
|
||||
JLOG(m_journal.debug())
|
||||
<< "ValidationTrie " << Json::Compact(validations.getJsonTrie());
|
||||
|
||||
// Will rely on peer LCL if no trusted validations exist
|
||||
hash_map<uint256, std::uint32_t> peerCounts;
|
||||
peerCounts[closedLedger] = 0;
|
||||
if (mMode >= omTRACKING)
|
||||
peerCounts[closedLedger]++;
|
||||
|
||||
for (auto& peer : peerList)
|
||||
{
|
||||
++ourVC.nodesUsing;
|
||||
uint256 peerLedger = peer->getClosedLedgerHash();
|
||||
|
||||
if (peerLedger.isNonZero())
|
||||
++peerCounts[peerLedger];
|
||||
}
|
||||
|
||||
for (auto& peer: peerList)
|
||||
{
|
||||
uint256 peerLedger = peer->getClosedLedgerHash ();
|
||||
for(auto const & it: peerCounts)
|
||||
JLOG(m_journal.debug()) << "L: " << it.first << " n=" << it.second;
|
||||
|
||||
if (peerLedger.isNonZero ())
|
||||
++ledgers[peerLedger].nodesUsing;
|
||||
}
|
||||
|
||||
|
||||
// 3) Is there a network ledger we'd like to switch to? If so, do we have
|
||||
// it?
|
||||
bool switchLedgers = false;
|
||||
ValidationCount bestCounts = ledgers[closedLedger];
|
||||
|
||||
for (auto const& it: ledgers)
|
||||
{
|
||||
uint256 const & currLedger = it.first;
|
||||
ValidationCount const & currCounts = it.second;
|
||||
|
||||
JLOG(m_journal.debug()) << "L: " << currLedger
|
||||
<< " t=" << currCounts.trustedValidations
|
||||
<< ", n=" << currCounts.nodesUsing;
|
||||
|
||||
bool const preferCurr = [&]()
|
||||
{
|
||||
// Prefer ledger with more trustedValidations
|
||||
if (currCounts.trustedValidations > bestCounts.trustedValidations)
|
||||
return true;
|
||||
if (currCounts.trustedValidations < bestCounts.trustedValidations)
|
||||
return false;
|
||||
// If neither are trusted, prefer more nodesUsing
|
||||
if (currCounts.trustedValidations == 0)
|
||||
{
|
||||
if (currCounts.nodesUsing > bestCounts.nodesUsing)
|
||||
return true;
|
||||
if (currCounts.nodesUsing < bestCounts.nodesUsing)
|
||||
return false;
|
||||
}
|
||||
// If tied trustedValidations (non-zero) or tied nodesUsing,
|
||||
// prefer higher ledger hash
|
||||
return currLedger > closedLedger;
|
||||
|
||||
}();
|
||||
|
||||
// Switch to current ledger if it is preferred over best so far
|
||||
if (preferCurr)
|
||||
{
|
||||
bestCounts = currCounts;
|
||||
closedLedger = currLedger;
|
||||
switchLedgers = true;
|
||||
}
|
||||
}
|
||||
uint256 preferredLCL = validations.getPreferredLCL(
|
||||
RCLValidatedLedger{ourClosed, validations.adaptor().journal()},
|
||||
m_ledgerMaster.getValidLedgerIndex(),
|
||||
peerCounts);
|
||||
|
||||
bool switchLedgers = preferredLCL != closedLedger;
|
||||
if(switchLedgers)
|
||||
closedLedger = preferredLCL;
|
||||
//-------------------------------------------------------------------------
|
||||
if (switchLedgers && (closedLedger == prevClosedLedger))
|
||||
{
|
||||
// don't switch to our own previous ledger
|
||||
@@ -1364,15 +1319,15 @@ bool NetworkOPsImp::checkLastClosedLedger (
|
||||
if (!switchLedgers)
|
||||
return false;
|
||||
|
||||
auto consensus = m_ledgerMaster.getLedgerByHash (closedLedger);
|
||||
auto consensus = m_ledgerMaster.getLedgerByHash(closedLedger);
|
||||
|
||||
if (!consensus)
|
||||
consensus = app_.getInboundLedgers().acquire (
|
||||
consensus = app_.getInboundLedgers().acquire(
|
||||
closedLedger, 0, InboundLedger::Reason::CONSENSUS);
|
||||
|
||||
if (consensus &&
|
||||
! m_ledgerMaster.isCompatible (*consensus, m_journal.debug(),
|
||||
"Not switching"))
|
||||
!m_ledgerMaster.isCompatible(
|
||||
*consensus, m_journal.debug(), "Not switching"))
|
||||
{
|
||||
// Don't switch to a ledger not on the validated chain
|
||||
networkClosed = ourClosed->info().hash;
|
||||
@@ -1380,18 +1335,18 @@ bool NetworkOPsImp::checkLastClosedLedger (
|
||||
}
|
||||
|
||||
JLOG(m_journal.warn()) << "We are not running on the consensus ledger";
|
||||
JLOG(m_journal.info()) << "Our LCL: " << getJson (*ourClosed);
|
||||
JLOG(m_journal.info()) << "Our LCL: " << getJson(*ourClosed);
|
||||
JLOG(m_journal.info()) << "Net LCL " << closedLedger;
|
||||
|
||||
if ((mMode == omTRACKING) || (mMode == omFULL))
|
||||
setMode (omCONNECTED);
|
||||
setMode(omCONNECTED);
|
||||
|
||||
if (consensus)
|
||||
{
|
||||
// FIXME: If this rewinds the ledger sequence, or has the same sequence, we
|
||||
// should update the status on any stored transactions in the invalidated
|
||||
// ledgers.
|
||||
switchLastClosedLedger (consensus);
|
||||
// FIXME: If this rewinds the ledger sequence, or has the same
|
||||
// sequence, we should update the status on any stored transactions
|
||||
// in the invalidated ledgers.
|
||||
switchLastClosedLedger(consensus);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user