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.
This commit is contained in:
Gregory Maxwell 2012-08-06 13:02:48 -04:00
parent 22dfd73598
commit 92735bca31
3 changed files with 25 additions and 5 deletions

View File

@ -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 == "addmultisigaddress" && n > 1) ConvertTo<Array>(params[1]);
if (strMethod == "listunspent" && n > 0) ConvertTo<boost::int64_t>(params[0]); 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 > 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 == "getrawtransaction" && n > 1) ConvertTo<boost::int64_t>(params[1]);
if (strMethod == "createrawtransaction" && n > 0) ConvertTo<Array>(params[0]); if (strMethod == "createrawtransaction" && n > 0) ConvertTo<Array>(params[0]);
if (strMethod == "createrawtransaction" && n > 1) ConvertTo<Object>(params[1]); if (strMethod == "createrawtransaction" && n > 1) ConvertTo<Object>(params[1]);

View File

@ -138,24 +138,40 @@ Value getrawtransaction(const Array& params, bool fHelp)
Value listunspent(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( throw runtime_error(
"listunspent [minconf=1] [maxconf=999999]\n" "listunspent [minconf=1] [maxconf=9999999] ['addr1','addr2',...]\n"
"Returns array of unspent transaction outputs\n" "Returns array of unspent transaction outputs\n"
"with between minconf and maxconf (inclusive) confirmations.\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" "Results are an array of Objects, each of which has:\n"
"{txid, vout, scriptPubKey, amount, confirmations}"); "{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; int nMinDepth = 1;
if (params.size() > 0) if (params.size() > 0)
nMinDepth = params[0].get_int(); nMinDepth = params[0].get_int();
int nMaxDepth = 999999; int nMaxDepth = 9999999;
if (params.size() > 1) if (params.size() > 1)
nMaxDepth = params[1].get_int(); 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; Array results;
vector<COutput> vecOutputs; vector<COutput> vecOutputs;
pwalletMain->AvailableCoins(vecOutputs, false); pwalletMain->AvailableCoins(vecOutputs, false);
@ -164,6 +180,9 @@ Value listunspent(const Array& params, bool fHelp)
if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth) if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth)
continue; continue;
if (setAddress.size() && !setAddress.count(out.tx->GetAddressOfTxOut(out.i)))
continue;
int64 nValue = out.tx->vout[out.i].nValue; int64 nValue = out.tx->vout[out.i].nValue;
const CScript& pk = out.tx->vout[out.i].scriptPubKey; const CScript& pk = out.tx->vout[out.i].scriptPubKey;
Object entry; Object entry;

View File

@ -647,7 +647,7 @@ public:
return true; return true;
} }
std::string GetAddressOfTxOut(int n) std::string GetAddressOfTxOut(int n) const
{ {
CTxDestination addr; CTxDestination addr;
ExtractDestination(vout[n].scriptPubKey, addr); ExtractDestination(vout[n].scriptPubKey, addr);