Improve ledger close timing

Added a safety to close the ledger quickly if there's
evidence validators we trust have already closed the
ledger. Base the minimum ledger open time on how long
we saw the ledger open. Do not rely on the rounded
close time for enforcing the minimum ledger open time.
This commit is contained in:
JoelKatz
2015-11-06 11:01:21 -08:00
committed by Nik Bougalis
parent b87eff2115
commit 1601f6bbc9

View File

@@ -61,13 +61,12 @@ namespace ripple {
@param previousProposers proposers in the last closing @param previousProposers proposers in the last closing
@param proposersClosed proposers who have currently closed this ledger @param proposersClosed proposers who have currently closed this ledger
@param proposersValidated proposers who have validated the last closed @param proposersValidated proposers who have validated the last closed
ledger ledger
@param previousMSeconds time, in milliseconds, for the previous ledger to @param previousMSeconds time, in milliseconds, for the previous ledger to
reach consensus (in milliseconds) reach consensus (in milliseconds)
@param currentMSeconds time, in milliseconds since the previous ledger @param currentMSeconds time, in milliseconds, since the previous ledger's
closed (possibly rounded) close time
@param openMSeconds time, in milliseconds, since the previous LCL was @param openMSeconds time, in milliseconds, waiting to close this ledger
computed
@param idleInterval the network's desired idle interval @param idleInterval the network's desired idle interval
*/ */
bool shouldCloseLedger ( bool shouldCloseLedger (
@@ -76,14 +75,15 @@ bool shouldCloseLedger (
int proposersClosed, int proposersClosed,
int proposersValidated, int proposersValidated,
int previousMSeconds, int previousMSeconds,
int currentMSeconds, int currentMSeconds, // Time since last ledger's close time
int openMSeconds, int openMSeconds, // Time waiting to close this ledger
int idleInterval, int idleInterval,
beast::Journal j) beast::Journal j)
{ {
if ((previousMSeconds < -1000) || (previousMSeconds > 600000) || if ((previousMSeconds < -1000) || (previousMSeconds > 600000) ||
(currentMSeconds < -1000) || (currentMSeconds > 600000)) (currentMSeconds > 600000))
{ {
// These are unexpected cases, we just close the ledger
JLOG (j.warning) << JLOG (j.warning) <<
"shouldCloseLedger Trans=" << (anyTransactions ? "yes" : "no") << "shouldCloseLedger Trans=" << (anyTransactions ? "yes" : "no") <<
" Prop: " << previousProposers << "/" << proposersClosed << " Prop: " << previousProposers << "/" << proposersClosed <<
@@ -92,42 +92,38 @@ bool shouldCloseLedger (
return true; return true;
} }
if ((proposersClosed + proposersValidated) > (previousProposers / 2))
{
// If more than half of the network has closed, we close
JLOG (j.trace) << "Others have closed";
return true;
}
if (!anyTransactions) if (!anyTransactions)
{ {
// did we miss a transaction? // Only close at the end of the idle interval
if (proposersClosed > (previousProposers / 4))
{
JLOG (j.trace) <<
"no transactions, many proposers: now (" << proposersClosed <<
" closed, " << previousProposers << " before)";
return true;
}
// Only close if we have idled for too long.
return currentMSeconds >= (idleInterval * 1000); // normal idle return currentMSeconds >= (idleInterval * 1000); // normal idle
} }
// If we have any transactions, we don't want to close too frequently: // Preserve minimum ledger open time
if (openMSeconds < LEDGER_MIN_CLOSE) if (openMSeconds < LEDGER_MIN_CLOSE)
{ {
if ((proposersClosed + proposersValidated) < (previousProposers / 2 )) JLOG (j.debug) <<
{ "Must wait minimum time before closing";
JLOG (j.debug) << return false;
"Must wait minimum time before closing";
return false;
}
} }
if (currentMSeconds < previousMSeconds) // Don't let this ledger close more than twice as fast as the previous
// ledger reached consensus so that slower validators can slow down
// the network
if (openMSeconds < (previousMSeconds / 2))
{ {
if ((proposersClosed + proposersValidated) < previousProposers) JLOG (j.debug) <<
{ "Ledger has not been open long enough";
JLOG (j.debug) << return false;
"We are waiting for more closes/validations";
return false;
}
} }
// Close the ledger
return true; return true;
} }
@@ -748,7 +744,7 @@ void LedgerConsensusImp::statePreClose ()
= app_.getValidations ().getTrustedValidationCount = app_.getValidations ().getTrustedValidationCount
(mPrevLedgerHash); (mPrevLedgerHash);
// This ledger is open. This computes how long since last ledger closed // This computes how long since last ledger's close time
int sinceClose; int sinceClose;
{ {
bool previousCloseCorrect = mHaveCorrectLCL bool previousCloseCorrect = mHaveCorrectLCL