mirror of
https://github.com/Xahau/xahaud.git
synced 2025-11-20 18:45:55 +00:00
Properly use ledger hash to break ties
This commit is contained in:
@@ -381,7 +381,7 @@ RCLConsensus::Adaptor::onAccept(
|
|||||||
app_.getJobQueue().addJob(
|
app_.getJobQueue().addJob(
|
||||||
jtACCEPT,
|
jtACCEPT,
|
||||||
"acceptLedger",
|
"acceptLedger",
|
||||||
[&, cj = std::move(consensusJson) ](auto&) mutable {
|
[=, cj = std::move(consensusJson) ](auto&) mutable {
|
||||||
// Note that no lock is held or acquired during this job.
|
// Note that no lock is held or acquired during this job.
|
||||||
// This is because generic Consensus guarantees that once a ledger
|
// This is because generic Consensus guarantees that once a ledger
|
||||||
// is accepted, the consensus results and capture by reference state
|
// is accepted, the consensus results and capture by reference state
|
||||||
@@ -876,6 +876,16 @@ RCLConsensus::Adaptor::validate(RCLCxLedger const& ledger, bool proposing)
|
|||||||
app_.overlay().send(val);
|
app_.overlay().send(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RCLConsensus::Adaptor::onModeChange(
|
||||||
|
ConsensusMode before,
|
||||||
|
ConsensusMode after)
|
||||||
|
{
|
||||||
|
JLOG(j_.info()) << "Consensus mode change before=" << to_string(before)
|
||||||
|
<< ", after=" << to_string(after);
|
||||||
|
mode_ = after;
|
||||||
|
}
|
||||||
|
|
||||||
Json::Value
|
Json::Value
|
||||||
RCLConsensus::getJson(bool full) const
|
RCLConsensus::getJson(bool full) const
|
||||||
{
|
{
|
||||||
@@ -950,14 +960,18 @@ RCLConsensus::Adaptor::preStartRound(RCLCxLedger const & prevLgr)
|
|||||||
prevLgr.seq() >= app_.getMaxDisallowedLedger() &&
|
prevLgr.seq() >= app_.getMaxDisallowedLedger() &&
|
||||||
!app_.getOPs().isAmendmentBlocked();
|
!app_.getOPs().isAmendmentBlocked();
|
||||||
|
|
||||||
|
const bool synced = app_.getOPs().getOperatingMode() == NetworkOPs::omFULL;
|
||||||
|
|
||||||
if (validating_)
|
if (validating_)
|
||||||
{
|
{
|
||||||
JLOG(j_.info()) << "Entering consensus process, validating";
|
JLOG(j_.info()) << "Entering consensus process, validating, synced="
|
||||||
|
<< (synced ? "yes" : "no");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Otherwise we just want to monitor the validation process.
|
// Otherwise we just want to monitor the validation process.
|
||||||
JLOG(j_.info()) << "Entering consensus process, watching";
|
JLOG(j_.info()) << "Entering consensus process, watching, synced="
|
||||||
|
<< (synced ? "yes" : "no");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify inbound ledgers that we are starting a new round
|
// Notify inbound ledgers that we are starting a new round
|
||||||
@@ -967,8 +981,7 @@ RCLConsensus::Adaptor::preStartRound(RCLCxLedger const & prevLgr)
|
|||||||
parms_.useRoundedCloseTime = prevLgr.ledger_->rules().enabled(fix1528);
|
parms_.useRoundedCloseTime = prevLgr.ledger_->rules().enabled(fix1528);
|
||||||
|
|
||||||
// propose only if we're in sync with the network (and validating)
|
// propose only if we're in sync with the network (and validating)
|
||||||
return validating_ &&
|
return validating_ && synced;
|
||||||
(app_.getOPs().getOperatingMode() == NetworkOPs::omFULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -239,11 +239,15 @@ class RCLConsensus
|
|||||||
RCLCxLedger const& ledger,
|
RCLCxLedger const& ledger,
|
||||||
ConsensusMode mode);
|
ConsensusMode mode);
|
||||||
|
|
||||||
|
/** Notified of change in consensus mode
|
||||||
|
|
||||||
|
@param before The prior consensus mode
|
||||||
|
@param after The new consensus mode
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
onModeChange(ConsensusMode before, ConsensusMode after)
|
onModeChange(
|
||||||
{
|
ConsensusMode before,
|
||||||
mode_ = after;
|
ConsensusMode after);
|
||||||
}
|
|
||||||
|
|
||||||
/** Close the open ledger and return initial consensus position.
|
/** Close the open ledger and return initial consensus position.
|
||||||
|
|
||||||
|
|||||||
@@ -1275,29 +1275,8 @@ bool NetworkOPsImp::checkLastClosedLedger (
|
|||||||
|
|
||||||
struct ValidationCount
|
struct ValidationCount
|
||||||
{
|
{
|
||||||
int trustedValidations, nodesUsing;
|
std::uint32_t trustedValidations = 0;
|
||||||
|
std::uint32_t nodesUsing = 0;
|
||||||
ValidationCount() : trustedValidations(0), nodesUsing(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
auto
|
|
||||||
asTie() const
|
|
||||||
{
|
|
||||||
return std::tie(trustedValidations, nodesUsing);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
operator>(const ValidationCount& v) const
|
|
||||||
{
|
|
||||||
return asTie() > v.asTie();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
operator==(const ValidationCount& v) const
|
|
||||||
{
|
|
||||||
return asTie() == v.asTie();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
hash_map<uint256, ValidationCount> ledgers;
|
hash_map<uint256, ValidationCount> ledgers;
|
||||||
@@ -1327,38 +1306,47 @@ bool NetworkOPsImp::checkLastClosedLedger (
|
|||||||
++ledgers[peerLedger].nodesUsing;
|
++ledgers[peerLedger].nodesUsing;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto bestVC = ledgers[closedLedger];
|
|
||||||
|
|
||||||
// 3) Is there a network ledger we'd like to switch to? If so, do we have
|
// 3) Is there a network ledger we'd like to switch to? If so, do we have
|
||||||
// it?
|
// it?
|
||||||
bool switchLedgers = false;
|
bool switchLedgers = false;
|
||||||
|
ValidationCount bestCounts = ledgers[closedLedger];
|
||||||
|
|
||||||
for (auto const& it: ledgers)
|
for (auto const& it: ledgers)
|
||||||
{
|
{
|
||||||
JLOG(m_journal.debug()) << "L: " << it.first
|
uint256 const & currLedger = it.first;
|
||||||
<< " t=" << it.second.trustedValidations
|
ValidationCount const & currCounts = it.second;
|
||||||
<< ", n=" << it.second.nodesUsing;
|
|
||||||
|
|
||||||
// Temporary logging to make sure tiebreaking isn't broken
|
JLOG(m_journal.debug()) << "L: " << currLedger
|
||||||
if (it.second.trustedValidations > 0)
|
<< " t=" << currCounts.trustedValidations
|
||||||
JLOG(m_journal.trace())
|
<< ", n=" << currCounts.nodesUsing;
|
||||||
<< " TieBreakTV: " << it.first;
|
|
||||||
else
|
bool const preferCurr = [&]()
|
||||||
{
|
{
|
||||||
if (it.second.nodesUsing > 0)
|
// 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)
|
||||||
{
|
{
|
||||||
JLOG(m_journal.trace())
|
if (currCounts.nodesUsing > bestCounts.nodesUsing)
|
||||||
<< " TieBreakNU: " << it.first;
|
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 a ledger with more support
|
}();
|
||||||
// or the one with higher hash if they have the same support
|
|
||||||
if (it.second > bestVC ||
|
// Switch to current ledger if it is preferred over best so far
|
||||||
(it.second == bestVC && it.first > closedLedger))
|
if (preferCurr)
|
||||||
{
|
{
|
||||||
bestVC = it.second;
|
bestCounts = currCounts;
|
||||||
closedLedger = it.first;
|
closedLedger = currLedger;
|
||||||
switchLedgers = true;
|
switchLedgers = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1305,7 +1305,7 @@ PeerImp::onMessage (std::shared_ptr <protocol::TMStatusChange> const& m)
|
|||||||
{
|
{
|
||||||
if (!closedLedgerHash_.isZero ())
|
if (!closedLedgerHash_.isZero ())
|
||||||
{
|
{
|
||||||
JLOG(p_journal_.trace()) << "Status: Out of sync";
|
JLOG(p_journal_.debug()) << "Status: Out of sync";
|
||||||
closedLedgerHash_.zero ();
|
closedLedgerHash_.zero ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1318,11 +1318,11 @@ PeerImp::onMessage (std::shared_ptr <protocol::TMStatusChange> const& m)
|
|||||||
// a peer has changed ledgers
|
// a peer has changed ledgers
|
||||||
memcpy (closedLedgerHash_.begin (), m->ledgerhash ().data (), 256 / 8);
|
memcpy (closedLedgerHash_.begin (), m->ledgerhash ().data (), 256 / 8);
|
||||||
addLedger (closedLedgerHash_);
|
addLedger (closedLedgerHash_);
|
||||||
JLOG(p_journal_.trace()) << "LCL is " << closedLedgerHash_;
|
JLOG(p_journal_.debug()) << "LCL is " << closedLedgerHash_;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
JLOG(p_journal_.trace()) << "Status: No ledger";
|
JLOG(p_journal_.debug()) << "Status: No ledger";
|
||||||
closedLedgerHash_.zero ();
|
closedLedgerHash_.zero ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user