Skip to content

Commit

Permalink
rpc: getreceivedbylabel, don't loop over the entire wallet txs map if…
Browse files Browse the repository at this point in the history
… 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.
  • Loading branch information
furszy committed May 20, 2022
1 parent 1ab389b commit 8897a21
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 13 deletions.
29 changes: 16 additions & 13 deletions src/wallet/rpc/coins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,31 @@
namespace wallet {
static CAmount GetReceived(const CWallet& wallet, const UniValue& params, bool by_label) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
{
std::set<CScript> output_scripts;

std::set<CTxDestination> addresses;
if (by_label) {
// Get the set of addresses assigned to label
std::string label = LabelFromValue(params[0]);
for (const auto& address : wallet.GetLabelAddresses(label)) {
auto output_script{GetScriptForDestination(address)};
if (wallet.IsMine(output_script)) {
output_scripts.insert(output_script);
}
}
addresses = wallet.GetLabelAddresses(LabelFromValue(params[0]));
if (addresses.empty()) throw JSONRPCError(RPC_WALLET_ERROR, "Label not found in wallet");
} else {
// Get the address
CTxDestination dest = DecodeDestination(params[0].get_str());
if (!IsValidDestination(dest)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
}
CScript script_pub_key = GetScriptForDestination(dest);
if (!wallet.IsMine(script_pub_key)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Address not found in wallet");
addresses.insert(dest);
}

// Filter by own scripts only
std::set<CScript> output_scripts;
for (const auto& address : addresses) {
auto output_script{GetScriptForDestination(address)};
if (wallet.IsMine(output_script)) {
output_scripts.insert(output_script);
}
output_scripts.insert(script_pub_key);
}

if (output_scripts.empty()) {
throw JSONRPCError(RPC_WALLET_ERROR, "Address not found in wallet");
}

// Minimum confirmations
Expand Down
3 changes: 3 additions & 0 deletions test/functional/wallet_listreceivedby.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ def run_test(self):
txid = self.nodes[0].sendtoaddress(addr, 0.1)
self.sync_all()

# getreceivedbylabel returns an error if the wallet doesn't own the label
assert_raises_rpc_error(-4, "Label not found in wallet", self.nodes[0].getreceivedbylabel, "dummy")

# listreceivedbylabel should return received_by_label_json because of 0 confirmations
assert_array_result(self.nodes[1].listreceivedbylabel(),
{"label": label},
Expand Down

0 comments on commit 8897a21

Please sign in to comment.