Browse Source

Improve network height estimation

pull/40/head^2
Jack Grigg 7 years ago
parent
commit
92bfde0edf
No known key found for this signature in database GPG Key ID: 665DBCD284F7DAFF
  1. 38
      src/gtest/test_metrics.cpp
  2. 14
      src/metrics.cpp
  3. 2
      src/metrics.h

38
src/gtest/test_metrics.cpp

@ -96,40 +96,40 @@ TEST(Metrics, GetLocalSolPS) {
TEST(Metrics, EstimateNetHeightInner) { TEST(Metrics, EstimateNetHeightInner) {
// Ensure that the (rounded) current height is returned if the tip is current // Ensure that the (rounded) current height is returned if the tip is current
SetMockTime(15000); SetMockTime(15000);
EXPECT_EQ(100, EstimateNetHeightInner(100, 14100, 50, 7500, 150)); EXPECT_EQ(100, EstimateNetHeightInner(100, 14100, 50, 7500, 0, 150));
SetMockTime(15150); SetMockTime(15150);
EXPECT_EQ(100, EstimateNetHeightInner(101, 14250, 50, 7500, 150)); EXPECT_EQ(100, EstimateNetHeightInner(101, 14250, 50, 7500, 0, 150));
// Ensure that correct estimates are returned if the tip is in the past // Ensure that correct estimates are returned if the tip is in the past
SetMockTime(15300); // Tip is 2 blocks behind SetMockTime(15300); // Tip is 2 blocks behind
EXPECT_EQ(100, EstimateNetHeightInner(100, 14100, 50, 7500, 150)); EXPECT_EQ(100, EstimateNetHeightInner(100, 14100, 50, 7500, 0, 150));
SetMockTime(15900); // Tip is 6 blocks behind SetMockTime(15900); // Tip is 6 blocks behind
EXPECT_EQ(110, EstimateNetHeightInner(100, 14100, 50, 7500, 150)); EXPECT_EQ(110, EstimateNetHeightInner(100, 14100, 50, 7500, 0, 150));
// Check estimates during resync // Check estimates during resync
SetMockTime(15000); SetMockTime(15000);
EXPECT_EQ(100, EstimateNetHeightInner( 0, 0, 50, 7500, 150)); EXPECT_EQ(100, EstimateNetHeightInner( 0, 0, 50, 7500, 0, 150));
EXPECT_EQ(100, EstimateNetHeightInner( 7, 600, 50, 7500, 150)); EXPECT_EQ(100, EstimateNetHeightInner( 7, 600, 50, 7500, 0, 150));
EXPECT_EQ(100, EstimateNetHeightInner( 8, 600, 50, 7500, 150)); EXPECT_EQ(100, EstimateNetHeightInner( 8, 600, 50, 7500, 0, 150));
EXPECT_EQ(100, EstimateNetHeightInner(10, 750, 50, 7500, 150)); EXPECT_EQ(100, EstimateNetHeightInner(10, 750, 50, 7500, 0, 150));
EXPECT_EQ(100, EstimateNetHeightInner(11, 900, 50, 7500, 150)); EXPECT_EQ(100, EstimateNetHeightInner(11, 900, 50, 7500, 0, 150));
EXPECT_EQ(100, EstimateNetHeightInner(20, 2100, 50, 7500, 150)); EXPECT_EQ(100, EstimateNetHeightInner(20, 2100, 50, 7500, 0, 150));
EXPECT_EQ(100, EstimateNetHeightInner(49, 6450, 50, 7500, 150)); EXPECT_EQ(100, EstimateNetHeightInner(49, 6450, 50, 7500, 0, 150));
EXPECT_EQ(100, EstimateNetHeightInner(50, 6600, 50, 7500, 150)); EXPECT_EQ(100, EstimateNetHeightInner(50, 6600, 50, 7500, 0, 150));
EXPECT_EQ(100, EstimateNetHeightInner(51, 6750, 50, 7500, 150)); EXPECT_EQ(100, EstimateNetHeightInner(51, 6750, 50, 7500, 0, 150));
EXPECT_EQ(100, EstimateNetHeightInner(55, 7350, 50, 7500, 150)); EXPECT_EQ(100, EstimateNetHeightInner(55, 7350, 50, 7500, 0, 150));
EXPECT_EQ(100, EstimateNetHeightInner(56, 7500, 50, 7500, 150)); EXPECT_EQ(100, EstimateNetHeightInner(56, 7500, 50, 7500, 0, 150));
EXPECT_EQ(100, EstimateNetHeightInner(57, 7650, 50, 7500, 150)); EXPECT_EQ(100, EstimateNetHeightInner(57, 7650, 50, 7500, 0, 150));
EXPECT_EQ(100, EstimateNetHeightInner(75, 10350, 50, 7500, 150)); EXPECT_EQ(100, EstimateNetHeightInner(75, 10350, 50, 7500, 0, 150));
// More complex calculations: // More complex calculations:
SetMockTime(20000); SetMockTime(20000);
// - Checkpoint spacing: 200 // - Checkpoint spacing: 200
// -> Average spacing: 175 // -> Average spacing: 175
// -> estimated height: 127 -> 130 // -> estimated height: 127 -> 130
EXPECT_EQ(130, EstimateNetHeightInner(100, 14100, 50, 5250, 150)); EXPECT_EQ(130, EstimateNetHeightInner(100, 14100, 50, 5250, 0, 150));
// - Checkpoint spacing: 50 // - Checkpoint spacing: 50
// -> Average spacing: 100 // -> Average spacing: 100
// -> estimated height: 153 -> 150 // -> estimated height: 153 -> 150
EXPECT_EQ(150, EstimateNetHeightInner(100, 14100, 50, 12000, 150)); EXPECT_EQ(150, EstimateNetHeightInner(100, 14100, 50, 12000, 0, 150));
} }

14
src/metrics.cpp

@ -106,12 +106,17 @@ double GetLocalSolPS()
int EstimateNetHeightInner(int height, int64_t tipmediantime, int EstimateNetHeightInner(int height, int64_t tipmediantime,
int heightLastCheckpoint, int64_t timeLastCheckpoint, int heightLastCheckpoint, int64_t timeLastCheckpoint,
int64_t targetSpacing) int64_t genesisTime, int64_t targetSpacing)
{ {
// We average the target spacing with the observed spacing to the last // We average the target spacing with the observed spacing to the last
// checkpoint, and use that to estimate the current network height. // checkpoint (either from below or above depending on the current height),
int medianHeight = height - CBlockIndex::nMedianTimeSpan / 2; // and use that to estimate the current network height.
double checkpointSpacing = (double (tipmediantime - timeLastCheckpoint)) / (medianHeight - heightLastCheckpoint); int medianHeight = height > CBlockIndex::nMedianTimeSpan ?
height - (1 + ((CBlockIndex::nMedianTimeSpan - 1) / 2)) :
height / 2;
double checkpointSpacing = medianHeight > heightLastCheckpoint ?
(double (tipmediantime - timeLastCheckpoint)) / (medianHeight - heightLastCheckpoint) :
(double (timeLastCheckpoint - genesisTime)) / heightLastCheckpoint;
double averageSpacing = (targetSpacing + checkpointSpacing) / 2; double averageSpacing = (targetSpacing + checkpointSpacing) / 2;
int netheight = medianHeight + ((GetTime() - tipmediantime) / averageSpacing); int netheight = medianHeight + ((GetTime() - tipmediantime) / averageSpacing);
// Round to nearest ten to reduce noise // Round to nearest ten to reduce noise
@ -125,6 +130,7 @@ int EstimateNetHeight(int height, int64_t tipmediantime, CChainParams chainParam
height, tipmediantime, height, tipmediantime,
Checkpoints::GetTotalBlocksEstimate(checkpointData), Checkpoints::GetTotalBlocksEstimate(checkpointData),
checkpointData.nTimeLastCheckpoint, checkpointData.nTimeLastCheckpoint,
chainParams.GenesisBlock().nTime,
chainParams.GetConsensus().nPowTargetSpacing); chainParams.GetConsensus().nPowTargetSpacing);
} }

2
src/metrics.h

@ -65,7 +65,7 @@ void MarkStartTime();
double GetLocalSolPS(); double GetLocalSolPS();
int EstimateNetHeightInner(int height, int64_t tipmediantime, int EstimateNetHeightInner(int height, int64_t tipmediantime,
int heightLastCheckpoint, int64_t timeLastCheckpoint, int heightLastCheckpoint, int64_t timeLastCheckpoint,
int64_t targetSpacing); int64_t genesisTime, int64_t targetSpacing);
void TriggerRefresh(); void TriggerRefresh();

Loading…
Cancel
Save