From d793f94b8a33040afa35be6899ea6c81e32f26ee Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Sun, 30 Oct 2016 14:36:36 -0700 Subject: [PATCH 01/10] Track mined blocks to detect and report orphans and mining revenue Part of #1713 Closes #1716 --- src/chainparams.cpp | 3 +++ src/chainparams.h | 2 ++ src/metrics.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++++- src/metrics.h | 5 ++++- src/miner.cpp | 2 +- src/rpcmining.cpp | 1 - 6 files changed, 56 insertions(+), 4 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 8691455e8..59869dff9 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; @@ -202,6 +203,7 @@ class CTestNetParams : public CMainParams { public: CTestNetParams() { strNetworkID = "test"; + strCurrencyUnits = "TAZ"; consensus.nMajorityEnforceBlockUpgrade = 51; consensus.nMajorityRejectBlockOutdated = 75; consensus.nMajorityWindow = 400; @@ -287,6 +289,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..78b3b4ecc 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 @@ -20,10 +22,18 @@ AtomicCounter ehSolverRuns; AtomicCounter solutionTargetChecks; AtomicCounter minedBlocks; +boost::synchronized_value> trackedBlocks; + boost::synchronized_value> messageBox; boost::synchronized_value initMessage; bool loaded = false; +void TrackMinedBlock(uint256 hash) +{ + minedBlocks.increment(); + trackedBlocks->push_back(hash); +} + static bool metrics_ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style) @@ -121,8 +131,43 @@ int printMetrics(size_t cols, int64_t nStart, bool mining) int mined = minedBlocks.get(); if (mined > 0) { + LOCK(cs_main); + boost::strict_lock_ptr> u = trackedBlocks.synchronize(); + auto consensusParams = Params().GetConsensus(); + auto tipHeight = chainActive.Height(); + std::string units = Params().CurrencyUnits(); + + // Update orphans and calculate subsidies + CAmount immature {0}; + CAmount mature {0}; + for (std::list::iterator it = u->begin(); it != u->end(); it++) { + 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; + } + } else { + it = u->erase(it); + } + } + int orphaned = mined - u->size(); + 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; diff --git a/src/metrics.h b/src/metrics.h index 4a2ca2264..b2cacd03a 100644 --- a/src/metrics.h +++ b/src/metrics.h @@ -2,6 +2,8 @@ // 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 @@ -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 bde9babd5..9ffe6b9c8 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -438,7 +438,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..a23d6b991 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -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()); } From 848c89cd6725ef1260165b751352520592bbaa58 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Sun, 30 Oct 2016 14:37:20 -0700 Subject: [PATCH 02/10] Refresh mining status to detect setgenerate changes Closes #1656 --- src/metrics.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/metrics.cpp b/src/metrics.cpp index 78b3b4ecc..580c88f6e 100644 --- a/src/metrics.cpp +++ b/src/metrics.cpp @@ -74,8 +74,11 @@ void ConnectMetricsScreen() uiInterface.InitMessage.connect(metrics_InitMessage); } -void printMiningStatus(bool mining) +int printMiningStatus(bool mining) { + // Number of lines that are always displayed + int lines = 1; + if (mining) { int nThreads = GetArg("-genproclimit", 1); if (nThreads < 0) { @@ -86,11 +89,15 @@ void printMiningStatus(bool mining) nThreads = boost::thread::hardware_concurrency(); } std::cout << strprintf(_("You are running %d mining threads."), 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) @@ -228,10 +235,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(); @@ -252,6 +255,10 @@ void ThreadShowMetricsScreen() // Erase below current position std::cout << "\e[J"; + // Miner status + bool mining = GetBoolArg("-gen", false); + + lines += printMiningStatus(mining); lines += printMetrics(cols, nStart, mining); lines += printMessageBox(cols); lines += printInitMessage(); From eb5b582e1fedb2afe12c80add36c2e199e6058ec Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Sun, 30 Oct 2016 15:25:40 -0700 Subject: [PATCH 03/10] Add network stats to metrics screen Closes #1688 --- src/metrics.cpp | 20 +++++++++++++++++++- src/rpcmining.cpp | 2 +- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/metrics.cpp b/src/metrics.cpp index 580c88f6e..cfc5c987b 100644 --- a/src/metrics.cpp +++ b/src/metrics.cpp @@ -28,6 +28,8 @@ boost::synchronized_value> messageBox; boost::synchronized_value initMessage; bool loaded = false; +extern int64_t GetNetworkHashPS(int lookup, int height); + void TrackMinedBlock(uint256 hash) { minedBlocks.increment(); @@ -74,6 +76,18 @@ void ConnectMetricsScreen() uiInterface.InitMessage.connect(metrics_InitMessage); } +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 @@ -88,7 +102,8 @@ int 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; @@ -258,6 +273,9 @@ void ThreadShowMetricsScreen() // Miner status bool mining = GetBoolArg("-gen", false); + if (loaded) { + lines += printNetworkStats(); + } lines += printMiningStatus(mining); lines += printMetrics(cols, nStart, mining); lines += printMessageBox(cols); diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index a23d6b991..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()) From 24f10266894245117f86c620a1be72fba26a6661 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Sun, 30 Oct 2016 16:54:05 -0700 Subject: [PATCH 04/10] Show mining info once the node has finished loading Closes #1685 --- src/metrics.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/metrics.cpp b/src/metrics.cpp index cfc5c987b..d2a15d91a 100644 --- a/src/metrics.cpp +++ b/src/metrics.cpp @@ -144,7 +144,7 @@ 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; From cb7098317d961cecf574df85c89051cb77c7cbb0 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Tue, 1 Nov 2016 11:59:40 -0500 Subject: [PATCH 05/10] Improve locking in metrics --- src/metrics.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/metrics.cpp b/src/metrics.cpp index d2a15d91a..34896a6b1 100644 --- a/src/metrics.cpp +++ b/src/metrics.cpp @@ -17,6 +17,8 @@ #include #include +CCriticalSection cs_metrics; + AtomicCounter transactionsValidated; AtomicCounter ehSolverRuns; AtomicCounter solutionTargetChecks; @@ -32,6 +34,7 @@ extern int64_t GetNetworkHashPS(int lookup, int height); void TrackMinedBlock(uint256 hash) { + LOCK(cs_metrics); minedBlocks.increment(); trackedBlocks->push_back(hash); } @@ -151,9 +154,10 @@ int printMetrics(size_t cols, int64_t nStart, bool mining) std::cout << "- " << strprintf(_("You have completed %d Equihash solver runs."), ehSolverRuns.get()) << std::endl; lines += 2; - int mined = minedBlocks.get(); - if (mined > 0) { - LOCK(cs_main); + int mined = 0; + int orphaned = 0; + { + LOCK2(cs_main, cs_metrics); boost::strict_lock_ptr> u = trackedBlocks.synchronize(); auto consensusParams = Params().GetConsensus(); auto tipHeight = chainActive.Height(); @@ -180,8 +184,12 @@ int printMetrics(size_t cols, int64_t nStart, bool mining) it = u->erase(it); } } - int orphaned = mined - u->size(); + mined = minedBlocks.get(); + orphaned = mined - u->size(); + } + + if (mined > 0) { std::cout << "- " << strprintf(_("You have mined %d blocks!"), mined) << std::endl; std::cout << " " << strprintf(_("Orphaned: %d blocks, Immature: %u %s, Mature: %u %s"), From 22ee0efe25f9a1c402ec3f4561319e6507b0d266 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Tue, 1 Nov 2016 20:37:59 -0500 Subject: [PATCH 06/10] Fix previous commit --- src/metrics.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/metrics.cpp b/src/metrics.cpp index 34896a6b1..6b047bbe8 100644 --- a/src/metrics.cpp +++ b/src/metrics.cpp @@ -156,16 +156,15 @@ int printMetrics(size_t cols, int64_t nStart, bool mining) 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(); - std::string units = Params().CurrencyUnits(); // Update orphans and calculate subsidies - CAmount immature {0}; - CAmount mature {0}; for (std::list::iterator it = u->begin(); it != u->end(); it++) { auto hash = *it; if (mapBlockIndex.count(hash) > 0 && @@ -190,6 +189,7 @@ int printMetrics(size_t cols, int64_t nStart, bool mining) } if (mined > 0) { + std::string units = Params().CurrencyUnits(); std::cout << "- " << strprintf(_("You have mined %d blocks!"), mined) << std::endl; std::cout << " " << strprintf(_("Orphaned: %d blocks, Immature: %u %s, Mature: %u %s"), From 73a439185d3a52119fbdca6a897ecb18b2faf4f2 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 2 Nov 2016 09:20:35 -0500 Subject: [PATCH 07/10] Ensure that no tracked blocks are skipped during orphan detection --- src/metrics.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/metrics.cpp b/src/metrics.cpp index 6b047bbe8..4d97312e2 100644 --- a/src/metrics.cpp +++ b/src/metrics.cpp @@ -165,7 +165,8 @@ int printMetrics(size_t cols, int64_t nStart, bool mining) auto tipHeight = chainActive.Height(); // Update orphans and calculate subsidies - for (std::list::iterator it = u->begin(); it != u->end(); it++) { + std::list::iterator it = u->begin(); + while (it != u->end()) { auto hash = *it; if (mapBlockIndex.count(hash) > 0 && chainActive.Contains(mapBlockIndex[hash])) { @@ -179,6 +180,7 @@ int printMetrics(size_t cols, int64_t nStart, bool mining) } else { mature += subsidy; } + it++; } else { it = u->erase(it); } From 3bddaf632e034abda1a08ba2b4190fe63ca61ac6 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 2 Nov 2016 14:50:00 -0500 Subject: [PATCH 08/10] Use uint64_t for AtomicCounter --- src/metrics.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/metrics.h b/src/metrics.h index b2cacd03a..2c5e7bd2c 100644 --- a/src/metrics.h +++ b/src/metrics.h @@ -8,7 +8,7 @@ #include struct AtomicCounter { - std::atomic value; + std::atomic value; AtomicCounter() : value {0} { } From e80490f5ffaad9714c7702a992b9bf5e237d7fce Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 2 Nov 2016 16:45:38 -0500 Subject: [PATCH 09/10] Fix gtest issue introduced into master --- src/Makefile.gtest.include | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Makefile.gtest.include b/src/Makefile.gtest.include index 8c41ef783..9c21e2c7f 100644 --- a/src/Makefile.gtest.include +++ b/src/Makefile.gtest.include @@ -1,12 +1,14 @@ 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/test_foundersreward.cpp \ From 6b820113e96c0f733263a250c76294f882802e5c Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 2 Nov 2016 17:43:37 -0500 Subject: [PATCH 10/10] Fix whitespace in Makefile.gtest.include --- src/Makefile.gtest.include | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.gtest.include b/src/Makefile.gtest.include index 9c21e2c7f..7cd10cc22 100644 --- a/src/Makefile.gtest.include +++ b/src/Makefile.gtest.include @@ -10,7 +10,7 @@ zcash_gtest_SOURCES = \ 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 \