diff --git a/src/Makefile.gtest.include b/src/Makefile.gtest.include index 8c41ef783..7cd10cc22 100644 --- a/src/Makefile.gtest.include +++ b/src/Makefile.gtest.include @@ -1,14 +1,16 @@ TESTS += zcash-gtest bin_PROGRAMS += zcash-gtest -# tool for generating our public parameters +# tool for generating our public parameters. +# test_checktransaction.cpp MUST be before +# any test that calls SelectParams(). zcash_gtest_SOURCES = \ gtest/main.cpp \ gtest/utils.cpp \ - gtest/test_checkblock.cpp \ gtest/test_checktransaction.cpp \ + gtest/test_checkblock.cpp \ gtest/json_test_vectors.cpp \ - gtest/json_test_vectors.h \ + gtest/json_test_vectors.h \ gtest/test_foundersreward.cpp \ gtest/test_wallet_zkeys.cpp \ gtest/test_jsonspirit.cpp \ diff --git a/src/chainparams.cpp b/src/chainparams.cpp index c3b9ae2de..b6bd2dfa0 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -36,6 +36,7 @@ class CMainParams : public CChainParams { public: CMainParams() { strNetworkID = "main"; + strCurrencyUnits = "ZEC"; consensus.fCoinbaseMustBeProtected = true; consensus.nSubsidySlowStartInterval = 20000; consensus.nSubsidyHalvingInterval = 840000; @@ -203,6 +204,7 @@ class CTestNetParams : public CMainParams { public: CTestNetParams() { strNetworkID = "test"; + strCurrencyUnits = "TAZ"; consensus.nMajorityEnforceBlockUpgrade = 51; consensus.nMajorityRejectBlockOutdated = 75; consensus.nMajorityWindow = 400; @@ -288,6 +290,7 @@ class CRegTestParams : public CTestNetParams { public: CRegTestParams() { strNetworkID = "regtest"; + strCurrencyUnits = "REG"; consensus.fCoinbaseMustBeProtected = false; consensus.nSubsidySlowStartInterval = 0; consensus.nSubsidyHalvingInterval = 150; diff --git a/src/chainparams.h b/src/chainparams.h index ecb4f94c3..0af9920de 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -67,6 +67,7 @@ public: int64_t PruneAfterHeight() const { return nPruneAfterHeight; } unsigned int EquihashN() const { return nEquihashN; } unsigned int EquihashK() const { return nEquihashK; } + std::string CurrencyUnits() const { return strCurrencyUnits; } /** Make miner stop after a block is found. In RPC, don't return until nGenProcLimit blocks are generated */ bool MineBlocksOnDemand() const { return fMineBlocksOnDemand; } /** In the future use NetworkIDString() for RPC fields */ @@ -99,6 +100,7 @@ protected: std::vector vSeeds; std::vector base58Prefixes[MAX_BASE58_TYPES]; std::string strNetworkID; + std::string strCurrencyUnits; CBlock genesis; std::vector vFixedSeeds; bool fRequireRPCPassword = false; diff --git a/src/metrics.cpp b/src/metrics.cpp index a5480838e..4d97312e2 100644 --- a/src/metrics.cpp +++ b/src/metrics.cpp @@ -5,9 +5,11 @@ #include "metrics.h" #include "chainparams.h" +#include "main.h" #include "ui_interface.h" #include "util.h" #include "utiltime.h" +#include "utilmoneystr.h" #include #include @@ -15,15 +17,28 @@ #include #include +CCriticalSection cs_metrics; + AtomicCounter transactionsValidated; AtomicCounter ehSolverRuns; AtomicCounter solutionTargetChecks; AtomicCounter minedBlocks; +boost::synchronized_value> trackedBlocks; + boost::synchronized_value> messageBox; boost::synchronized_value initMessage; bool loaded = false; +extern int64_t GetNetworkHashPS(int lookup, int height); + +void TrackMinedBlock(uint256 hash) +{ + LOCK(cs_metrics); + minedBlocks.increment(); + trackedBlocks->push_back(hash); +} + static bool metrics_ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style) @@ -64,8 +79,23 @@ void ConnectMetricsScreen() uiInterface.InitMessage.connect(metrics_InitMessage); } -void printMiningStatus(bool mining) +int printNetworkStats() { + LOCK2(cs_main, cs_vNodes); + + std::cout << " " << _("Block height") << " | " << chainActive.Height() << std::endl; + std::cout << " " << _("Network solution rate") << " | " << GetNetworkHashPS(120, -1) << " Sol/s" << std::endl; + std::cout << " " << _("Connections") << " | " << vNodes.size() << std::endl; + std::cout << std::endl; + + return 4; +} + +int printMiningStatus(bool mining) +{ + // Number of lines that are always displayed + int lines = 1; + if (mining) { int nThreads = GetArg("-genproclimit", 1); if (nThreads < 0) { @@ -75,12 +105,17 @@ void printMiningStatus(bool mining) else nThreads = boost::thread::hardware_concurrency(); } - std::cout << strprintf(_("You are running %d mining threads."), nThreads) << std::endl; + std::cout << strprintf(_("You are mining with the %s solver on %d threads."), + GetArg("-equihashsolver", "default"), nThreads) << std::endl; + lines++; } else { std::cout << _("You are currently not mining.") << std::endl; std::cout << _("To enable mining, add 'gen=1' to your zcash.conf and restart.") << std::endl; + lines += 2; } std::cout << std::endl; + + return lines; } int printMetrics(size_t cols, int64_t nStart, bool mining) @@ -112,17 +147,59 @@ int printMetrics(size_t cols, int64_t nStart, bool mining) std::cout << "- " << strprintf(_("You have validated %d transactions!"), transactionsValidated.get()) << std::endl; - if (mining) { + if (mining && loaded) { double solps = uptime > 0 ? (double)solutionTargetChecks.get() / uptime : 0; std::string strSolps = strprintf("%.4f Sol/s", solps); std::cout << "- " << strprintf(_("You have contributed %s on average to the network solution rate."), strSolps) << std::endl; std::cout << "- " << strprintf(_("You have completed %d Equihash solver runs."), ehSolverRuns.get()) << std::endl; lines += 2; - int mined = minedBlocks.get(); + int mined = 0; + int orphaned = 0; + CAmount immature {0}; + CAmount mature {0}; + { + LOCK2(cs_main, cs_metrics); + boost::strict_lock_ptr> u = trackedBlocks.synchronize(); + auto consensusParams = Params().GetConsensus(); + auto tipHeight = chainActive.Height(); + + // Update orphans and calculate subsidies + std::list::iterator it = u->begin(); + while (it != u->end()) { + auto hash = *it; + if (mapBlockIndex.count(hash) > 0 && + chainActive.Contains(mapBlockIndex[hash])) { + int height = mapBlockIndex[hash]->nHeight; + CAmount subsidy = GetBlockSubsidy(height, consensusParams); + if ((height > 0) && (height <= consensusParams.GetLastFoundersRewardBlockHeight())) { + subsidy -= subsidy/5; + } + if (std::max(0, COINBASE_MATURITY - (tipHeight - height)) > 0) { + immature += subsidy; + } else { + mature += subsidy; + } + it++; + } else { + it = u->erase(it); + } + } + + mined = minedBlocks.get(); + orphaned = mined - u->size(); + } + if (mined > 0) { + std::string units = Params().CurrencyUnits(); std::cout << "- " << strprintf(_("You have mined %d blocks!"), mined) << std::endl; - lines++; + std::cout << " " + << strprintf(_("Orphaned: %d blocks, Immature: %u %s, Mature: %u %s"), + orphaned, + FormatMoney(immature), units, + FormatMoney(mature), units) + << std::endl; + lines += 2; } } std::cout << std::endl; @@ -183,10 +260,6 @@ void ThreadShowMetricsScreen() std::cout << _("You're helping to strengthen the network and contributing to a social good :)") << std::endl; std::cout << std::endl; - // Miner status - bool mining = GetBoolArg("-gen", false); - printMiningStatus(mining); - // Count uptime int64_t nStart = GetTime(); @@ -207,6 +280,13 @@ void ThreadShowMetricsScreen() // Erase below current position std::cout << "\e[J"; + // Miner status + bool mining = GetBoolArg("-gen", false); + + if (loaded) { + lines += printNetworkStats(); + } + lines += printMiningStatus(mining); lines += printMetrics(cols, nStart, mining); lines += printMessageBox(cols); lines += printInitMessage(); diff --git a/src/metrics.h b/src/metrics.h index 4a2ca2264..2c5e7bd2c 100644 --- a/src/metrics.h +++ b/src/metrics.h @@ -2,11 +2,13 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "uint256.h" + #include #include struct AtomicCounter { - std::atomic value; + std::atomic value; AtomicCounter() : value {0} { } @@ -26,7 +28,8 @@ struct AtomicCounter { extern AtomicCounter transactionsValidated; extern AtomicCounter ehSolverRuns; extern AtomicCounter solutionTargetChecks; -extern AtomicCounter minedBlocks; + +void TrackMinedBlock(uint256 hash); void ConnectMetricsScreen(); void ThreadShowMetricsScreen(); diff --git a/src/miner.cpp b/src/miner.cpp index 9289a9f63..ddab39f74 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -440,7 +440,7 @@ static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& rese if (!ProcessNewBlock(state, NULL, pblock, true, NULL)) return error("ZcashMiner: ProcessNewBlock, block not accepted"); - minedBlocks.increment(); + TrackMinedBlock(pblock->GetHash()); return true; } diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 3759bd03a..af34c291c 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -37,7 +37,7 @@ using namespace std; * or over the difficulty averaging window if 'lookup' is nonpositive. * If 'height' is nonnegative, compute the estimate at the time when a given block was found. */ -Value GetNetworkHashPS(int lookup, int height) { +int64_t GetNetworkHashPS(int lookup, int height) { CBlockIndex *pb = chainActive.Tip(); if (height >= 0 && height < chainActive.Height()) @@ -205,7 +205,6 @@ endloop: CValidationState state; if (!ProcessNewBlock(state, NULL, pblock, true, NULL)) throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted"); - minedBlocks.increment(); ++nHeight; blockHashes.push_back(pblock->GetHash().GetHex()); }