Skip to content

Commit

Permalink
Add txn-no as a pagination token into listaccounthistory rpc (#1110)
Browse files Browse the repository at this point in the history
* Add txn-no as a pegination into listaccounthistory rpc

* Added a review comment suggesion

* txn is used as a pagination key to search in account history DB

* block height and txn are used as keys to search in wallet

* txn is used as pagination key to search in wallet

* Updated txn logic and tests.

* CWalletTx.nIndex is used as txn instead of entry.vout

* Update test/functional/rpc_listaccounthistory.py

Co-authored-by: surangap <surangatco@gmail.com>
Co-authored-by: Anthony Fieroni <bvbfan@abv.bg>
Co-authored-by: Prasanna Loganathar <pvl@prasannavl.com>
  • Loading branch information
4 people authored Mar 18, 2022
1 parent 2419f51 commit 2471a96
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 2 deletions.
15 changes: 13 additions & 2 deletions src/masternodes/rpc_accounts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ UniValue outputEntryToJSON(COutputEntry const & entry, CBlockIndex const * index
} else {
obj.pushKV("type", "receive");
}
obj.pushKV("txn", (uint64_t) entry.vout);
obj.pushKV("txn", (uint64_t) pwtx->nIndex);
obj.pushKV("txid", pwtx->GetHash().ToString());
TAmounts amounts({{DCT_ID{0},entry.amount}});
obj.pushKV("amounts", AmountsToJSON(amounts));
Expand Down Expand Up @@ -964,6 +964,8 @@ UniValue listaccounthistory(const JSONRPCRequest& request) {
"Filter by transaction type, supported letter from {CustomTxType}"},
{"limit", RPCArg::Type::NUM, RPCArg::Optional::OMITTED,
"Maximum number of records to return, 100 by default"},
{"txn", RPCArg::Type::NUM, RPCArg::Optional::OMITTED,
"Order in block, unlimited by default"},
},
},
},
Expand Down Expand Up @@ -991,6 +993,7 @@ UniValue listaccounthistory(const JSONRPCRequest& request) {
std::string tokenFilter;
uint32_t limit = 100;
auto txType = CustomTxType::None;
uint32_t txn = std::numeric_limits<uint32_t>::max();

if (request.params.size() > 1) {
UniValue optionsObj = request.params[1].get_obj();
Expand All @@ -1002,6 +1005,7 @@ UniValue listaccounthistory(const JSONRPCRequest& request) {
{"token", UniValueType(UniValue::VSTR)},
{"txtype", UniValueType(UniValue::VSTR)},
{"limit", UniValueType(UniValue::VNUM)},
{"txn", UniValueType(UniValue::VNUM)},
}, true, true);

if (!optionsObj["maxBlockHeight"].isNull()) {
Expand Down Expand Up @@ -1031,6 +1035,10 @@ UniValue listaccounthistory(const JSONRPCRequest& request) {
if (limit == 0) {
limit = std::numeric_limits<decltype(limit)>::max();
}

if (!optionsObj["txn"].isNull()) {
txn = (uint32_t) optionsObj["txn"].get_int64();
}
}

pwallet->BlockUntilSyncedToCurrentChain();
Expand Down Expand Up @@ -1159,7 +1167,7 @@ UniValue listaccounthistory(const JSONRPCRequest& request) {
return count != 0 || isMine;
};

AccountHistoryKey startKey{account, maxBlockHeight, std::numeric_limits<uint32_t>::max()};
AccountHistoryKey startKey{account, maxBlockHeight, txn};

if (!noRewards && !account.empty()) {
// revert previous tx to restore account balances to maxBlockHeight
Expand All @@ -1184,6 +1192,9 @@ UniValue listaccounthistory(const JSONRPCRequest& request) {
return txs.count(pwtx->GetHash()) || startBlock > index->nHeight || index->nHeight > maxBlockHeight;
},
[&](COutputEntry const & entry, CBlockIndex const * index, CWalletTx const * pwtx) {
if (txn != std::numeric_limits<uint32_t>::max() && index->nHeight == maxBlockHeight && pwtx->nIndex > txn ) {
return true;
}
auto& array = ret.emplace(index->nHeight, UniValue::VARR).first->second;
array.push_back(outputEntryToJSON(entry, index, pwtx));
return --count != 0;
Expand Down
22 changes: 22 additions & 0 deletions test/functional/rpc_listaccounthistory.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ def run_test(self):
found = False
for txs in results:
assert_equal(txs['owner'], collateral_a)
self.log.info("test 0: block %d, txn is %d", txs['blockHeight'], txs['txn'])
if txs['type'] == 'MintToken':
found = True
assert_equal(found, True)
Expand All @@ -72,6 +73,27 @@ def run_test(self):
for txs in results:
assert(hasattr(txs['amounts'], '__len__') and (not isinstance(txs['amounts'], str)))

# list {"maxBlockHeight":103, "txn":1}, should list without blockheight = 103, txn=2. i.e without MintToken
results = self.nodes[0].listaccounthistory(collateral_a, {"maxBlockHeight":103, "txn":1})
for txs in results:
self.log.info("test 1: block %d, txn is %d", txs['blockHeight'], txs['txn'])
assert_equal(txs['owner'], collateral_a)
assert_equal(txs['blockHeight'] <= 103, True)
if txs['blockHeight'] == 103:
assert_equal(txs['txn'] <= 1 , True) # for block 103 txn:1 applies.

# list {"maxBlockHeight":103, "txn":0}, should list without blockheight = 103, txn=1,2. i.e without any txs from 103 block
results = self.nodes[0].listaccounthistory(collateral_a, {"maxBlockHeight":103, "txn":0})

for txs in results:
self.log.info("test 2: block %d, txn is %d", txs['blockHeight'], txs['txn'])
assert_equal(txs['owner'], collateral_a)
assert_equal(txs['blockHeight'] <= 103, True)
if txs['blockHeight'] == 103:
assert_equal(txs['txn'] <= 0 , True)
else:
assert_equal(txs['txn'] >= 0 , True) # means txn:0 only applicable to block 103 only

# Get node 1 results
results = self.nodes[1].listaccounthistory(collateral_a)

Expand Down

0 comments on commit 2471a96

Please sign in to comment.