diff --git a/src/masternodes/mn_rpc.cpp b/src/masternodes/mn_rpc.cpp index 11250e7070..6af6130744 100644 --- a/src/masternodes/mn_rpc.cpp +++ b/src/masternodes/mn_rpc.cpp @@ -3040,11 +3040,15 @@ UniValue listaccounthistory(const JSONRPCRequest& request) { {"maxBlockHeight", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "Optional height to iterate from (downto genesis block), (default = chaintip)."}, {"depth", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, - "Maximum depth, 100 blocks by default for every account"}, + "Maximum depth, 100 blocks by default for every account, if limit is set it does nothing"}, {"no_rewards", RPCArg::Type::BOOL, RPCArg::Optional::OMITTED, "Filter out rewards"}, {"token", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "Filter by token"}, + {"txtype", RPCArg::Type::STR, RPCArg::Optional::OMITTED, + "Filter by transaction type, supported letter from 'CRTMNnpuslrUbBG'"}, + {"limit", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, + "Maximum number of records to return, 100 by default"}, }, }, }, @@ -3066,6 +3070,8 @@ UniValue listaccounthistory(const JSONRPCRequest& request) { uint32_t depth = 100; bool noRewards = false; std::string tokenFilter; + uint32_t limit = 100; + auto txType = CustomTxType::None; if (request.params.size() > 1) { UniValue optionsObj = request.params[1].get_obj(); @@ -3075,6 +3081,8 @@ UniValue listaccounthistory(const JSONRPCRequest& request) { {"depth", UniValueType(UniValue::VNUM)}, {"no_rewards", UniValueType(UniValue::VBOOL)}, {"token", UniValueType(UniValue::VSTR)}, + {"txtype", UniValueType(UniValue::VSTR)}, + {"limit", UniValueType(UniValue::VNUM)}, }, true, true); if (!optionsObj["maxBlockHeight"].isNull()) { @@ -3091,10 +3099,26 @@ UniValue listaccounthistory(const JSONRPCRequest& request) { if (!optionsObj["token"].isNull()) { tokenFilter = optionsObj["token"].get_str(); } + + if (!optionsObj["txtype"].isNull()) { + const auto str = optionsObj["txtype"].get_str(); + if (str.size() == 1) { + txType = CustomTxCodeToType(str[0]); + } + } + if (!optionsObj["limit"].isNull()) { + limit = (uint32_t) optionsObj["limit"].get_int64(); + depth = std::numeric_limits::max(); + } + if (limit == 0) { + limit = std::numeric_limits::max(); + } } pwallet->BlockUntilSyncedToCurrentChain(); startBlock = std::min(startBlock, uint32_t(chainHeight(*pwallet->chain().lock()))); + depth = std::min(depth, std::numeric_limits::max() - startBlock - 1); + depth += startBlock + 1; CScript owner; isminefilter filter = ISMINE_ALL_USED; @@ -3113,9 +3137,13 @@ UniValue listaccounthistory(const JSONRPCRequest& request) { filter = ISMINE_SPENDABLE; AccountHistoryKey startKey{ prevOwner, startBlock, std::numeric_limits::max() }; // starting from max txn values pcustomcsview->ForEachAccountHistory([&](CScript const & owner, uint32_t height, uint32_t txn, uint256 const & txid, unsigned char category, TAmounts const & diffs) { - if (height > startKey.blockHeight || (depth <= startKey.blockHeight && (height < startKey.blockHeight - depth))) + if (height > startKey.blockHeight || depth <= startKey.blockHeight) return true; // continue + if (CustomTxType::None != txType && category != uint8_t(txType)) { + return true; + } + if(!tokenFilter.empty()) { bool hasToken = false; for (auto const & diff : diffs) { @@ -3146,22 +3174,28 @@ UniValue listaccounthistory(const JSONRPCRequest& request) { if (isMine) { ret.push_back(accounthistoryToJSON(owner, height, txn, txid, category, diffs)); + --limit; + if (shouldSearchInWallet) { txs.insert(txid); } } - return true; + return limit != 0; }, startKey); } else if (accounts == "all") { // traversing the whole DB, skipping wrong heights AccountHistoryKey startKey{ CScript{}, startBlock, std::numeric_limits::max() }; // starting from max txn values pcustomcsview->ForEachAccountHistory([&](CScript const & owner, uint32_t height, uint32_t txn, uint256 const & txid, unsigned char category, TAmounts const & diffs) { - if (height > startKey.blockHeight || (depth <= startKey.blockHeight && (height < startKey.blockHeight - depth))) { + if (height > startKey.blockHeight || depth <= startKey.blockHeight) { return true; // continue } + if (CustomTxType::None != txType && category != uint8_t(txType)) { + return true; + } + if(!tokenFilter.empty()) { bool hasToken = false; for (auto const & diff : diffs) { @@ -3189,7 +3223,7 @@ UniValue listaccounthistory(const JSONRPCRequest& request) { if (shouldSearchInWallet) { txs.insert(txid); } - return true; + return --limit != 0; }, startKey); } @@ -3199,9 +3233,13 @@ UniValue listaccounthistory(const JSONRPCRequest& request) { AccountHistoryKey startKey{ owner, startBlock, std::numeric_limits::max() }; // starting from max txn values pcustomcsview->ForEachAccountHistory([&](CScript const & owner, uint32_t height, uint32_t txn, uint256 const & txid, unsigned char category, TAmounts const & diffs) { - if (owner != startKey.owner || (height > startKey.blockHeight || (depth <= startKey.blockHeight && (height < startKey.blockHeight - depth)))) + if (owner != startKey.owner || height > startKey.blockHeight || depth <= startKey.blockHeight) return false; + if (CustomTxType::None != txType && category != uint8_t(txType)) { + return true; + } + if(!tokenFilter.empty()) { bool hasToken = false; for (auto const & diff : diffs) { @@ -3229,7 +3267,7 @@ UniValue listaccounthistory(const JSONRPCRequest& request) { if (shouldSearchInWallet) { txs.insert(txid); } - return true; + return --limit != 0; }, startKey); }