Skip to content

Commit 4d65c0c

Browse files
authored
Merge pull request #217 from AkioNak/fix-rpc-listreceivedbyaddress
fix listreceivedbyaddress to sum amounts for each asset.
2 parents d6a9a01 + 7485b36 commit 4d65c0c

File tree

3 files changed

+46
-31
lines changed

3 files changed

+46
-31
lines changed

qa/rpc-tests/confidential_transactions.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ def run_test(self):
107107
assert_equal(self.nodes[2].getbalance()["bitcoin"], node2)
108108

109109
# Check 2's listreceivedbyaddress
110-
received_by_address = self.nodes[2].listreceivedbyaddress()
110+
received_by_address = self.nodes[2].listreceivedbyaddress(0, False, False, "bitcoin")
111111
validate_by_address = [(unconfidential_address2, value1 + value3), (unconfidential_address, value0 + value2)]
112112
assert_equal(sorted([(ele['address'], ele['amount']) for ele in received_by_address], key=lambda t: t[0]),
113113
sorted(validate_by_address, key = lambda t: t[0]))
@@ -131,7 +131,7 @@ def run_test(self):
131131
assert_equal(list_unspent[0]['amount']+list_unspent[1]['amount'], value1+value3)
132132
received_by_address = self.nodes[1].listreceivedbyaddress(1, False, True)
133133
assert_equal(len(received_by_address), 1)
134-
assert_equal((received_by_address[0]['address'], received_by_address[0]['amount']),
134+
assert_equal((received_by_address[0]['address'], received_by_address[0]['amount']['bitcoin']),
135135
(unconfidential_address2, value1 + value3))
136136

137137
# Spending a single confidential output and sending it to a
@@ -368,6 +368,16 @@ def run_test(self):
368368
assert_equal(self.nodes[0].getwalletinfo()["balance"][issued["token"]], 1)
369369

370370

371+
# Check for value when receiving defferent assets by same address.
372+
self.nodes[0].sendtoaddress(unconfidential_address2, Decimal('0.00000001'), "", "", False, test_asset)
373+
self.nodes[0].sendtoaddress(unconfidential_address2, Decimal('0.00000002'), "", "", False, test_asset)
374+
self.nodes[0].generate(1)
375+
self.sync_all()
376+
received_by_address = self.nodes[1].listreceivedbyaddress(0, False, True)
377+
multi_asset_amount = [x for x in received_by_address if x['address'] == unconfidential_address2][0]['amount']
378+
assert_equal(multi_asset_amount['bitcoin'], value1 + value3 )
379+
assert_equal(multi_asset_amount[test_asset], Decimal('0.00000003'))
380+
371381
# Check blinded multisig functionality
372382
# Get two pubkeys
373383
blinded_addr = self.nodes[0].getnewaddress()

qa/rpc-tests/receivedby.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,11 @@ def run_test(self):
5656
self.sync_all()
5757
assert_array_result(self.nodes[1].listreceivedbyaddress(),
5858
{"address":unblinded},
59-
{"address":unblinded, "account":"", "amount":Decimal("0.1"), "confirmations":10, "txids":[txid,]})
59+
{"address":unblinded, "account":"", "amount":{"bitcoin":Decimal("0.1")}, "confirmations":10, "txids":[txid,]})
6060
#With min confidence < 10
6161
assert_array_result(self.nodes[1].listreceivedbyaddress(5),
6262
{"address":unblinded},
63-
{"address":unblinded, "account":"", "amount":Decimal("0.1"), "confirmations":10, "txids":[txid,]})
63+
{"address":unblinded, "account":"", "amount":{"bitcoin":Decimal("0.1")}, "confirmations":10, "txids":[txid,]})
6464
#With min confidence > 10, should not find Tx
6565
assert_array_result(self.nodes[1].listreceivedbyaddress(11),{"blindedaddress":addr},{ },True)
6666

@@ -69,7 +69,7 @@ def run_test(self):
6969
unblinded = self.nodes[1].validateaddress(addr)['unconfidential']
7070
assert_array_result(self.nodes[1].listreceivedbyaddress(0,True),
7171
{"address":unblinded},
72-
{"address":unblinded, "account":"", "amount":0, "confirmations":0, "txids":[]})
72+
{"address":unblinded, "account":"", "amount":{}, "confirmations":0, "txids":[]})
7373

