aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/rpcwallet.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet/rpcwallet.cpp')
-rw-r--r--src/wallet/rpcwallet.cpp109
1 files changed, 57 insertions, 52 deletions
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index 2cc3072c16..3b6dfd42ca 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -9,8 +9,11 @@
#include "consensus/validation.h"
#include "core_io.h"
#include "init.h"
+#include "wallet/coincontrol.h"
#include "validation.h"
#include "net.h"
+#include "policy/feerate.h"
+#include "policy/fees.h"
#include "policy/policy.h"
#include "policy/rbf.h"
#include "rpc/server.h"
@@ -727,6 +730,9 @@ UniValue getbalance(const JSONRPCRequest& request)
if (request.params.size() == 0)
return ValueFromAmount(pwallet->GetBalance());
+ const std::string& account_param = request.params[0].get_str();
+ const std::string* account = account_param != "*" ? &account_param : nullptr;
+
int nMinDepth = 1;
if (request.params.size() > 1)
nMinDepth = request.params[1].get_int();
@@ -735,41 +741,7 @@ UniValue getbalance(const JSONRPCRequest& request)
if(request.params[2].get_bool())
filter = filter | ISMINE_WATCH_ONLY;
- if (request.params[0].get_str() == "*") {
- // Calculate total balance in a very different way from GetBalance().
- // The biggest difference is that GetBalance() sums up all unspent
- // TxOuts paying to the wallet, while this sums up both spent and
- // unspent TxOuts paying to the wallet, and then subtracts the values of
- // TxIns spending from the wallet. This also has fewer restrictions on
- // which unconfirmed transactions are considered trusted.
- CAmount nBalance = 0;
- for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
- const CWalletTx& wtx = pairWtx.second;
- if (!CheckFinalTx(wtx) || wtx.GetBlocksToMaturity() > 0 || wtx.GetDepthInMainChain() < 0)
- continue;
-
- CAmount allFee;
- std::string strSentAccount;
- std::list<COutputEntry> listReceived;
- std::list<COutputEntry> listSent;
- wtx.GetAmounts(listReceived, listSent, allFee, strSentAccount, filter);
- if (wtx.GetDepthInMainChain() >= nMinDepth)
- {
- BOOST_FOREACH(const COutputEntry& r, listReceived)
- nBalance += r.amount;
- }
- BOOST_FOREACH(const COutputEntry& s, listSent)
- nBalance -= s.amount;
- nBalance -= allFee;
- }
- return ValueFromAmount(nBalance);
- }
-
- std::string strAccount = AccountFromValue(request.params[0]);
-
- CAmount nBalance = pwallet->GetAccountBalance(strAccount, nMinDepth, filter);
-
- return ValueFromAmount(nBalance);
+ return ValueFromAmount(pwallet->GetLegacyBalance(filter, nMinDepth, account));
}
UniValue getunconfirmedbalance(const JSONRPCRequest &request)
@@ -899,7 +871,7 @@ UniValue sendfrom(const JSONRPCRequest& request)
EnsureWalletIsUnlocked(pwallet);
// Check funds
- CAmount nBalance = pwallet->GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE);
+ CAmount nBalance = pwallet->GetLegacyBalance(ISMINE_SPENDABLE, nMinDepth, &strAccount);
if (nAmount > nBalance)
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
@@ -1008,7 +980,7 @@ UniValue sendmany(const JSONRPCRequest& request)
EnsureWalletIsUnlocked(pwallet);
// Check funds
- CAmount nBalance = pwallet->GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE);
+ CAmount nBalance = pwallet->GetLegacyBalance(ISMINE_SPENDABLE, nMinDepth, &strAccount);
if (totalAmount > nBalance)
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
@@ -2076,7 +2048,7 @@ UniValue walletpassphrase(const JSONRPCRequest& request)
int64_t nSleepTime = request.params[1].get_int64();
pwallet->nRelockTime = GetTime() + nSleepTime;
- RPCRunLater(strprintf("lockwallet(%s)", pwallet->strWalletFile), boost::bind(LockWallet, pwallet), nSleepTime);
+ RPCRunLater(strprintf("lockwallet(%s)", pwallet->GetName()), boost::bind(LockWallet, pwallet), nSleepTime);
return NullUniValue;
}
@@ -2498,22 +2470,29 @@ UniValue listunspent(const JSONRPCRequest& request)
return NullUniValue;
}
- if (request.fHelp || request.params.size() > 4)
+ if (request.fHelp || request.params.size() > 5)
throw std::runtime_error(
- "listunspent ( minconf maxconf [\"addresses\",...] [include_unsafe] )\n"
+ "listunspent ( minconf maxconf [\"addresses\",...] [include_unsafe] [query_options])\n"
"\nReturns array of unspent transaction outputs\n"
"with between minconf and maxconf (inclusive) confirmations.\n"
"Optionally filter to only include txouts paid to specified addresses.\n"
"\nArguments:\n"
"1. minconf (numeric, optional, default=1) The minimum confirmations to filter\n"
"2. maxconf (numeric, optional, default=9999999) The maximum confirmations to filter\n"
- "3. \"addresses\" (string) A json array of bitcoin addresses to filter\n"
+ "3. \"addresses\" (string) A json array of bitcoin addresses to filter\n"
" [\n"
- " \"address\" (string) bitcoin address\n"
+ " \"address\" (string) bitcoin address\n"
" ,...\n"
" ]\n"
"4. include_unsafe (bool, optional, default=true) Include outputs that are not safe to spend\n"
" See description of \"safe\" attribute below.\n"
+ "5. query_options (json, optional) JSON with query options\n"
+ " {\n"
+ " \"minimumAmount\" (numeric or string, default=0) Minimum value of each UTXO in " + CURRENCY_UNIT + "\n"
+ " \"maximumAmount\" (numeric or string, default=unlimited) Maximum value of each UTXO in " + CURRENCY_UNIT + "\n"
+ " \"maximumCount\" (numeric or string, default=unlimited) Maximum number of UTXOs\n"
+ " \"minimumSumAmount\" (numeric or string, default=unlimited) Minimum sum value of all UTXOs in " + CURRENCY_UNIT + "\n"
+ " }\n"
"\nResult\n"
"[ (array of json object)\n"
" {\n"
@@ -2538,6 +2517,8 @@ UniValue listunspent(const JSONRPCRequest& request)
+ HelpExampleCli("listunspent", "")
+ HelpExampleCli("listunspent", "6 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"")
+ HelpExampleRpc("listunspent", "6, 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"")
+ + HelpExampleCli("listunspent", "6 9999999 '[]' true '{ \"minimumAmount\": 0.005 }'")
+ + HelpExampleRpc("listunspent", "6, 9999999, [] , true, { \"minimumAmount\": 0.005 } ")
);
int nMinDepth = 1;
@@ -2573,15 +2554,34 @@ UniValue listunspent(const JSONRPCRequest& request)
include_unsafe = request.params[3].get_bool();
}
+ CAmount nMinimumAmount = 0;
+ CAmount nMaximumAmount = MAX_MONEY;
+ CAmount nMinimumSumAmount = MAX_MONEY;
+ uint64_t nMaximumCount = 0;
+
+ if (request.params.size() > 4) {
+ const UniValue& options = request.params[4].get_obj();
+
+ if (options.exists("minimumAmount"))
+ nMinimumAmount = AmountFromValue(options["minimumAmount"]);
+
+ if (options.exists("maximumAmount"))
+ nMaximumAmount = AmountFromValue(options["maximumAmount"]);
+
+ if (options.exists("minimumSumAmount"))
+ nMinimumSumAmount = AmountFromValue(options["minimumSumAmount"]);
+
+ if (options.exists("maximumCount"))
+ nMaximumCount = options["maximumCount"].get_int64();
+ }
+
UniValue results(UniValue::VARR);
std::vector<COutput> vecOutputs;
assert(pwallet != NULL);
LOCK2(cs_main, pwallet->cs_wallet);
- pwallet->AvailableCoins(vecOutputs, !include_unsafe, NULL, true);
- BOOST_FOREACH(const COutput& out, vecOutputs) {
- if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth)
- continue;
+ pwallet->AvailableCoins(vecOutputs, !include_unsafe, NULL, nMinimumAmount, nMaximumAmount, nMinimumSumAmount, nMaximumCount, nMinDepth, nMaxDepth);
+ BOOST_FOREACH(const COutput& out, vecOutputs) {
CTxDestination address;
const CScript& scriptPubKey = out.tx->tx->vout[out.i].scriptPubKey;
bool fValidAddress = ExtractDestination(scriptPubKey, address);
@@ -2797,7 +2797,7 @@ UniValue bumpfee(const JSONRPCRequest& request)
"The command will fail if the wallet or mempool contains a transaction that spends one of T's outputs.\n"
"By default, the new fee will be calculated automatically using estimatefee.\n"
"The user can specify a confirmation target for estimatefee.\n"
- "Alternatively, the user can specify totalFee, or use RPC setpaytxfee to set a higher fee rate.\n"
+ "Alternatively, the user can specify totalFee, or use RPC settxfee to set a higher fee rate.\n"
"At a minimum, the new fee rate must be high enough to pay an additional new relay fee (incrementalfee\n"
"returned by getnetworkinfo) to enter the node's mempool.\n"
"\nArguments:\n"
@@ -2834,7 +2834,7 @@ UniValue bumpfee(const JSONRPCRequest& request)
hash.SetHex(request.params[0].get_str());
// optional parameters
- bool specifiedConfirmTarget = false;
+ bool ignoreGlobalPayTxFee = false;
int newConfirmTarget = nTxConfirmTarget;
CAmount totalFee = 0;
bool replaceable = true;
@@ -2851,7 +2851,10 @@ UniValue bumpfee(const JSONRPCRequest& request)
if (options.exists("confTarget") && options.exists("totalFee")) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "confTarget and totalFee options should not both be set. Please provide either a confirmation target for fee estimation or an explicit total fee for the transaction.");
} else if (options.exists("confTarget")) {
- specifiedConfirmTarget = true;
+ // If the user has explicitly set a confTarget in this rpc call,
+ // then override the default logic that uses the global payTxFee
+ // instead of the confirmation target.
+ ignoreGlobalPayTxFee = true;
newConfirmTarget = options["confTarget"].get_int();
if (newConfirmTarget <= 0) { // upper-bound will be checked by estimatefee/smartfee
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid confTarget (cannot be <= 0)");
@@ -2871,7 +2874,7 @@ UniValue bumpfee(const JSONRPCRequest& request)
LOCK2(cs_main, pwallet->cs_wallet);
EnsureWalletIsUnlocked(pwallet);
- CFeeBumper feeBump(pwallet, hash, newConfirmTarget, specifiedConfirmTarget, totalFee, replaceable);
+ CFeeBumper feeBump(pwallet, hash, newConfirmTarget, ignoreGlobalPayTxFee, totalFee, replaceable);
BumpFeeResult res = feeBump.getResult();
if (res != BumpFeeResult::OK)
{
@@ -2909,11 +2912,12 @@ UniValue bumpfee(const JSONRPCRequest& request)
UniValue errors(UniValue::VARR);
for (const std::string& err: feeBump.getErrors())
errors.push_back(err);
- result.push_back(errors);
+ result.push_back(Pair("errors", errors));
return result;
}
+extern UniValue abortrescan(const JSONRPCRequest& request); // in rpcdump.cpp
extern UniValue dumpprivkey(const JSONRPCRequest& request); // in rpcdump.cpp
extern UniValue importprivkey(const JSONRPCRequest& request);
extern UniValue importaddress(const JSONRPCRequest& request);
@@ -2930,6 +2934,7 @@ static const CRPCCommand commands[] =
{ "rawtransactions", "fundrawtransaction", &fundrawtransaction, false, {"hexstring","options"} },
{ "hidden", "resendwallettransactions", &resendwallettransactions, true, {} },
{ "wallet", "abandontransaction", &abandontransaction, false, {"txid"} },
+ { "wallet", "abortrescan", &abortrescan, false, {} },
{ "wallet", "addmultisigaddress", &addmultisigaddress, true, {"nrequired","keys","account"} },
{ "wallet", "addwitnessaddress", &addwitnessaddress, true, {"address"} },
{ "wallet", "backupwallet", &backupwallet, true, {"destination"} },
@@ -2962,7 +2967,7 @@ static const CRPCCommand commands[] =
{ "wallet", "listreceivedbyaddress", &listreceivedbyaddress, false, {"minconf","include_empty","include_watchonly"} },
{ "wallet", "listsinceblock", &listsinceblock, false, {"blockhash","target_confirmations","include_watchonly"} },
{ "wallet", "listtransactions", &listtransactions, false, {"account","count","skip","include_watchonly"} },
- { "wallet", "listunspent", &listunspent, false, {"minconf","maxconf","addresses","include_unsafe"} },
+ { "wallet", "listunspent", &listunspent, false, {"minconf","maxconf","addresses","include_unsafe","query_options"} },
{ "wallet", "lockunspent", &lockunspent, true, {"unlock","transactions"} },
{ "wallet", "move", &movecmd, false, {"fromaccount","toaccount","amount","minconf","comment"} },
{ "wallet", "sendfrom", &sendfrom, false, {"fromaccount","toaddress","amount","minconf","comment","comment_to"} },