From f06db823351820dc8b887eaa49d6170c9715e317 Mon Sep 17 00:00:00 2001 From: Andrey Date: Mon, 19 Apr 2021 16:20:27 +0400 Subject: [PATCH 1/3] Reimplementing ListTransactions with a global flag --- src/evo/deterministicmns.cpp | 2 +- src/evo/deterministicmns.h | 2 +- src/masternode-payments.cpp | 8 ++++++++ src/masternode-payments.h | 1 + src/rpc/client.cpp | 1 - src/wallet/rpcwallet.cpp | 36 +++++++++++++++--------------------- 6 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/evo/deterministicmns.cpp b/src/evo/deterministicmns.cpp index 1f5111681c..7ac85243ea 100644 --- a/src/evo/deterministicmns.cpp +++ b/src/evo/deterministicmns.cpp @@ -993,7 +993,7 @@ bool CDeterministicMNManager::IsDIP3Enforced(int nHeight) void CDeterministicMNManager::CleanupCache(int nHeight) { - AssertLockHeld(cs); + LOCK(cs); std::vector toDelete; for (const auto& p : mnListsCache) { diff --git a/src/evo/deterministicmns.h b/src/evo/deterministicmns.h index 767169e063..e84ac47f39 100644 --- a/src/evo/deterministicmns.h +++ b/src/evo/deterministicmns.h @@ -664,7 +664,7 @@ class CDeterministicMNManager void UpgradeDBIfNeeded(); static bool IsDIP3Active(int height); -private: +public: void CleanupCache(int nHeight); }; diff --git a/src/masternode-payments.cpp b/src/masternode-payments.cpp index c53673f57d..fb1a3ab2b9 100644 --- a/src/masternode-payments.cpp +++ b/src/masternode-payments.cpp @@ -247,6 +247,14 @@ bool CMasternodePayments::GetBlockTxOuts(int nBlockHeight, CAmount blockReward, return true; } +bool CMasternodePayments::GetBlockTxOutsWipeCache(int nBlockHeight, CAmount blockReward, std::vector& voutMasternodePaymentsRet) const +{ + bool result = GetBlockTxOuts(nBlockHeight, blockReward, voutMasternodePaymentsRet); + AssertLockHeld(cs_main); + deterministicMNManager->CleanupCache(chainActive.Height()); + return result; +} + // Is this masternode scheduled to get paid soon? // -- Only look ahead up to 8 blocks to allow for propagation of the latest 2 blocks of votes bool CMasternodePayments::IsScheduled(const CDeterministicMNCPtr& dmnIn, int nNotBlockHeight) const diff --git a/src/masternode-payments.h b/src/masternode-payments.h index db6a7fd010..1c4249a603 100644 --- a/src/masternode-payments.h +++ b/src/masternode-payments.h @@ -32,6 +32,7 @@ class CMasternodePayments { public: bool GetBlockTxOuts(int nBlockHeight, CAmount blockReward, std::vector& voutMasternodePaymentsRet) const; + bool GetBlockTxOutsWipeCache(int nBlockHeight, CAmount blockReward, std::vector& voutMasternodePaymentsRet) const; bool IsTransactionValid(const CTransaction& txNew, int nBlockHeight, CAmount blockReward) const; bool IsScheduled(const CDeterministicMNCPtr& dmn, int nNotBlockHeight) const; diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 219a0bc202..e4b1526809 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -68,7 +68,6 @@ static const CRPCConvertParam vRPCConvertParams[] = { "listtransactions", 1, "count" }, { "listtransactions", 2, "skip" }, { "listtransactions", 3, "include_watchonly" }, - { "listtransactions", 4, "skip_mnout_check" }, { "listaccounts", 0, "minconf" }, { "listaccounts", 1, "include_watchonly" }, { "walletpassphrase", 1, "timeout" }, diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index be0ecfb054..3465a1b7e5 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1485,7 +1485,7 @@ static void MaybePushAddress(UniValue & entry, const CTxDestination &dest, CBitc entry.push_back(Pair("address", addr.ToString())); } -void ListTransactions(CWallet * const pwallet, const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter, bool omitNmPayments) +void ListTransactions(CWallet * const pwallet, const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter) { CAmount nFee; string strSentAccount; @@ -1552,20 +1552,18 @@ void ListTransactions(CWallet * const pwallet, const CWalletTx& wtx, const strin { int txHeight = chainActive.Height() - wtx.GetDepthInMainChain(); + std::vector voutMasternodePaymentsRet; + mnpayments.GetBlockTxOutsWipeCache(txHeight, CAmount(), voutMasternodePaymentsRet); + //compare address of payee to addr. + bool its_znode_payment = false; + for(CTxOut const & out : voutMasternodePaymentsRet) { + CTxDestination payeeDest; + ExtractDestination(out.scriptPubKey, payeeDest); + CBitcoinAddress payeeAddr(payeeDest); - if (!omitNmPayments) { - std::vector voutMasternodePaymentsRet; - mnpayments.GetBlockTxOuts(txHeight, CAmount(), voutMasternodePaymentsRet); - //compare address of payee to addr. - for(CTxOut const & out : voutMasternodePaymentsRet) { - CTxDestination payeeDest; - ExtractDestination(out.scriptPubKey, payeeDest); - CBitcoinAddress payeeAddr(payeeDest); - - if(addr.ToString() == payeeAddr.ToString()) { - its_znode_payment = true; - } + if(addr.ToString() == payeeAddr.ToString()) { + its_znode_payment = true; } } if(its_znode_payment){ @@ -1618,7 +1616,7 @@ UniValue listtransactions(const JSONRPCRequest& request) return NullUniValue; } - if (request.fHelp || request.params.size() > 5) + if (request.fHelp || request.params.size() > 4) throw runtime_error( "listtransactions ( \"account\" count skip include_watchonly)\n" "\nReturns up to 'count' most recent transactions skipping the first 'from' transactions for account 'account'.\n" @@ -1627,7 +1625,6 @@ UniValue listtransactions(const JSONRPCRequest& request) "2. count (numeric, optional, default=10) The number of transactions to return\n" "3. skip (numeric, optional, default=0) The number of transactions to skip\n" "4. include_watchonly (bool, optional, default=false) Include transactions to watch-only addresses (see 'importaddress')\n" - "5. skip_mnout_check (bool, optional, default=false) Skip checking for masternode payment txout (improves performance)\n" "\nResult:\n" "[\n" " {\n" @@ -1694,9 +1691,6 @@ UniValue listtransactions(const JSONRPCRequest& request) if(request.params.size() > 3) if(request.params[3].get_bool()) filter = filter | ISMINE_WATCH_ONLY; - bool omitNmPayments = false; - if(request.params.size() > 4) - omitNmPayments = request.params[4].get_bool(); if (nCount < 0) throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative count"); @@ -1712,7 +1706,7 @@ UniValue listtransactions(const JSONRPCRequest& request) { CWalletTx *const pwtx = (*it).second.first; if (pwtx != 0) - ListTransactions(pwallet, *pwtx, strAccount, 0, true, ret, filter, omitNmPayments); + ListTransactions(pwallet, *pwtx, strAccount, 0, true, ret, filter); CAccountingEntry *const pacentry = (*it).second.second; if (pacentry != 0) AcentryToJSON(*pacentry, strAccount, ret); @@ -1921,7 +1915,7 @@ UniValue listsinceblock(const JSONRPCRequest& request) CWalletTx tx = pairWtx.second; if (depth == -1 || tx.GetDepthInMainChain() < depth) - ListTransactions(pwallet, tx, "*", 0, true, transactions, filter, false); + ListTransactions(pwallet, tx, "*", 0, true, transactions, filter); } CBlockIndex *pblockLast = chainActive[chainActive.Height() + 1 - target_confirms]; @@ -2017,7 +2011,7 @@ UniValue gettransaction(const JSONRPCRequest& request) WalletTxToJSON(wtx, entry); UniValue details(UniValue::VARR); - ListTransactions(pwallet, wtx, "*", 0, false, details, filter, false); + ListTransactions(pwallet, wtx, "*", 0, false, details, filter); entry.push_back(Pair("details", details)); string strHex = EncodeHexTx(static_cast(wtx), RPCSerializationFlags()); From d76b2c5555fc4624f2c45fbfff8f8d7773404e82 Mon Sep 17 00:00:00 2001 From: Andrey Date: Mon, 19 Apr 2021 18:54:31 +0400 Subject: [PATCH 2/3] Fixing ListTransaction perf with a global flag --- src/init.cpp | 3 +++ src/util.cpp | 1 + src/util.h | 1 + src/wallet/rpcwallet.cpp | 23 ++++++++++++----------- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index cadccbd95f..1873db4497 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -614,6 +614,8 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-elysiumshowblockconsensushash=", "Calculate and log the consensus hash for the specified block"); #endif + strUsage += HelpMessageOpt("-skipmnpayoutcheck", _("Do not check for masternode payout when handling listtransactions, listsinceblock and gettransaction calls (improves performance)")); + return strUsage; } @@ -1403,6 +1405,7 @@ bool AppInitParameterInteraction() } } } + fSkipMnpayoutCheck = GetBoolArg("-skipmnpayoutcheck", false); return true; } diff --git a/src/util.cpp b/src/util.cpp index bb4b630b81..5f57ffa6cc 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -126,6 +126,7 @@ bool fLogTimestamps = DEFAULT_LOGTIMESTAMPS; bool fLogTimeMicros = DEFAULT_LOGTIMEMICROS; bool fLogIPs = DEFAULT_LOGIPS; +bool fSkipMnpayoutCheck = false; std::atomic fReopenDebugLog(false); CTranslationInterface translationInterface; diff --git a/src/util.h b/src/util.h index 507d0cd779..400c7980b6 100644 --- a/src/util.h +++ b/src/util.h @@ -69,6 +69,7 @@ extern std::atomic fReopenElysiumLog; extern const char * const BITCOIN_CONF_FILENAME; extern const char * const BITCOIN_PID_FILENAME; +extern bool fSkipMnpayoutCheck; /** * Translation function: Call Translate signal on UI interface, which returns a boost::optional result. diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 3465a1b7e5..14504f4b8f 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1552,18 +1552,19 @@ void ListTransactions(CWallet * const pwallet, const CWalletTx& wtx, const strin { int txHeight = chainActive.Height() - wtx.GetDepthInMainChain(); - std::vector voutMasternodePaymentsRet; - mnpayments.GetBlockTxOutsWipeCache(txHeight, CAmount(), voutMasternodePaymentsRet); - //compare address of payee to addr. - bool its_znode_payment = false; - for(CTxOut const & out : voutMasternodePaymentsRet) { - CTxDestination payeeDest; - ExtractDestination(out.scriptPubKey, payeeDest); - CBitcoinAddress payeeAddr(payeeDest); - - if(addr.ToString() == payeeAddr.ToString()) { - its_znode_payment = true; + if (!fSkipMnpayoutCheck) { + std::vector voutMasternodePaymentsRet; + mnpayments.GetBlockTxOutsWipeCache(txHeight, CAmount(), voutMasternodePaymentsRet); + //compare address of payee to addr. + for(CTxOut const & out : voutMasternodePaymentsRet) { + CTxDestination payeeDest; + ExtractDestination(out.scriptPubKey, payeeDest); + CBitcoinAddress payeeAddr(payeeDest); + + if(addr.ToString() == payeeAddr.ToString()) { + its_znode_payment = true; + } } } if(its_znode_payment){ From f651249bfd9e41cc38f9b10448a43b008e22ab5f Mon Sep 17 00:00:00 2001 From: Andrey Date: Tue, 20 Apr 2021 00:07:38 +0400 Subject: [PATCH 3/3] Improving the listtransactions performance --- src/evo/deterministicmns.cpp | 2 +- src/evo/deterministicmns.h | 2 +- src/masternode-payments.cpp | 8 -------- src/masternode-payments.h | 1 - src/wallet/rpcwallet.cpp | 2 +- 5 files changed, 3 insertions(+), 12 deletions(-) diff --git a/src/evo/deterministicmns.cpp b/src/evo/deterministicmns.cpp index 7ac85243ea..1f5111681c 100644 --- a/src/evo/deterministicmns.cpp +++ b/src/evo/deterministicmns.cpp @@ -993,7 +993,7 @@ bool CDeterministicMNManager::IsDIP3Enforced(int nHeight) void CDeterministicMNManager::CleanupCache(int nHeight) { - LOCK(cs); + AssertLockHeld(cs); std::vector toDelete; for (const auto& p : mnListsCache) { diff --git a/src/evo/deterministicmns.h b/src/evo/deterministicmns.h index e84ac47f39..767169e063 100644 --- a/src/evo/deterministicmns.h +++ b/src/evo/deterministicmns.h @@ -664,7 +664,7 @@ class CDeterministicMNManager void UpgradeDBIfNeeded(); static bool IsDIP3Active(int height); -public: +private: void CleanupCache(int nHeight); }; diff --git a/src/masternode-payments.cpp b/src/masternode-payments.cpp index fb1a3ab2b9..c53673f57d 100644 --- a/src/masternode-payments.cpp +++ b/src/masternode-payments.cpp @@ -247,14 +247,6 @@ bool CMasternodePayments::GetBlockTxOuts(int nBlockHeight, CAmount blockReward, return true; } -bool CMasternodePayments::GetBlockTxOutsWipeCache(int nBlockHeight, CAmount blockReward, std::vector& voutMasternodePaymentsRet) const -{ - bool result = GetBlockTxOuts(nBlockHeight, blockReward, voutMasternodePaymentsRet); - AssertLockHeld(cs_main); - deterministicMNManager->CleanupCache(chainActive.Height()); - return result; -} - // Is this masternode scheduled to get paid soon? // -- Only look ahead up to 8 blocks to allow for propagation of the latest 2 blocks of votes bool CMasternodePayments::IsScheduled(const CDeterministicMNCPtr& dmnIn, int nNotBlockHeight) const diff --git a/src/masternode-payments.h b/src/masternode-payments.h index 1c4249a603..db6a7fd010 100644 --- a/src/masternode-payments.h +++ b/src/masternode-payments.h @@ -32,7 +32,6 @@ class CMasternodePayments { public: bool GetBlockTxOuts(int nBlockHeight, CAmount blockReward, std::vector& voutMasternodePaymentsRet) const; - bool GetBlockTxOutsWipeCache(int nBlockHeight, CAmount blockReward, std::vector& voutMasternodePaymentsRet) const; bool IsTransactionValid(const CTransaction& txNew, int nBlockHeight, CAmount blockReward) const; bool IsScheduled(const CDeterministicMNCPtr& dmn, int nNotBlockHeight) const; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 14504f4b8f..1b0e956d04 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1555,7 +1555,7 @@ void ListTransactions(CWallet * const pwallet, const CWalletTx& wtx, const strin bool its_znode_payment = false; if (!fSkipMnpayoutCheck) { std::vector voutMasternodePaymentsRet; - mnpayments.GetBlockTxOutsWipeCache(txHeight, CAmount(), voutMasternodePaymentsRet); + mnpayments.GetBlockTxOuts(txHeight, CAmount(), voutMasternodePaymentsRet); //compare address of payee to addr. for(CTxOut const & out : voutMasternodePaymentsRet) { CTxDestination payeeDest;