diff --git a/src/privatesend/privatesend-client.cpp b/src/privatesend/privatesend-client.cpp index d4258af5749f..7d9146707477 100644 --- a/src/privatesend/privatesend-client.cpp +++ b/src/privatesend/privatesend-client.cpp @@ -19,6 +19,7 @@ #include "wallet/coincontrol.h" #include +#include CPrivateSendClientManager privateSendClient; @@ -1669,3 +1670,54 @@ void CPrivateSendClientManager::DoMaintenance(CConnman& connman) nDoAutoNextRun = nTick + PRIVATESEND_AUTO_TIMEOUT_MIN + GetRandInt(PRIVATESEND_AUTO_TIMEOUT_MAX - PRIVATESEND_AUTO_TIMEOUT_MIN); } } + +void CPrivateSendClientSession::GetJsonInfo(UniValue& obj) const +{ + obj.clear(); + obj.setObject(); + if (mixingMasternode != nullptr) { + assert(mixingMasternode->pdmnState); + obj.push_back(Pair("protxhash", mixingMasternode->proTxHash.ToString())); + obj.push_back(Pair("outpoint", mixingMasternode->collateralOutpoint.ToStringShort())); + obj.push_back(Pair("service", mixingMasternode->pdmnState->addr.ToString())); + } + CAmount amount{0}; + if (nSessionDenom) { + // TODO: GetDenominationsToString has few issues: + // - it returns a string of denomination amounts concatenated via "+" if there are many of them + // - it uses FormatMoney which drops trailing zeros + // We no longer use multiple denominations in one session and this thing should be refactored + // together with other similar functions in CPrivatesend. + // For now, we just use a workaround here to convert a string into CAmount and convert it to a + // proper format via ValueFromAmount later. + ParseFixedPoint(CPrivateSend::GetDenominationsToString(nSessionDenom), 8, &amount); + } + obj.push_back(Pair("denomination", ValueFromAmount(amount))); + obj.push_back(Pair("state", GetStateString())); + obj.push_back(Pair("entries_count", GetEntriesCount())); +} + +void CPrivateSendClientManager::GetJsonInfo(UniValue& obj) const +{ + LOCK(cs_deqsessions); + obj.clear(); + obj.setObject(); + obj.push_back(Pair("enabled", fEnablePrivateSend)); + obj.push_back(Pair("running", fPrivateSendRunning)); + obj.push_back(Pair("multisession", fPrivateSendMultiSession)); + obj.push_back(Pair("max_sessions", nPrivateSendSessions)); + obj.push_back(Pair("max_rounds", nPrivateSendRounds)); + obj.push_back(Pair("max_amount", nPrivateSendAmount)); + obj.push_back(Pair("max_denoms", nPrivateSendDenoms)); + obj.push_back(Pair("queue_size", GetQueueSize())); + + UniValue arrSessions(UniValue::VARR); + for (const auto& session : deqSessions) { + if (session.GetState() != POOL_STATE_IDLE) { + UniValue objSession(UniValue::VOBJ); + session.GetJsonInfo(objSession); + arrSessions.push_back(objSession); + } + } + obj.push_back(Pair("sessions", arrSessions)); +} diff --git a/src/privatesend/privatesend-client.h b/src/privatesend/privatesend-client.h index b14032aef377..2bcd1c6d1571 100644 --- a/src/privatesend/privatesend-client.h +++ b/src/privatesend/privatesend-client.h @@ -14,7 +14,7 @@ class CPrivateSendClientManager; class CConnman; class CNode; - +class UniValue; static const int MIN_PRIVATESEND_SESSIONS = 1; static const int MIN_PRIVATESEND_ROUNDS = 2; @@ -162,6 +162,8 @@ class CPrivateSendClientSession : public CPrivateSendBaseSession bool ProcessPendingDsaRequest(CConnman& connman); bool CheckTimeout(); + + void GetJsonInfo(UniValue& obj) const; }; /** Used to keep track of current status of mixing pool @@ -249,6 +251,8 @@ class CPrivateSendClientManager : public CPrivateSendBaseManager void UpdatedBlockTip(const CBlockIndex* pindex); void DoMaintenance(CConnman& connman); + + void GetJsonInfo(UniValue& obj) const; }; #endif diff --git a/src/privatesend/privatesend-server.cpp b/src/privatesend/privatesend-server.cpp index e536bb29053e..f31720bcb10b 100644 --- a/src/privatesend/privatesend-server.cpp +++ b/src/privatesend/privatesend-server.cpp @@ -20,6 +20,8 @@ #include "llmq/quorums_instantsend.h" +#include + CPrivateSendServer privateSendServer; void CPrivateSendServer::ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman) @@ -938,3 +940,17 @@ void CPrivateSendServer::DoMaintenance(CConnman& connman) privateSendServer.CheckTimeout(connman); privateSendServer.CheckForCompleteQueue(connman); } + +void CPrivateSendServer::GetJsonInfo(UniValue& obj) const +{ + obj.clear(); + obj.setObject(); + obj.push_back(Pair("queue_size", GetQueueSize())); + CAmount amount{0}; + if (nSessionDenom) { + ParseFixedPoint(CPrivateSend::GetDenominationsToString(nSessionDenom), 8, &amount); + } + obj.push_back(Pair("denomination", ValueFromAmount(amount))); + obj.push_back(Pair("state", GetStateString())); + obj.push_back(Pair("entries_count", GetEntriesCount())); +} diff --git a/src/privatesend/privatesend-server.h b/src/privatesend/privatesend-server.h index 4d9e02e90b9d..fbaceb092e74 100644 --- a/src/privatesend/privatesend-server.h +++ b/src/privatesend/privatesend-server.h @@ -9,6 +9,7 @@ #include "privatesend.h" class CPrivateSendServer; +class UniValue; // The main object for accessing mixing extern CPrivateSendServer privateSendServer; @@ -82,6 +83,8 @@ class CPrivateSendServer : public CPrivateSendBaseSession, public CPrivateSendBa void CheckForCompleteQueue(CConnman& connman); void DoMaintenance(CConnman& connman); + + void GetJsonInfo(UniValue& obj) const; }; #endif diff --git a/src/rpc/masternode.cpp b/src/rpc/masternode.cpp index 48e9a38df19e..0864145e990c 100644 --- a/src/rpc/masternode.cpp +++ b/src/rpc/masternode.cpp @@ -93,44 +93,75 @@ UniValue privatesend(const JSONRPCRequest& request) UniValue getpoolinfo(const JSONRPCRequest& request) { - if (request.fHelp || request.params.size() != 0) - throw std::runtime_error( - "getpoolinfo\n" - "Returns an object containing mixing pool related information.\n"); + throw std::runtime_error( + "getpoolinfo\n" + "DEPRECATED. Please use getprivatesendinfo instead.\n" + ); +} -#ifdef ENABLE_WALLET - CPrivateSendBaseManager* pprivateSendBaseManager = fMasternodeMode ? (CPrivateSendBaseManager*)&privateSendServer : (CPrivateSendBaseManager*)&privateSendClient; +UniValue getprivatesendinfo(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 0) { + throw std::runtime_error( + "getprivatesendinfo\n" + "Returns an object containing an information about PrivateSend settings and state.\n" + "\nResult (for regular nodes):\n" + "{\n" + " \"enabled\": true|false, (bool) Whether mixing functionality is enabled\n" + " \"running\": true|false, (bool) Whether mixing is currently running\n" + " \"multisession\": true|false, (bool) Whether PrivateSend Multisession option is enabled\n" + " \"max_sessions\": xxx, (numeric) How many parallel mixing sessions can there be at once\n" + " \"max_rounds\": xxx, (numeric) How many rounds to mix\n" + " \"max_amount\": xxx, (numeric) How many " + CURRENCY_UNIT + " to keep anonimized\n" + " \"max_denoms\": xxx, (numeric) How many inputs of each denominated amount to create\n" + " \"queue_size\": xxx, (numeric) How many queues there are currently on the network\n" + " \"sessions\": (array of json objects)\n" + " [\n" + " {\n" + " \"protxhash\": \"...\", (string) The ProTxHash of the masternode\n" + " \"outpoint\": \"txid-index\", (string) The outpoint of the masternode\n" + " \"service\": \"host:port\", (string) The IP address and port of the masternode\n" + " \"denomination\": xxx, (numeric) The denomination of the mixing session in " + CURRENCY_UNIT + "\n" + " \"state\": \"...\", (string) Current state of the mixing session\n" + " \"entries_count\": xxx, (numeric) The number of entries in the mixing session\n" + " }\n" + " ,...\n" + " ],\n" + " \"keys_left\": xxx, (numeric) How many new keys are left since last automatic backup\n" + " \"warnings\": \"...\" (string) Warnings if any\n" + "}\n" + "\nResult (for masternodes):\n" + "{\n" + " \"queue_size\": xxx, (numeric) How many queues there are currently on the network\n" + " \"denomination\": xxx, (numeric) The denomination of the mixing session in " + CURRENCY_UNIT + "\n" + " \"state\": \"...\", (string) Current state of the mixing session\n" + " \"entries_count\": xxx, (numeric) The number of entries in the mixing session\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("getprivatesendinfo", "") + + HelpExampleRpc("getprivatesendinfo", "") + ); + } UniValue obj(UniValue::VOBJ); - // TODO: - // obj.push_back(Pair("state", pprivateSendBase->GetStateString())); - obj.push_back(Pair("queue", pprivateSendBaseManager->GetQueueSize())); - // obj.push_back(Pair("entries", pprivateSendBase->GetEntriesCount())); - obj.push_back(Pair("status", privateSendClient.GetStatuses())); - - std::vector vecDmns; - if (privateSendClient.GetMixingMasternodesInfo(vecDmns)) { - UniValue pools(UniValue::VARR); - for (const auto& dmn : vecDmns) { - UniValue pool(UniValue::VOBJ); - pool.push_back(Pair("outpoint", dmn->collateralOutpoint.ToStringShort())); - pool.push_back(Pair("addr", dmn->pdmnState->addr.ToString())); - pools.push_back(pool); - } - obj.push_back(Pair("pools", pools)); + + if (fMasternodeMode) { + privateSendServer.GetJsonInfo(obj); + return obj; } + +#ifdef ENABLE_WALLET + privateSendClient.GetJsonInfo(obj); + CWallet* const pwallet = GetWalletForJSONRPCRequest(request); - if (pwallet) { - obj.push_back(Pair("keys_left", pwallet->nKeysLeftSinceAutoBackup)); - obj.push_back(Pair("warnings", pwallet->nKeysLeftSinceAutoBackup < PRIVATESEND_KEYS_THRESHOLD_WARNING - ? "WARNING: keypool is almost depleted!" : "")); + if (!pwallet) { + return obj; } -#else // ENABLE_WALLET - UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("state", privateSendServer.GetStateString())); - obj.push_back(Pair("queue", privateSendServer.GetQueueSize())); - obj.push_back(Pair("entries", privateSendServer.GetEntriesCount())); + + obj.push_back(Pair("keys_left", pwallet->nKeysLeftSinceAutoBackup)); + obj.push_back(Pair("warnings", pwallet->nKeysLeftSinceAutoBackup < PRIVATESEND_KEYS_THRESHOLD_WARNING + ? "WARNING: keypool is almost depleted!" : "")); #endif // ENABLE_WALLET return obj; @@ -635,6 +666,7 @@ static const CRPCCommand commands[] = { "dash", "masternode", &masternode, true, {} }, { "dash", "masternodelist", &masternodelist, true, {} }, { "dash", "getpoolinfo", &getpoolinfo, true, {} }, + { "dash", "getprivatesendinfo", &getprivatesendinfo, true, {} }, #ifdef ENABLE_WALLET { "dash", "privatesend", &privatesend, false, {} }, #endif // ENABLE_WALLET