Skip to content

Commit 52b7601

Browse files
committed
Added EXPERIMENTAL_TRIGGER_TIMER
1 parent 050eacf commit 52b7601

File tree

4 files changed

+67
-5
lines changed

4 files changed

+67
-5
lines changed

src/herder/HerderImpl.cpp

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,16 +1229,69 @@ HerderImpl::setupTriggerNextLedger()
12291229
// bootstrap with a pessimistic estimate of when
12301230
// the ballot protocol started last
12311231
auto now = mApp.getClock().now();
1232-
auto lastBallotStart = now - milliseconds;
1233-
auto lastStart = mHerderSCPDriver.getPrepareStart(lastIndex);
1234-
if (lastStart)
1232+
auto lastLedgerStatingPoint = now - milliseconds;
1233+
1234+
#ifdef BUILD_TESTS
1235+
if (mApp.getConfig().EXPERIMENTAL_TRIGGER_TIMER &&
1236+
mApp.getClock().getMode() == VirtualClock::REAL_TIME)
1237+
{
1238+
auto consensusCloseTime = trackingConsensusCloseTime();
1239+
1240+
// Bootstrap to pessimistic estimate on startup
1241+
if (consensusCloseTime == 0)
1242+
{
1243+
CLOG_WARNING(
1244+
Herder,
1245+
"Consensus close time is 0, using pessimistic estimate");
1246+
// Keep the existing lastLedgerStatingPoint
1247+
}
1248+
else
1249+
{
1250+
// The externalized close time is a unix timestamp. We convert it to
1251+
// steady_clock time by:
1252+
// 1. Converting unix timestamp to system_clock::time_point (wall
1253+
// clock time)
1254+
// 2. Calculating how long ago that was from current system time
1255+
// 3. Subtracting that duration from current steady_clock time
1256+
auto externalizedSystemTime =
1257+
VirtualClock::from_time_t(consensusCloseTime);
1258+
auto currentSystemTime = mApp.getClock().system_now();
1259+
1260+
// Handle clock drift: if externalized time is in the future,
1261+
// fall back to pessimistic estimate
1262+
if (externalizedSystemTime >= currentSystemTime)
1263+
{
1264+
CLOG_WARNING(Herder,
1265+
"Externalized closeTime {} is in the future "
1266+
"(current time {}), "
1267+
"using pessimistic estimate",
1268+
consensusCloseTime,
1269+
VirtualClock::to_time_t(currentSystemTime));
1270+
// Keep the existing lastLedgerStatingPoint which is already set
1271+
// to the pessimistic estimate (now - milliseconds)
1272+
}
1273+
else
1274+
{
1275+
// Calculate how long ago the externalized closeTime was
1276+
auto timeSinceExternalized =
1277+
currentSystemTime - externalizedSystemTime;
1278+
lastLedgerStatingPoint = now - timeSinceExternalized;
1279+
}
1280+
}
1281+
}
1282+
else
1283+
#endif
12351284
{
1236-
lastBallotStart = *lastStart;
1285+
auto lastStart = mHerderSCPDriver.getPrepareStart(lastIndex);
1286+
if (lastStart)
1287+
{
1288+
lastLedgerStatingPoint = *lastStart;
1289+
}
12371290
}
12381291

12391292
// Adjust trigger time in case node's clock has drifted.
12401293
// This ensures that next value to nominate is valid
1241-
auto triggerTime = lastBallotStart + milliseconds;
1294+
auto triggerTime = lastLedgerStatingPoint + milliseconds;
12421295

12431296
if (triggerTime < now)
12441297
{

src/main/Config.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,7 @@ Config::Config() : NODE_SEED(SecretKey::random())
357357
CATCHUP_SKIP_KNOWN_RESULTS_FOR_TESTING = false;
358358
MODE_USES_IN_MEMORY_LEDGER = false;
359359
SKIP_HIGH_CRITICAL_VALIDATOR_CHECKS_FOR_TESTING = false;
360+
EXPERIMENTAL_TRIGGER_TIMER = false;
360361
#endif
361362

362363
#ifdef BEST_OFFER_DEBUGGING
@@ -1131,6 +1132,8 @@ Config::processConfig(std::shared_ptr<cpptoml::table> t)
11311132
EXPERIMENTAL_BACKGROUND_TX_SIG_VERIFICATION =
11321133
readBool(item);
11331134
}},
1135+
{"EXPERIMENTAL_TRIGGER_TIMER",
1136+
[&]() { EXPERIMENTAL_TRIGGER_TIMER = readBool(item); }},
11341137
{"ARTIFICIALLY_DELAY_LEDGER_CLOSE_FOR_TESTING",
11351138
[&]() {
11361139
ARTIFICIALLY_DELAY_LEDGER_CLOSE_FOR_TESTING =

src/main/Config.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -848,6 +848,11 @@ class Config : public std::enable_shared_from_this<Config>
848848
size_t TESTING_MAX_SOROBAN_BYTE_ALLOWANCE;
849849
size_t TESTING_MAX_CLASSIC_BYTE_ALLOWANCE;
850850

851+
// Experimental flag to use externalized close time for trigger timer
852+
// calculation instead of prepare start time. Should only be used for
853+
// testing.
854+
bool EXPERIMENTAL_TRIGGER_TIMER;
855+
851856
// Set QUORUM_SET using automatic quorum set configuration based on
852857
// `validators`.
853858
void

src/test/test.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ getTestConfig(int instanceNumber, Config::TestDbMode mode)
251251
thisConfig.MANUAL_CLOSE = true;
252252

253253
thisConfig.TEST_CASES_ENABLED = true;
254+
thisConfig.EXPERIMENTAL_TRIGGER_TIMER = true;
254255

255256
thisConfig.PEER_PORT =
256257
static_cast<unsigned short>(DEFAULT_PEER_PORT + instanceNumber * 2);

0 commit comments

Comments
 (0)