// Copyright (c) 2016 The Zcash developers
// Distributed under the MIT software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or https://www.opensource.org/licenses/mit-license.php .
#include "metrics.h"
#include "chainparams.h"
#include "checkpoints.h"
#include "main.h"
+#include "timedata.h"
#include "ui_interface.h"
#include "util.h"
#include "utiltime.h"
#endif
#include <unistd.h>
+extern uint64_t ASSETCHAINS_TIMELOCKGTE;
+extern uint32_t ASSETCHAINS_ALGO, ASSETCHAINS_VERUSHASH;
+int64_t komodo_block_unlocktime(uint32_t nHeight);
+
void AtomicTimer::start()
{
std::unique_lock<std::mutex> lock(mtx);
return duration > 0 ? (double)count.get() / duration : 0;
}
-CCriticalSection cs_metrics;
-
boost::synchronized_value<int64_t> nNodeStartTime;
boost::synchronized_value<int64_t> nNextRefresh;
AtomicCounter transactionsValidated;
AtomicCounter ehSolverRuns;
AtomicCounter solutionTargetChecks;
-AtomicCounter minedBlocks;
-AtomicTimer miningTimer;
+static AtomicCounter minedBlocks;
+PerfCounterTimer miningTimer;
+CCriticalSection cs_metrics;
+
+double AtomicTimer::rate(const int64_t &count)
+{
+ std::unique_lock<std::mutex> lock(mtx);
+ LOCK(cs_metrics);
+ int64_t duration = total_time;
+ if (threads > 0) {
+ // Timer is running, so get the latest count
+ duration += GetTime() - start_time;
+ }
+ return duration > 0 ? (double)count / duration : 0;
+}
+
+double PerfCounterTimer::rate()
+{
+ return AtomicTimer::rate(counter);
+}
+
+double PerfCounterTimer::rate(const AtomicCounter &count)
+{
+ return AtomicTimer::rate(count);
+}
+
+double PerfCounterTimer::rate(const int64_t &count)
+{
+ return AtomicTimer::rate(count);
+}
+
+void PerfCounterTimer::clear()
+{
+ std::unique_lock<std::mutex> lock(mtx);
+ if (!threads)
+ {
+ counter = 0;
+ start_time = GetTime();
+ total_time = 0;
+ }
+}
+
+int64_t PerfCounterTimer::operator+=(int64_t operand)
+{
+ std::unique_lock<std::mutex> lock(mtx);
+ return counter += operand;
+}
-boost::synchronized_value<std::list<uint256>> trackedBlocks;
+static boost::synchronized_value<std::list<uint256>> trackedBlocks;
-boost::synchronized_value<std::list<std::string>> messageBox;
-boost::synchronized_value<std::string> initMessage;
-bool loaded = false;
+static boost::synchronized_value<std::list<std::string>> messageBox;
+static boost::synchronized_value<std::string> initMessage;
+static bool loaded = false;
extern int64_t GetNetworkHashPS(int lookup, int height);
double GetLocalSolPS()
{
- return miningTimer.rate(solutionTargetChecks);
+ if (ASSETCHAINS_ALGO == ASSETCHAINS_VERUSHASH)
+ {
+ return miningTimer.rate();
+ }
+ else
+ return miningTimer.rate(solutionTargetChecks);
}
-int EstimateNetHeightInner(int height, int64_t tipmediantime,
- int heightLastCheckpoint, int64_t timeLastCheckpoint,
- int64_t genesisTime, int64_t targetSpacing)
+int EstimateNetHeight(const Consensus::Params& params, int currentHeadersHeight, int64_t currentHeadersTime)
{
- // We average the target spacing with the observed spacing to the last
- // checkpoint (either from below or above depending on the current height),
- // and use that to estimate the current network height.
- 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;
- int netheight = medianHeight + ((GetTime() - tipmediantime) / averageSpacing);
- // Round to nearest ten to reduce noise
- return ((netheight + 5) / 10) * 10;
-}
+ int64_t now = GetAdjustedTime();
+ if (currentHeadersTime >= now) {
+ return currentHeadersHeight;
+ }
-int EstimateNetHeight(int height, int64_t tipmediantime, CChainParams chainParams)
-{
- auto checkpointData = chainParams.Checkpoints();
- return EstimateNetHeightInner(
- height, tipmediantime,
- Checkpoints::GetTotalBlocksEstimate(checkpointData),
- checkpointData.nTimeLastCheckpoint,
- chainParams.GenesisBlock().nTime,
- chainParams.GetConsensus().nPowTargetSpacing);
+ int estimatedHeight = currentHeadersHeight + (now - currentHeadersTime) / params.PoWTargetSpacing(currentHeadersHeight);
+
+ int blossomActivationHeight = params.vUpgrades[Consensus::UPGRADE_BLOSSOM].nActivationHeight;
+ if (currentHeadersHeight >= blossomActivationHeight || estimatedHeight <= blossomActivationHeight) {
+ return ((estimatedHeight + 5) / 10) * 10;
+ }
+
+ int numPreBlossomBlocks = blossomActivationHeight - currentHeadersHeight;
+ int64_t preBlossomTime = numPreBlossomBlocks * params.PoWTargetSpacing(blossomActivationHeight - 1);
+ int64_t blossomActivationTime = currentHeadersTime + preBlossomTime;
+ if (blossomActivationTime >= now) {
+ return blossomActivationHeight;
+ }
+
+ int netheight = blossomActivationHeight + (now - blossomActivationTime) / params.PoWTargetSpacing(blossomActivationHeight);
+ return ((netheight + 5) / 10) * 10;
}
void TriggerRefresh()
int lines = 4;
int height;
- int64_t tipmediantime;
+ int64_t currentHeadersHeight;
+ int64_t currentHeadersTime;
size_t connections;
int64_t netsolps;
{
LOCK2(cs_main, cs_vNodes);
height = chainActive.Height();
- tipmediantime = chainActive.LastTip()->GetMedianTimePast();
+ currentHeadersHeight = pindexBestHeader ? pindexBestHeader->GetHeight(): -1;
+ currentHeadersTime = pindexBestHeader ? pindexBestHeader->nTime : 0;
connections = vNodes.size();
netsolps = GetNetworkHashPS(120, -1);
}
auto localsolps = GetLocalSolPS();
- if (IsInitialBlockDownload()) {
- int netheight = EstimateNetHeight(height, tipmediantime, Params());
+ if (IsInitialBlockDownload(Params())) {
+ int netheight = currentHeadersHeight == -1 || currentHeadersTime == 0 ?
+ 0 : EstimateNetHeight(Params().GetConsensus(), currentHeadersHeight, currentHeadersTime);
int downloadPercent = height * 100 / netheight;
std::cout << " " << _("Downloading blocks") << " | " << height << " / ~" << netheight << " (" << downloadPercent << "%)" << std::endl;
} else {
}
if (fvNodesEmpty) {
std::cout << _("Mining is paused while waiting for connections.") << std::endl;
- } else if (IsInitialBlockDownload()) {
+ } else if (IsInitialBlockDownload(Params())) {
std::cout << _("Mining is paused while downloading blocks.") << std::endl;
} else {
std::cout << _("Mining is paused (a JoinSplit may be in progress).") << std::endl;
auto hash = *it;
if (mapBlockIndex.count(hash) > 0 &&
chainActive.Contains(mapBlockIndex[hash])) {
- int height = mapBlockIndex[hash]->nHeight;
+ int height = mapBlockIndex[hash]->GetHeight();
CAmount subsidy = GetBlockSubsidy(height, consensusParams);
- if ((height > 0) && (height <= consensusParams.GetLastFoundersRewardBlockHeight())) {
+ if ((height > 0) && (height <= consensusParams.GetLastFoundersRewardBlockHeight(height))) {
subsidy -= subsidy/5;
}
- if (std::max(0, COINBASE_MATURITY - (tipHeight - height)) > 0) {
+
+ if ((std::max(0, COINBASE_MATURITY - (tipHeight - height)) > 0) ||
+ (tipHeight < komodo_block_unlocktime(height) && subsidy >= ASSETCHAINS_TIMELOCKGTE)) {
immature += subsidy;
} else {
mature += subsidy;
return 2;
}
+#ifdef WIN32
+#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
+
+bool enableVTMode()
+{
+ // Set output mode to handle virtual terminal sequences
+ HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
+ if (hOut == INVALID_HANDLE_VALUE) {
+ return false;
+ }
+
+ DWORD dwMode = 0;
+ if (!GetConsoleMode(hOut, &dwMode)) {
+ return false;
+ }
+
+ dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
+ if (!SetConsoleMode(hOut, dwMode)) {
+ return false;
+ }
+ return true;
+}
+#endif
+
void ThreadShowMetricsScreen()
{
// Make this thread recognisable as the metrics screen thread
int64_t nRefresh = GetArg("-metricsrefreshtime", isTTY ? 1 : 600);
if (isScreen) {
+#ifdef WIN32
+ enableVTMode();
+#endif
+
// Clear screen
std::cout << "\e[2J";
// Get current window size
if (isTTY) {
#ifdef _WIN32
- CONSOLE_SCREEN_BUFFER_INFO csbi;
- GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
- cols = csbi.srWindow.Right - csbi.srWindow.Left + 1;
- #else
- struct winsize w;
- w.ws_col = 0;
- if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) != -1 && w.ws_col != 0) {
- cols = w.ws_col;
- }
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
+ if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi) != 0) {
+ cols = csbi.srWindow.Right - csbi.srWindow.Left + 1;
+ }
+#else
+ struct winsize w;
+ w.ws_col = 0;
+ if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) != -1 && w.ws_col != 0) {
+ cols = w.ws_col;
+ }
#endif
}
if (isScreen) {
// Explain how to exit
- std::cout << "[" << _("Press Ctrl+C to exit") << "] [" << _("Set 'showmetrics=0' to hide") << "]" << std::endl;
+ std::cout << "[";
+#ifdef WIN32
+ std::cout << _("'zcash-cli.exe stop' to exit");
+#else
+ std::cout << _("Press Ctrl+C to exit");
+#endif
+ std::cout << "] [" << _("Set 'showmetrics=0' to hide") << "]" << std::endl;
} else {
// Print delineator
std::cout << "----------------------------------------" << std::endl;