Auto merge of #4181 - oxarbitrage:issue4084, r=Eirik0

Display "next upgrade" info on metrics screen

Closes #4084.
This commit is contained in:
Homu 2019-11-07 11:41:54 -08:00
commit 18df8e67e1
3 changed files with 94 additions and 19 deletions

View File

@ -107,3 +107,30 @@ TEST(Metrics, EstimateNetHeight) {
} }
RegtestDeactivateBlossom(); RegtestDeactivateBlossom();
} }
TEST(Metrics, NextUpgrade) {
SelectParams(CBaseChainParams::REGTEST);
const Consensus::Params& params = Params().GetConsensus();
UpdateNetworkUpgradeParameters(Consensus::UPGRADE_TESTDUMMY, 100);
EXPECT_EQ(SecondsLeftToNextEpoch(params, 1).value(), 14850);
EXPECT_EQ(DisplayDuration(SecondsLeftToNextEpoch(params, 1).value(), DurationFormat::REDUCED), "4 hours");
EXPECT_EQ(DisplayDuration(SecondsLeftToNextEpoch(params, 1).value(), DurationFormat::FULL), "4 hours, 7 minutes, 30 seconds");
EXPECT_EQ(SecondsLeftToNextEpoch(params, 90).value(), 1500);
EXPECT_EQ(DisplayDuration(SecondsLeftToNextEpoch(params, 90).value(), DurationFormat::REDUCED), "25 minutes");
EXPECT_EQ(DisplayDuration(SecondsLeftToNextEpoch(params, 90).value(), DurationFormat::FULL), "25 minutes, 0 seconds");
EXPECT_EQ(SecondsLeftToNextEpoch(params, 99).value(), 150);
EXPECT_EQ(DisplayDuration(SecondsLeftToNextEpoch(params, 99).value(), DurationFormat::REDUCED), "2 minutes");
EXPECT_EQ(DisplayDuration(SecondsLeftToNextEpoch(params, 99).value(), DurationFormat::FULL), "2 minutes, 30 seconds");
auto paramsBlossom = RegtestActivateBlossom(true);
EXPECT_EQ(SecondsLeftToNextEpoch(paramsBlossom, 1).value(), 7425);
EXPECT_EQ(DisplayDuration(SecondsLeftToNextEpoch(paramsBlossom, 1).value(), DurationFormat::REDUCED), "2 hours");
EXPECT_EQ(DisplayDuration(SecondsLeftToNextEpoch(paramsBlossom, 1).value(), DurationFormat::FULL), "2 hours, 3 minutes, 45 seconds");
RegtestDeactivateBlossom();
UpdateNetworkUpgradeParameters(Consensus::UPGRADE_TESTDUMMY, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT);
}

View File

