aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Maxwell <greg@xiph.org>2012-08-06 13:02:48 -0400
committerGregory Maxwell <greg@xiph.org>2012-08-23 15:55:50 -0400
commit92735bca313768dbc49789566c47e3a68ecef59a (patch)
treebc5f0fa10286a0a9122296441c92126648e2c6fa
parent22dfd7359863217eb8caef75084cfa8fa8e1d8fb (diff)
downloadbitcoin-92735bca313768dbc49789566c47e3a68ecef59a.tar.xz
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.
-rw-r--r--src/bitcoinrpc.cpp1
-rw-r--r--src/rpcrawtransaction.cpp27
-rw-r--r--src/wallet.h2
3 files changed, 25 insertions, 5 deletions
diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp
index ebde28fe04..c144f5fbad 100644
--- a/src/bitcoinrpc.cpp
+++ b/src/bitcoinrpc.cpp
@@ -1140,6 +1140,7 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector<std::stri
if (strMethod == "addmultisigaddress" && n > 1) ConvertTo<Array>(params[1]);
if (strMethod == "listunspent" && n > 0) ConvertTo<boost::int64_t>(params[0]);
if (strMethod == "listunspent" && n > 1) ConvertTo<boost::int64_t>(params[1]);
+ if (strMethod == "listunspent" && n > 2) ConvertTo<Array>(params[2]);
if (strMethod == "getrawtransaction" && n > 1) ConvertTo<boost::int64_t>(params[1]);
if (strMethod == "createrawtransaction" && n > 0) ConvertTo<Array>(params[0]);
if (strMethod == "createrawtransaction" && n > 1) ConvertTo<Object>(params[1]);
diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp
index fefefc7d62..d6fb30cac6 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<CBitcoinAddress> 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<COutput> 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 5f6a6a4444..f02c1467b5 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);