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

Enable filter by tx type in listaccounthistory rpc method #120

Merged
merged 7 commits into from
Dec 10, 2020
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();
ShengguangXiao marked this conversation as resolved.
Show resolved Hide resolved
}
}

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