Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add getlocalsolps and getnetworksolps RPC calls, show them in getmininginfo #1642

Merged
merged 1 commit into from Dec 9, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Makefile.gtest.include
Expand Up @@ -19,6 +19,7 @@ zcash_gtest_SOURCES = \
gtest/test_keystore.cpp \
gtest/test_noteencryption.cpp \
gtest/test_merkletree.cpp \
gtest/test_metrics.cpp \
gtest/test_pow.cpp \
gtest/test_random.cpp \
gtest/test_rpc.cpp \
Expand Down
30 changes: 30 additions & 0 deletions src/gtest/test_metrics.cpp
@@ -0,0 +1,30 @@
#include <gtest/gtest.h>

#include "metrics.h"
#include "utiltime.h"


TEST(Metrics, GetLocalSolPS) {
SetMockTime(100);
MarkStartTime();

// No time has passed
EXPECT_EQ(0, GetLocalSolPS());

// Increment time
SetMockTime(101);
EXPECT_EQ(0, GetLocalSolPS());

// Increment solutions
solutionTargetChecks.increment();
EXPECT_EQ(1, GetLocalSolPS());

// Increment time
SetMockTime(102);
EXPECT_EQ(0.5, GetLocalSolPS());

// Increment solutions
solutionTargetChecks.increment();
solutionTargetChecks.increment();
EXPECT_EQ(1.5, GetLocalSolPS());
}
3 changes: 3 additions & 0 deletions src/init.cpp
Expand Up @@ -979,6 +979,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
CScheduler::Function serviceLoop = boost::bind(&CScheduler::serviceQueue, &scheduler);
threadGroup.create_thread(boost::bind(&TraceThread<CScheduler::Function>, "scheduler", serviceLoop));

// Count uptime
MarkStartTime();

if ((chainparams.NetworkIDString() != "regtest") &&
GetBoolArg("-showmetrics", true) &&
!fPrintToConsole && !GetBoolArg("-daemon", false)) {
Expand Down
32 changes: 25 additions & 7 deletions src/metrics.cpp
Expand Up @@ -19,6 +19,7 @@

CCriticalSection cs_metrics;

boost::synchronized_value<int64_t> nNodeStartTime;
AtomicCounter transactionsValidated;
AtomicCounter ehSolverRuns;
AtomicCounter solutionTargetChecks;
Expand All @@ -39,6 +40,26 @@ void TrackMinedBlock(uint256 hash)
trackedBlocks->push_back(hash);
}

void MarkStartTime()
{
*nNodeStartTime = GetTime();
}

int64_t GetUptime()
{
return GetTime() - *nNodeStartTime;
}

double GetLocalSolPS_INTERNAL(int64_t uptime)
{
return uptime > 0 ? (double)solutionTargetChecks.get() / uptime : 0;
}

double GetLocalSolPS()
{
return GetLocalSolPS_INTERNAL(GetUptime());
}

static bool metrics_ThreadSafeMessageBox(const std::string& message,
const std::string& caption,
unsigned int style)
Expand Down Expand Up @@ -118,13 +139,13 @@ int printMiningStatus(bool mining)
return lines;
}

int printMetrics(size_t cols, int64_t nStart, bool mining)
int printMetrics(size_t cols, bool mining)
{
// Number of lines that are always displayed
int lines = 3;

// Calculate uptime
int64_t uptime = GetTime() - nStart;
int64_t uptime = GetUptime();
int days = uptime / (24 * 60 * 60);
int hours = (uptime - (days * 24 * 60 * 60)) / (60 * 60);
int minutes = (uptime - (((days * 24) + hours) * 60 * 60)) / 60;
Expand All @@ -148,7 +169,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 && loaded) {
double solps = uptime > 0 ? (double)solutionTargetChecks.get() / uptime : 0;
double solps = GetLocalSolPS_INTERNAL(uptime);
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;
Expand Down Expand Up @@ -260,9 +281,6 @@ void ThreadShowMetricsScreen()
std::cout << _("You're helping to strengthen the network and contributing to a social good :)") << std::endl;
std::cout << std::endl;

// Count uptime
int64_t nStart = GetTime();

while (true) {
// Number of lines that are always displayed
int lines = 1;
Expand All @@ -287,7 +305,7 @@ void ThreadShowMetricsScreen()
lines += printNetworkStats();
}
lines += printMiningStatus(mining);
lines += printMetrics(cols, nStart, mining);
lines += printMetrics(cols, mining);
lines += printMessageBox(cols);
lines += printInitMessage();

Expand Down
3 changes: 3 additions & 0 deletions src/metrics.h
Expand Up @@ -31,6 +31,9 @@ extern AtomicCounter solutionTargetChecks;

void TrackMinedBlock(uint256 hash);

void MarkStartTime();
double GetLocalSolPS();

void ConnectMetricsScreen();
void ThreadShowMetricsScreen();

Expand Down
51 changes: 48 additions & 3 deletions src/rpcmining.cpp
Expand Up @@ -74,19 +74,60 @@ int64_t GetNetworkHashPS(int lookup, int height) {
return (int64_t)(workDiff.getdouble() / timeDiff);
}

Value getlocalsolps(const Array& params, bool fHelp)
{
if (fHelp)
throw runtime_error(
"getlocalsolps\n"
"\nReturns the average local solutions per second since this node was started.\n"
"This is the same information shown on the metrics screen (if enabled).\n"
"\nResult:\n"
"xxx.xxxxx (numeric) Solutions per second average\n"
"\nExamples:\n"
+ HelpExampleCli("getlocalsolps", "")
+ HelpExampleRpc("getlocalsolps", "")
);

LOCK(cs_main);
return GetLocalSolPS();
}

Value getnetworksolps(const Array& params, bool fHelp)
{
if (fHelp || params.size() > 2)
throw runtime_error(
"getnetworksolps ( blocks height )\n"
"\nReturns the estimated network solutions per second based on the last n blocks.\n"
"Pass in [blocks] to override # of blocks, -1 specifies over difficulty averaging window.\n"
"Pass in [height] to estimate the network speed at the time when a certain block was found.\n"
"\nArguments:\n"
"1. blocks (numeric, optional, default=120) The number of blocks, or -1 for blocks over difficulty averaging window.\n"
"2. height (numeric, optional, default=-1) To estimate at the time of the given height.\n"
"\nResult:\n"
"x (numeric) Solutions per second estimated\n"
"\nExamples:\n"
+ HelpExampleCli("getnetworksolps", "")
+ HelpExampleRpc("getnetworksolps", "")
);

LOCK(cs_main);
return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1);
}