@ -203,16 +203,59 @@ void ConnectMetricsScreen()
uiInterface.InitMessage.connect(metrics_InitMessage); uiInterface.InitMessage.connect(metrics_InitMessage);
} }
std::string DisplayDuration(int64_t time, DurationFormat format)
{
int days = time / (24 * 60 * 60);
int hours = (time - (days * 24 * 60 * 60)) / (60 * 60);
int minutes = (time - (((days * 24) + hours) * 60 * 60)) / 60;
int seconds = time - (((((days * 24) + hours) * 60) + minutes) * 60);
std::string strDuration;
if (format == DurationFormat::REDUCED) {
if (days > 0) {
strDuration = strprintf(_("%d days"), days);
} else if (hours > 0) {
strDuration = strprintf(_("%d hours"), hours);
} else if (minutes > 0) {
strDuration = strprintf(_("%d minutes"), minutes);
} else {
strDuration = strprintf(_("%d seconds"), seconds);
}
} else {
if (days > 0) {
strDuration = strprintf(_("%d days, %d hours, %d minutes, %d seconds"), days, hours, minutes, seconds);
} else if (hours > 0) {
strDuration = strprintf(_("%d hours, %d minutes, %d seconds"), hours, minutes, seconds);
} else if (minutes > 0) {
strDuration = strprintf(_("%d minutes, %d seconds"), minutes, seconds);
} else {
strDuration = strprintf(_("%d seconds"), seconds);
}
}
return strDuration;
}
boost::optional<int64_t> SecondsLeftToNextEpoch(const Consensus::Params& params, int currentHeight)
{
auto nextHeight = NextActivationHeight(currentHeight, params);
if (nextHeight) {
return (nextHeight.get() - currentHeight) * params.PoWTargetSpacing(nextHeight.get() - 1);
} else {
return boost::none;
}
}
int printStats(bool mining) int printStats(bool mining)
{ {
// Number of lines that are always displayed // Number of lines that are always displayed
int lines = 4; int lines = 5;
int height; int height;
int64_t currentHeadersHeight; int64_t currentHeadersHeight;
int64_t currentHeadersTime; int64_t currentHeadersTime;
size_t connections; size_t connections;
int64_t netsolps; int64_t netsolps;
const Consensus::Params& params = Params().GetConsensus();
{ {
LOCK2(cs_main, cs_vNodes); LOCK2(cs_main, cs_vNodes);
height = chainActive.Height(); height = chainActive.Height();
@ -225,12 +268,25 @@ int printStats(bool mining)
if (IsInitialBlockDownload(Params())) { if (IsInitialBlockDownload(Params())) {
int netheight = currentHeadersHeight == -1 || currentHeadersTime == 0 ? int netheight = currentHeadersHeight == -1 || currentHeadersTime == 0 ?
0 : EstimateNetHeight(Params().GetConsensus(), currentHeadersHeight, currentHeadersTime); 0 : EstimateNetHeight(params, currentHeadersHeight, currentHeadersTime);
int downloadPercent = height * 100 / netheight; int downloadPercent = height * 100 / netheight;
std::cout << " " << _("Downloading blocks") << " | " << height << " / ~" << netheight << " (" << downloadPercent << "%)" << std::endl; std::cout << " " << _("Downloading blocks") << " | " << height << " / ~" << netheight << " (" << downloadPercent << "%)" << std::endl;
} else { } else {
std::cout << " " << _("Block height") << " | " << height << std::endl; std::cout << " " << _("Block height") << " | " << height << std::endl;
} }
auto secondsLeft = SecondsLeftToNextEpoch(params, height);
std::string strUpgradeTime;
if (secondsLeft) {
auto nextHeight = NextActivationHeight(height, params).value();
auto nextBranch = NextEpoch(height, params).value();
strUpgradeTime = strprintf(_("%s at block height %d, in around %s"),
NetworkUpgradeInfo[nextBranch].strName, nextHeight, DisplayDuration(secondsLeft.value(), DurationFormat::REDUCED));
}
else {
strUpgradeTime = "Unknown";
}
std::cout << " " << _("Next upgrade") << " | " << strUpgradeTime << std::endl;
std::cout << " " << _("Connections") << " | " << connections << std::endl; std::cout << " " << _("Connections") << " | " << connections << std::endl;
std::cout << " " << _("Network solution rate") << " | " << netsolps << " Sol/s" << std::endl; std::cout << " " << _("Network solution rate") << " | " << netsolps << " Sol/s" << std::endl;
if (mining && miningTimer.running()) { if (mining && miningTimer.running()) {
@ -286,24 +342,9 @@ int printMetrics(size_t cols, bool mining)
// Number of lines that are always displayed // Number of lines that are always displayed
int lines = 3; int lines = 3;
// Calculate uptime // Calculate and display uptime
int64_t uptime = GetUptime(); std::string duration = DisplayDuration(GetUptime(), DurationFormat::FULL);
int days = uptime / (24 * 60 * 60);
int hours = (uptime - (days * 24 * 60 * 60)) / (60 * 60);
int minutes = (uptime - (((days * 24) + hours) * 60 * 60)) / 60;
int seconds = uptime - (((((days * 24) + hours) * 60) + minutes) * 60);
// Display uptime
std::string duration;
if (days > 0) {
duration = strprintf(_("%d days, %d hours, %d minutes, %d seconds"), days, hours, minutes, seconds);
} else if (hours > 0) {
duration = strprintf(_("%d hours, %d minutes, %d seconds"), hours, minutes, seconds);
} else if (minutes > 0) {
duration = strprintf(_("%d minutes, %d seconds"), minutes, seconds);
} else {
duration = strprintf(_("%d seconds"), seconds);
}
std::string strDuration = strprintf(_("Since starting this node %s ago:"), duration); std::string strDuration = strprintf(_("Since starting this node %s ago:"), duration);
std::cout << strDuration << std::endl; std::cout << strDuration << std::endl;
lines += (strDuration.size() / cols); lines += (strDuration.size() / cols);

View File

@ -55,6 +55,11 @@ public:
double rate(const AtomicCounter& count); double rate(const AtomicCounter& count);
}; };
enum DurationFormat {
FULL,
REDUCED
};
extern AtomicCounter transactionsValidated; extern AtomicCounter transactionsValidated;
extern AtomicCounter ehSolverRuns; extern AtomicCounter ehSolverRuns;
extern AtomicCounter solutionTargetChecks; extern AtomicCounter solutionTargetChecks;
@ -65,6 +70,8 @@ void TrackMinedBlock(uint256 hash);
void MarkStartTime(); void MarkStartTime();
double GetLocalSolPS(); double GetLocalSolPS();
int EstimateNetHeight(const Consensus::Params& params, int currentBlockHeight, int64_t currentBlockTime); int EstimateNetHeight(const Consensus::Params& params, int currentBlockHeight, int64_t currentBlockTime);
boost::optional<int64_t> SecondsLeftToNextEpoch(const Consensus::Params& params, int currentHeight);
std::string DisplayDuration(int64_t time, DurationFormat format);
void TriggerRefresh(); void TriggerRefresh();