Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/rpcwallet.cpp
Show First 20 Lines • Show All 1,405 Lines • ▼ Show 20 Lines | if (params.size() > 1) { | ||||
fIncludeEmpty = params[1].get_bool(); | fIncludeEmpty = params[1].get_bool(); | ||||
} | } | ||||
isminefilter filter = ISMINE_SPENDABLE; | isminefilter filter = ISMINE_SPENDABLE; | ||||
if (params.size() > 2 && params[2].get_bool()) { | if (params.size() > 2 && params[2].get_bool()) { | ||||
filter = filter | ISMINE_WATCH_ONLY; | filter = filter | ISMINE_WATCH_ONLY; | ||||
} | } | ||||
bool has_filtered_address = false; | |||||
CTxDestination filtered_address = CNoDestination(); | |||||
if (!fByAccounts && params.size() > 3) { | |||||
if (!IsValidDestinationString(params[3].get_str(), | |||||
config.GetChainParams())) { | |||||
throw JSONRPCError(RPC_WALLET_ERROR, | |||||
"address_filter parameter was invalid"); | |||||
} | |||||
filtered_address = | |||||
DecodeDestination(params[3].get_str(), config.GetChainParams()); | |||||
has_filtered_address = true; | |||||
} | |||||
// Tally | // Tally | ||||
std::map<CTxDestination, tallyitem> mapTally; | std::map<CTxDestination, tallyitem> mapTally; | ||||
for (const std::pair<uint256, CWalletTx> &pairWtx : pwallet->mapWallet) { | for (const std::pair<uint256, CWalletTx> &pairWtx : pwallet->mapWallet) { | ||||
const CWalletTx &wtx = pairWtx.second; | const CWalletTx &wtx = pairWtx.second; | ||||
CValidationState state; | CValidationState state; | ||||
if (wtx.IsCoinBase() || | if (wtx.IsCoinBase() || | ||||
!ContextualCheckTransactionForCurrentBlock(config, *wtx.tx, | !ContextualCheckTransactionForCurrentBlock(config, *wtx.tx, | ||||
state)) { | state)) { | ||||
continue; | continue; | ||||
} | } | ||||
int nDepth = wtx.GetDepthInMainChain(); | int nDepth = wtx.GetDepthInMainChain(); | ||||
if (nDepth < nMinDepth) { | if (nDepth < nMinDepth) { | ||||
continue; | continue; | ||||
} | } | ||||
for (const CTxOut &txout : wtx.tx->vout) { | for (const CTxOut &txout : wtx.tx->vout) { | ||||
CTxDestination address; | CTxDestination address; | ||||
if (!ExtractDestination(txout.scriptPubKey, address)) { | if (!ExtractDestination(txout.scriptPubKey, address)) { | ||||
continue; | continue; | ||||
} | } | ||||
if (has_filtered_address && !(filtered_address == address)) { | |||||
continue; | |||||
} | |||||
isminefilter mine = IsMine(*pwallet, address); | isminefilter mine = IsMine(*pwallet, address); | ||||
if (!(mine & filter)) { | if (!(mine & filter)) { | ||||
continue; | continue; | ||||
} | } | ||||
tallyitem &item = mapTally[address]; | tallyitem &item = mapTally[address]; | ||||
item.nAmount += txout.nValue; | item.nAmount += txout.nValue; | ||||
item.nConf = std::min(item.nConf, nDepth); | item.nConf = std::min(item.nConf, nDepth); | ||||
item.txids.push_back(wtx.GetId()); | item.txids.push_back(wtx.GetId()); | ||||
if (mine & ISMINE_WATCH_ONLY) { | if (mine & ISMINE_WATCH_ONLY) { | ||||
item.fIsWatchonly = true; | item.fIsWatchonly = true; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
// Reply | // Reply | ||||
UniValue ret(UniValue::VARR); | UniValue ret(UniValue::VARR); | ||||
std::map<std::string, tallyitem> mapAccountTally; | std::map<std::string, tallyitem> mapAccountTally; | ||||
for (const std::pair<CTxDestination, CAddressBookData> &item : | |||||
pwallet->mapAddressBook) { | // Create mapAddressBook iterator | ||||
const CTxDestination &dest = item.first; | // If we aren't filtering, go from begin() to end() | ||||
const std::string &strAccount = item.second.name; | auto start = pwallet->mapAddressBook.begin(); | ||||
std::map<CTxDestination, tallyitem>::iterator it = mapTally.find(dest); | auto end = pwallet->mapAddressBook.end(); | ||||
// If we are filtering, find() the applicable entry | |||||
if (has_filtered_address) { | |||||
start = pwallet->mapAddressBook.find(filtered_address); | |||||
if (start != end) { | |||||
end = std::next(start); | |||||
} | |||||
} | |||||
for (auto item_it = start; item_it != end; ++item_it) { | |||||
const CTxDestination &address = item_it->first; | |||||
const std::string &strAccount = item_it->second.name; | |||||
std::map<CTxDestination, tallyitem>::iterator it = | |||||
mapTally.find(address); | |||||
if (it == mapTally.end() && !fIncludeEmpty) { | if (it == mapTally.end() && !fIncludeEmpty) { | ||||
continue; | continue; | ||||
} | } | ||||
Amount nAmount = Amount::zero(); | Amount nAmount = Amount::zero(); | ||||
int nConf = std::numeric_limits<int>::max(); | int nConf = std::numeric_limits<int>::max(); | ||||
bool fIsWatchonly = false; | bool fIsWatchonly = false; | ||||
if (it != mapTally.end()) { | if (it != mapTally.end()) { | ||||
nAmount = (*it).second.nAmount; | nAmount = (*it).second.nAmount; | ||||
nConf = (*it).second.nConf; | nConf = (*it).second.nConf; | ||||
fIsWatchonly = (*it).second.fIsWatchonly; | fIsWatchonly = (*it).second.fIsWatchonly; | ||||
} | } | ||||
if (fByAccounts) { | if (fByAccounts) { | ||||
tallyitem &_item = mapAccountTally[strAccount]; | tallyitem &_item = mapAccountTally[strAccount]; | ||||
_item.nAmount += nAmount; | _item.nAmount += nAmount; | ||||
_item.nConf = std::min(_item.nConf, nConf); | _item.nConf = std::min(_item.nConf, nConf); | ||||
_item.fIsWatchonly = fIsWatchonly; | _item.fIsWatchonly = fIsWatchonly; | ||||
} else { | } else { | ||||
UniValue obj(UniValue::VOBJ); | UniValue obj(UniValue::VOBJ); | ||||
if (fIsWatchonly) { | if (fIsWatchonly) { | ||||
obj.push_back(Pair("involvesWatchonly", true)); | obj.push_back(Pair("involvesWatchonly", true)); | ||||
} | } | ||||
obj.push_back(Pair("address", EncodeDestination(dest))); | obj.push_back(Pair("address", EncodeDestination(address))); | ||||
obj.push_back(Pair("account", strAccount)); | obj.push_back(Pair("account", strAccount)); | ||||
obj.push_back(Pair("amount", ValueFromAmount(nAmount))); | obj.push_back(Pair("amount", ValueFromAmount(nAmount))); | ||||
obj.push_back( | obj.push_back( | ||||
Pair("confirmations", | Pair("confirmations", | ||||
(nConf == std::numeric_limits<int>::max() ? 0 : nConf))); | (nConf == std::numeric_limits<int>::max() ? 0 : nConf))); | ||||
if (!fByAccounts) { | if (!fByAccounts) { | ||||
obj.push_back(Pair("label", strAccount)); | obj.push_back(Pair("label", strAccount)); | ||||
} | } | ||||
Show All 32 Lines | |||||
static UniValue listreceivedbyaddress(const Config &config, | static UniValue listreceivedbyaddress(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
CWallet *const pwallet = GetWalletForJSONRPCRequest(request); | CWallet *const pwallet = GetWalletForJSONRPCRequest(request); | ||||
if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { | if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { | ||||
return NullUniValue; | return NullUniValue; | ||||
} | } | ||||
if (request.fHelp || request.params.size() > 3) { | if (request.fHelp || request.params.size() > 4) { | ||||
throw std::runtime_error( | throw std::runtime_error( | ||||
"listreceivedbyaddress ( minconf include_empty include_watchonly)\n" | "listreceivedbyaddress ( minconf include_empty include_watchonly " | ||||
"address_filter )\n" | |||||
"\nList balances by receiving address.\n" | "\nList balances by receiving address.\n" | ||||
"\nArguments:\n" | "\nArguments:\n" | ||||
"1. minconf (numeric, optional, default=1) The minimum " | "1. minconf (numeric, optional, default=1) The minimum " | ||||
"number of confirmations before payments are included.\n" | "number of confirmations before payments are included.\n" | ||||
"2. include_empty (bool, optional, default=false) Whether to " | "2. include_empty (bool, optional, default=false) Whether to " | ||||
"include addresses that haven't received any payments.\n" | "include addresses that haven't received any payments.\n" | ||||
"3. include_watchonly (bool, optional, default=false) Whether to " | "3. include_watchonly (bool, optional, default=false) Whether to " | ||||
"include watch-only addresses (see 'importaddress').\n" | "include watch-only addresses (see 'importaddress').\n" | ||||
"4. address_filter (string, optional) If present, only return " | |||||
"information on this address.\n" | |||||
"\nResult:\n" | "\nResult:\n" | ||||
"[\n" | "[\n" | ||||
" {\n" | " {\n" | ||||
" \"involvesWatchonly\" : true, (bool) Only returned if " | " \"involvesWatchonly\" : true, (bool) Only returned if " | ||||
"imported addresses were involved in transaction\n" | "imported addresses were involved in transaction\n" | ||||
" \"address\" : \"receivingaddress\", (string) The receiving " | " \"address\" : \"receivingaddress\", (string) The receiving " | ||||
"address\n" | "address\n" | ||||
" \"account\" : \"accountname\", (string) DEPRECATED. The " | " \"account\" : \"accountname\", (string) DEPRECATED. The " | ||||
Show All 13 Lines | if (request.fHelp || request.params.size() > 4) { | ||||
" ]\n" | " ]\n" | ||||
" }\n" | " }\n" | ||||
" ,...\n" | " ,...\n" | ||||
"]\n" | "]\n" | ||||
"\nExamples:\n" + | "\nExamples:\n" + | ||||
HelpExampleCli("listreceivedbyaddress", "") + | HelpExampleCli("listreceivedbyaddress", "") + | ||||
HelpExampleCli("listreceivedbyaddress", "6 true") + | HelpExampleCli("listreceivedbyaddress", "6 true") + | ||||
HelpExampleRpc("listreceivedbyaddress", "6, true, true")); | HelpExampleRpc("listreceivedbyaddress", "6, true, true") + | ||||
HelpExampleRpc( | |||||
"listreceivedbyaddress", | |||||
"6, true, true, \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\"")); | |||||
} | } | ||||
ObserveSafeMode(); | ObserveSafeMode(); | ||||
LOCK2(cs_main, pwallet->cs_wallet); | LOCK2(cs_main, pwallet->cs_wallet); | ||||
return ListReceived(config, pwallet, request.params, false); | return ListReceived(config, pwallet, request.params, false); | ||||
} | } | ||||
static UniValue listreceivedbyaccount(const Config &config, | static UniValue listreceivedbyaccount(const Config &config, | ||||
▲ Show 20 Lines • Show All 2,065 Lines • ▼ Show 20 Lines | static const ContextFreeRPCCommand commands[] = { | ||||
{ "wallet", "gettransaction", gettransaction, {"txid","include_watchonly"} }, | { "wallet", "gettransaction", gettransaction, {"txid","include_watchonly"} }, | ||||
{ "wallet", "getunconfirmedbalance", getunconfirmedbalance, {} }, | { "wallet", "getunconfirmedbalance", getunconfirmedbalance, {} }, | ||||
{ "wallet", "getwalletinfo", getwalletinfo, {} }, | { "wallet", "getwalletinfo", getwalletinfo, {} }, | ||||
{ "wallet", "keypoolrefill", keypoolrefill, {"newsize"} }, | { "wallet", "keypoolrefill", keypoolrefill, {"newsize"} }, | ||||
{ "wallet", "listaccounts", listaccounts, {"minconf","include_watchonly"} }, | { "wallet", "listaccounts", listaccounts, {"minconf","include_watchonly"} }, | ||||
{ "wallet", "listaddressgroupings", listaddressgroupings, {} }, | { "wallet", "listaddressgroupings", listaddressgroupings, {} }, | ||||
{ "wallet", "listlockunspent", listlockunspent, {} }, | { "wallet", "listlockunspent", listlockunspent, {} }, | ||||
{ "wallet", "listreceivedbyaccount", listreceivedbyaccount, {"minconf","include_empty","include_watchonly"} }, | { "wallet", "listreceivedbyaccount", listreceivedbyaccount, {"minconf","include_empty","include_watchonly"} }, | ||||
{ "wallet", "listreceivedbyaddress", listreceivedbyaddress, {"minconf","include_empty","include_watchonly"} }, | { "wallet", "listreceivedbyaddress", listreceivedbyaddress, {"minconf","include_empty","include_watchonly","address_filter"} }, | ||||
{ "wallet", "listsinceblock", listsinceblock, {"blockhash","target_confirmations","include_watchonly"} }, | { "wallet", "listsinceblock", listsinceblock, {"blockhash","target_confirmations","include_watchonly"} }, | ||||
{ "wallet", "listtransactions", listtransactions, {"account","count","skip","include_watchonly"} }, | { "wallet", "listtransactions", listtransactions, {"account","count","skip","include_watchonly"} }, | ||||
{ "wallet", "listunspent", listunspent, {"minconf","maxconf","addresses","include_unsafe","query_options"} }, | { "wallet", "listunspent", listunspent, {"minconf","maxconf","addresses","include_unsafe","query_options"} }, | ||||
{ "wallet", "listwallets", listwallets, {} }, | { "wallet", "listwallets", listwallets, {} }, | ||||
{ "wallet", "lockunspent", lockunspent, {"unlock","transactions"} }, | { "wallet", "lockunspent", lockunspent, {"unlock","transactions"} }, | ||||
{ "wallet", "move", movecmd, {"fromaccount","toaccount","amount","minconf","comment"} }, | { "wallet", "move", movecmd, {"fromaccount","toaccount","amount","minconf","comment"} }, | ||||
{ "wallet", "rescanblockchain", rescanblockchain, {"start_height", "stop_height"} }, | { "wallet", "rescanblockchain", rescanblockchain, {"start_height", "stop_height"} }, | ||||
{ "wallet", "sendfrom", sendfrom, {"fromaccount","toaddress","amount","minconf","comment","comment_to"} }, | { "wallet", "sendfrom", sendfrom, {"fromaccount","toaddress","amount","minconf","comment","comment_to"} }, | ||||
Show All 21 Lines |