Value getnetworkhashps(const Array& params, bool fHelp)
{
if (fHelp || params.size() > 2)
throw runtime_error(
"getnetworkhashps ( blocks height )\n"
"\nReturns the estimated network hashes per second based on the last n blocks.\n"
"\nDEPRECATED - left for backwards-compatibility. Use getnetworksolps instead.\n"
"\nReturns the estimated network solutions per second based on the last n blocks.\n"
"Pass in [blocks] to override # of blocks, -1 specifies over difficulty averaging window.\n"
"Pass in [height] to estimate the network speed at the time when a certain block was found.\n"
"\nArguments:\n"
"1. blocks (numeric, optional, default=120) The number of blocks, or -1 for blocks over difficulty averaging window.\n"
"2. height (numeric, optional, default=-1) To estimate at the time of the given height.\n"
"\nResult:\n"
"x (numeric) Hashes per second estimated\n"
"x (numeric) Solutions per second estimated\n"
"\nExamples:\n"
+ HelpExampleCli("getnetworkhashps", "")
+ HelpExampleRpc("getnetworkhashps", "")
Expand Down Expand Up @@ -275,6 +316,8 @@ Value getmininginfo(const Array& params, bool fHelp)
" \"errors\": \"...\" (string) Current errors\n"
" \"generate\": true|false (boolean) If the generation is on or off (see getgenerate or setgenerate calls)\n"
" \"genproclimit\": n (numeric) The processor limit for generation. -1 if no generation. (see getgenerate or setgenerate calls)\n"
" \"localsolps\": xxx.xxxxx (numeric) The average local solution rate in Sol/s since this node was started\n"
" \"networksolps\": x (numeric) The estimated network solution rate in Sol/s\n"
" \"pooledtx\": n (numeric) The size of the mem pool\n"
" \"testnet\": true|false (boolean) If using testnet or not\n"
" \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
Expand All @@ -294,7 +337,9 @@ Value getmininginfo(const Array& params, bool fHelp)
obj.push_back(Pair("difficulty", (double)GetNetworkDifficulty()));
obj.push_back(Pair("errors", GetWarnings("statusbar")));
obj.push_back(Pair("genproclimit", (int)GetArg("-genproclimit", -1)));
obj.push_back(Pair("networkhashps", getnetworkhashps(params, false)));
obj.push_back(Pair("localsolps" , getlocalsolps(params, false)));
obj.push_back(Pair("networksolps", getnetworksolps(params, false)));
obj.push_back(Pair("networkhashps", getnetworksolps(params, false)));
obj.push_back(Pair("pooledtx", (uint64_t)mempool.size()));
obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC()));
obj.push_back(Pair("chain", Params().NetworkIDString()));
Expand Down
2 changes: 2 additions & 0 deletions src/rpcserver.cpp
Expand Up @@ -304,6 +304,8 @@ static const CRPCCommand vRPCCommands[] =
/* Mining */
{ "mining", "getblocktemplate", &getblocktemplate, true },
{ "mining", "getmininginfo", &getmininginfo, true },
{ "mining", "getlocalsolps", &getlocalsolps, true },
{ "mining", "getnetworksolps", &getnetworksolps, true },
{ "mining", "getnetworkhashps", &getnetworkhashps, true },
{ "mining", "prioritisetransaction", &prioritisetransaction, true },
{ "mining", "submitblock", &submitblock, true },
Expand Down
2 changes: 2 additions & 0 deletions src/rpcserver.h
Expand Up @@ -169,6 +169,8 @@ extern json_spirit::Value importwallet(const json_spirit::Array& params, bool fH
extern json_spirit::Value getgenerate(const json_spirit::Array& params, bool fHelp); // in rpcmining.cpp
extern json_spirit::Value setgenerate(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value generate(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getlocalsolps(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getnetworksolps(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getnetworkhashps(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getmininginfo(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value prioritisetransaction(const json_spirit::Array& params, bool fHelp);
Expand Down