Skip to content

Commit

Permalink
Merge pull request #120 from bvbfan/feature/listaccounthistory_by_txtype
Browse files Browse the repository at this point in the history
Enable filter by tx type in listaccounthistory rpc method
  • Loading branch information
monstrobishi authored Dec 10, 2020
2 parents f529e8d + aabaf10 commit 22b30a5
Showing 1 changed file with 45 additions and 7 deletions.
52 changes: 45 additions & 7 deletions src/masternodes/mn_rpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"},
},
},
},
Expand All @@ -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();
Expand All @@ -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()) {
Expand All @@ -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<decltype(depth)>::max();
}
if (limit == 0) {
limit = std::numeric_limits<decltype(limit)>::max();
}
}

pwallet->BlockUntilSyncedToCurrentChain();
startBlock = std::min(startBlock, uint32_t(chainHeight(*pwallet->chain().lock())));
depth = std::min(depth, std::numeric_limits<decltype(depth)>::max() - startBlock - 1);
depth += startBlock + 1;

CScript owner;
isminefilter filter = ISMINE_ALL_USED;
Expand All @@ -3113,9 +3137,13 @@ UniValue listaccounthistory(const JSONRPCRequest& request) {
filter = ISMINE_SPENDABLE;
AccountHistoryKey startKey{ prevOwner, startBlock, std::numeric_limits<uint32_t>::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) {
Expand Down Expand Up @@ -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<uint32_t>::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) {
Expand Down Expand Up @@ -3189,7 +3223,7 @@ UniValue listaccounthistory(const JSONRPCRequest& request) {
if (shouldSearchInWallet) {
txs.insert(txid);
}
return true;
return --limit != 0;
}, startKey);

}
Expand All @@ -3199,9 +3233,13 @@ UniValue listaccounthistory(const JSONRPCRequest& request) {

AccountHistoryKey startKey{ owner, startBlock, std::numeric_limits<uint32_t>::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) {
Expand Down Expand Up @@ -3229,7 +3267,7 @@ UniValue listaccounthistory(const JSONRPCRequest& request) {
if (shouldSearchInWallet) {
txs.insert(txid);
}
return true;
return --limit != 0;
}, startKey);
}

Expand Down

0 comments on commit 22b30a5

Please sign in to comment.