From 92735bca313768dbc49789566c47e3a68ecef59a Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Mon, 6 Aug 2012 13:02:48 -0400 Subject: [PATCH] Add txout address filtering to listunspent. This applies on top of the coincontrol listaddressgroupings patch and makes finding eligible outputs from the groups returned by listaddressgroupings possible. --- src/bitcoinrpc.cpp | 1 + src/rpcrawtransaction.cpp | 27 +++++++++++++++++++++++---- src/wallet.h | 2 +- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index ebde28fe..c144f5fb 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -1140,6 +1140,7 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector 1) ConvertTo(params[1]); if (strMethod == "listunspent" && n > 0) ConvertTo(params[0]); if (strMethod == "listunspent" && n > 1) ConvertTo(params[1]); + if (strMethod == "listunspent" && n > 2) ConvertTo(params[2]); if (strMethod == "getrawtransaction" && n > 1) ConvertTo(params[1]); if (strMethod == "createrawtransaction" && n > 0) ConvertTo(params[0]); if (strMethod == "createrawtransaction" && n > 1) ConvertTo(params[1]); diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index fefefc7d..d6fb30ca 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -138,24 +138,40 @@ Value getrawtransaction(const Array& params, bool fHelp) Value listunspent(const Array& params, bool fHelp) { - if (fHelp || params.size() > 2) + if (fHelp || params.size() > 3) throw runtime_error( - "listunspent [minconf=1] [maxconf=999999]\n" + "listunspent [minconf=1] [maxconf=9999999] ['addr1','addr2',...]\n" "Returns array of unspent transaction outputs\n" "with between minconf and maxconf (inclusive) confirmations.\n" + "Optionally filtered to only include txouts paid to specified addresses.\n" "Results are an array of Objects, each of which has:\n" "{txid, vout, scriptPubKey, amount, confirmations}"); - RPCTypeCheck(params, list_of(int_type)(int_type)); + RPCTypeCheck(params, list_of(int_type)(int_type)(array_type)); int nMinDepth = 1; if (params.size() > 0) nMinDepth = params[0].get_int(); - int nMaxDepth = 999999; + int nMaxDepth = 9999999; if (params.size() > 1) nMaxDepth = params[1].get_int(); + set setAddress; + if (params.size() > 2) + { + Array inputs = params[2].get_array(); + BOOST_FOREACH(Value& input, inputs) + { + CBitcoinAddress address(input.get_str()); + if (!address.IsValid()) + throw JSONRPCError(-5, string("Invalid Bitcoin address:")+input.get_str()); + if (setAddress.count(address)) + throw JSONRPCError(-8, string("Invalid parameter, duplicated address: ")+input.get_str()); + setAddress.insert(address); + } + } + Array results; vector vecOutputs; pwalletMain->AvailableCoins(vecOutputs, false); @@ -164,6 +180,9 @@ Value listunspent(const Array& params, bool fHelp) if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth) continue; + if (setAddress.size() && !setAddress.count(out.tx->GetAddressOfTxOut(out.i))) + continue; + int64 nValue = out.tx->vout[out.i].nValue; const CScript& pk = out.tx->vout[out.i].scriptPubKey; Object entry; diff --git a/src/wallet.h b/src/wallet.h index 5f6a6a44..f02c1467 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -647,7 +647,7 @@ public: return true; } - std::string GetAddressOfTxOut(int n) + std::string GetAddressOfTxOut(int n) const { CTxDestination addr; ExtractDestination(vout[n].scriptPubKey, addr);