Skip to content

Commit 8897a21

Browse files
committed
rpc: getreceivedbylabel, don't loop over the entire wallet txs map if no destinations were found for the input label.
If wallet.GetLabelAddresses() returns an empty vector (the wallet does not have addresses with that label in the addressbook) or if none of the returned destinations are from the wallet, we can return the function right away.
1 parent 1ab389b commit 8897a21

File tree

2 files changed

+19
-13
lines changed

2 files changed

+19
-13
lines changed

src/wallet/rpc/coins.cpp

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,28 +18,31 @@
1818
namespace wallet {
1919
static CAmount GetReceived(const CWallet& wallet, const UniValue& params, bool by_label) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
2020
{
21-
std::set<CScript> output_scripts;
22-
21+
std::set<CTxDestination> addresses;
2322
if (by_label) {
2423
// Get the set of addresses assigned to label
25-
std::string label = LabelFromValue(params[0]);
26-
for (const auto& address : wallet.GetLabelAddresses(label)) {
27-
auto output_script{GetScriptForDestination(address)};
28-
if (wallet.IsMine(output_script)) {
29-
output_scripts.insert(output_script);
30-
}
31-
}
24+
addresses = wallet.GetLabelAddresses(LabelFromValue(params[0]));
25+
if (addresses.empty()) throw JSONRPCError(RPC_WALLET_ERROR, "Label not found in wallet");
3226
} else {
3327
// Get the address
3428
CTxDestination dest = DecodeDestination(params[0].get_str());
3529
if (!IsValidDestination(dest)) {
3630
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
3731
}
38-
CScript script_pub_key = GetScriptForDestination(dest);
39-
if (!wallet.IsMine(script_pub_key)) {
40-
throw JSONRPCError(RPC_WALLET_ERROR, "Address not found in wallet");
32+
addresses.insert(dest);
33+
}
34+
35+
// Filter by own scripts only
36+
std::set<CScript> output_scripts;
37+
for (const auto& address : addresses) {
38+
auto output_script{GetScriptForDestination(address)};
39+
if (wallet.IsMine(output_script)) {
40+
output_scripts.insert(output_script);
4141
}
42-
output_scripts.insert(script_pub_key);
42+
}
43+
44+
if (output_scripts.empty()) {
45+
throw JSONRPCError(RPC_WALLET_ERROR, "Address not found in wallet");
4346
}
4447

4548
// Minimum confirmations

test/functional/wallet_listreceivedby.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,9 @@ def run_test(self):
131131
txid = self.nodes[0].sendtoaddress(addr, 0.1)
132132
self.sync_all()
133133

134+
# getreceivedbylabel returns an error if the wallet doesn't own the label
135+
assert_raises_rpc_error(-4, "Label not found in wallet", self.nodes[0].getreceivedbylabel, "dummy")
136+
134137
# listreceivedbylabel should return received_by_label_json because of 0 confirmations
135138
assert_array_result(self.nodes[1].listreceivedbylabel(),
136139
{"label": label},

0 commit comments

Comments
 (0)