7474
'''
7575
getreceivedbyaddress Test
@@ -106,7 +106,7 @@ def run_test(self):
106106
received_by_account_json = get_sub_array_from_array(self.nodes[1].listreceivedbyaccount(),{"account":account})
107107
if len(received_by_account_json) == 0:
108108
raise AssertionError("No accounts found in node")
109-
balance_by_account = self.nodes[1].getreceivedbyaccount(account)
109+
balance_by_account = self.nodes[1].getreceivedbyaccount(account)["bitcoin"]
110110

111111
txid = self.nodes[0].sendtoaddress(addr, 0.1)
112112
self.sync_all()
@@ -117,7 +117,7 @@ def run_test(self):
117117
received_by_account_json)
118118

119119
# getreceivedbyaddress should return same balance because of 0 confirmations
120-
balance = self.nodes[1].getreceivedbyaccount(account)
120+
balance = self.nodes[1].getreceivedbyaccount(account)["bitcoin"]
121121
if balance != balance_by_account:
122122
raise AssertionError("Wrong balance returned by getreceivedbyaccount, %0.2f"%(balance))
123123

@@ -126,10 +126,10 @@ def run_test(self):
126126
# listreceivedbyaccount should return updated account balance
127127
assert_array_result(self.nodes[1].listreceivedbyaccount(),
128128
{"account":account},
129-
{"account":received_by_account_json["account"], "amount":(received_by_account_json["amount"] + Decimal("0.1"))})
129+
{"account":received_by_account_json["account"], "amount":{"bitcoin":(received_by_account_json["amount"]["bitcoin"] + Decimal("0.1"))}})
130130

131131
# getreceivedbyaddress should return updates balance
132-
balance = self.nodes[1].getreceivedbyaccount(account)
132+
balance = self.nodes[1].getreceivedbyaccount(account)["bitcoin"]
133133
if balance != balance_by_account + Decimal("0.1"):
134134
raise AssertionError("Wrong balance returned by getreceivedbyaccount, %0.2f"%(balance))
135135

@@ -140,12 +140,12 @@ def run_test(self):
140140
raise AssertionError("No accounts found in node")
141141

142142
# Test includeempty of listreceivedbyaccount
143-
if received_by_account_json["amount"] != Decimal("0.0"):
143+
if received_by_account_json["amount"] != {}:
144144
raise AssertionError("Wrong balance returned by listreceivedbyaccount, %0.2f"%(received_by_account_json["amount"]))
145145

146146
# Test getreceivedbyaccount for 0 amount accounts
147147
balance = self.nodes[1].getreceivedbyaccount("mynewaccount")
148-
if balance != Decimal("0.0"):
148+
if balance != {}:
149149
raise AssertionError("Wrong balance returned by getreceivedbyaccount, %0.2f"%(balance))
150150

151151
if __name__ == '__main__':

src/wallet/rpcwallet.cpp

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -839,7 +839,7 @@ UniValue getreceivedbyaccount(const JSONRPCRequest& request)
839839
set<CTxDestination> setAddress = pwalletMain->GetAccountAddresses(strAccount);
840840

841841
// Tally
842-
CAmount nAmount = 0;
842+
CAmountMap mapAmount;
843843
for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
844844
{
845845
const CWalletTx& wtx = (*it).second;
@@ -849,13 +849,17 @@ UniValue getreceivedbyaccount(const JSONRPCRequest& request)
849849
for (unsigned int i = 0; i < wtx.tx->vout.size(); i++)
850850
{
851851
CTxDestination address;
852-
if (ExtractDestination(wtx.tx->vout[i].scriptPubKey, address) && IsMine(*pwalletMain, address) && setAddress.count(address))
853-
if (wtx.GetDepthInMainChain() >= nMinDepth && wtx.GetOutputValueOut(i) >= 0)
854-
nAmount += wtx.GetOutputValueOut(i);
852+
if (ExtractDestination(wtx.tx->vout[i].scriptPubKey, address) && IsMine(*pwalletMain, address) && setAddress.count(address)) {
853+
if (wtx.GetDepthInMainChain() >= nMinDepth && wtx.GetOutputValueOut(i) >= 0) {
854+
CAmountMap wtxValue;
855+
wtxValue[wtx.GetOutputAsset(i)] = wtx.GetOutputValueOut(i);
856+
mapAmount += wtxValue;
857+
}
858+
}
855859
}
856860
}
857861

858-
return ValueFromAmount(nAmount);
862+
return PushAssetBalance(mapAmount, pwalletMain, "");
859863
}
860864

861865

@@ -1380,12 +1384,12 @@ struct tallyitem
13801384
{
13811385
CBitcoinAddress address;
13821386
CAmount nAmount;
1387+
CAmountMap mapAmount;
13831388
int nConf;
13841389
vector<uint256> txids;
13851390
bool fIsWatchonly;
13861391
tallyitem()
13871392
{
1388-
nAmount = 0;
13891393
nConf = std::numeric_limits<int>::max();
13901394
fIsWatchonly = false;
13911395
}
@@ -1408,14 +1412,14 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts)
14081412
if(params[2].get_bool())
14091413
filter = filter | ISMINE_WATCH_ONLY;
14101414

1411-
std::string strasset = "bitcoin";
1415+
std::string strasset = "";
14121416
if (params.size() > 3 && params[3].isStr()) {
14131417
if (fByAccounts)
14141418
throw JSONRPCError(RPC_WALLET_ERROR, "Accounts are completely disabled for assets.");
14151419
strasset = params[3].get_str();
14161420
}
14171421
CAsset asset;
1418-
if (strasset != "*")
1422+
if (strasset != "")
14191423
asset = GetAssetFromString(strasset);
14201424

14211425
// Tally
@@ -1444,14 +1448,16 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts)
14441448
if (wtx.GetOutputValueOut(i) < 0)
14451449
continue;
14461450

1447-
if (strasset != "*" && wtx.GetOutputAsset(i) != asset)
1451+
if (strasset != "" && wtx.GetOutputAsset(i) != asset)
14481452
continue;
14491453

14501454
CBitcoinAddress bitcoinaddress(address);
14511455

14521456
tallyitem& item = mapTally[address];
14531457
item.address = bitcoinaddress;
1454-
item.nAmount += wtx.GetOutputValueOut(i);
1458+
CAmountMap wtxValue;
1459+
wtxValue[wtx.GetOutputAsset(i)] = wtx.GetOutputValueOut(i);
1460+
item.mapAmount += wtxValue;
14551461
item.nConf = min(item.nConf, nDepth);
14561462
item.txids.push_back(wtx.GetHash());
14571463
if (mine & ISMINE_WATCH_ONLY)
@@ -1471,21 +1477,21 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts)
14711477
continue;
14721478

14731479
CBitcoinAddress fulladdress = address;
1474-
CAmount nAmount = 0;
1480+
CAmountMap mapAmount;
14751481
int nConf = std::numeric_limits<int>::max();
14761482
bool fIsWatchonly = false;
14771483
if (it != mapTally.end())
14781484
{
14791485
fulladdress = (*it).second.address;
1480-
nAmount = (*it).second.nAmount;
1486+
mapAmount = (*it).second.mapAmount;
14811487
nConf = (*it).second.nConf;
14821488
fIsWatchonly = (*it).second.fIsWatchonly;
14831489
}
14841490

14851491
if (fByAccounts)
14861492
{
14871493
tallyitem& _item = mapAccountTally[strAccount];
1488-
_item.nAmount += nAmount;
1494+
_item.mapAmount += mapAmount;
14891495
_item.nConf = min(_item.nConf, nConf);
14901496
_item.fIsWatchonly = fIsWatchonly;
14911497
}
@@ -1498,10 +1504,9 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts)
14981504
fulladdress = fulladdress.GetUnblinded();
14991505
obj.push_back(Pair("address", fulladdress.ToString()));
15001506
obj.push_back(Pair("account", strAccount));
1501-
obj.push_back(Pair("amount", ValueFromAmount(nAmount)));
1507+
obj.push_back(Pair("amount", PushAssetBalance(mapAmount, pwalletMain, strasset)));
15021508
obj.push_back(Pair("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
1503-
if (!fByAccounts)
1504-
obj.push_back(Pair("label", strAccount));
1509+
obj.push_back(Pair("label", strAccount));
15051510
UniValue transactions(UniValue::VARR);
15061511
if (it != mapTally.end())
15071512
{
@@ -1519,13 +1524,13 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts)
15191524
{
15201525
for (map<string, tallyitem>::iterator it = mapAccountTally.begin(); it != mapAccountTally.end(); ++it)
15211526
{
1522-
CAmount nAmount = (*it).second.nAmount;
1527+
CAmountMap mapAmount = (*it).second.mapAmount;
15231528
int nConf = (*it).second.nConf;
15241529
UniValue obj(UniValue::VOBJ);
15251530
if((*it).second.fIsWatchonly)
15261531
obj.push_back(Pair("involvesWatchonly", true));
15271532
obj.push_back(Pair("account", (*it).first));
1528-
obj.push_back(Pair("amount", ValueFromAmount(nAmount)));
1533+
obj.push_back(Pair("amount", PushAssetBalance(mapAmount, pwalletMain, strasset)));
15291534
obj.push_back(Pair("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
15301535
ret.push_back(obj);
15311536
}
@@ -1541,13 +1546,13 @@ UniValue listreceivedbyaddress(const JSONRPCRequest& request)
15411546

15421547
if (request.fHelp || request.params.size() > 4)
15431548
throw runtime_error(
1544-
"listreceivedbyaddress ( minconf include_empty include_watchonly, asset)\n"
1549+
"listreceivedbyaddress ( minconf include_empty include_watchonly, \"assetlabel\" )\n"
15451550
"\nList balances by receiving address.\n"
15461551
"\nArguments:\n"
15471552
"1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n"
15481553
"2. include_empty (bool, optional, default=false) Whether to include addresses that haven't received any payments.\n"
15491554
"3. include_watchonly (bool, optional, default=false) Whether to include watch-only addresses (see 'importaddress').\n"
1550-
"4. \"asset\" (string, optional, default=bitcoin) The hex asset id or label to filter for. \"*\" is used to list all results.\n"
1555+
"4. \"assetlabel\" (string, optional) The hex asset id or asset label to filter for.\n"
15511556
"\nResult:\n"
15521557
"[\n"
15531558
" {\n"

0 commit comments

Comments
 (0)