Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/rpcwallet.cpp
Show First 20 Lines • Show All 593 Lines • ▼ Show 20 Lines | static UniValue sendtoaddress(const Config &config, | ||||
// Amount | // Amount | ||||
Amount nAmount = AmountFromValue(request.params[1]); | Amount nAmount = AmountFromValue(request.params[1]); | ||||
if (nAmount <= Amount::zero()) { | if (nAmount <= Amount::zero()) { | ||||
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send"); | throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send"); | ||||
} | } | ||||
// Wallet comments | // Wallet comments | ||||
mapValue_t mapValue; | mapValue_t mapValue; | ||||
if (request.params.size() > 2 && !request.params[2].isNull() && | if (!request.params[2].isNull() && !request.params[2].get_str().empty()) { | ||||
!request.params[2].get_str().empty()) { | |||||
mapValue["comment"] = request.params[2].get_str(); | mapValue["comment"] = request.params[2].get_str(); | ||||
} | } | ||||
if (request.params.size() > 3 && !request.params[3].isNull() && | if (!request.params[3].isNull() && !request.params[3].get_str().empty()) { | ||||
!request.params[3].get_str().empty()) { | |||||
mapValue["to"] = request.params[3].get_str(); | mapValue["to"] = request.params[3].get_str(); | ||||
} | } | ||||
bool fSubtractFeeFromAmount = false; | bool fSubtractFeeFromAmount = false; | ||||
if (request.params.size() > 4) { | if (!request.params[4].isNull()) { | ||||
fSubtractFeeFromAmount = request.params[4].get_bool(); | fSubtractFeeFromAmount = request.params[4].get_bool(); | ||||
} | } | ||||
EnsureWalletIsUnlocked(pwallet); | EnsureWalletIsUnlocked(pwallet); | ||||
CTransactionRef tx = | CTransactionRef tx = | ||||
SendMoney(pwallet, dest, nAmount, fSubtractFeeFromAmount, | SendMoney(pwallet, dest, nAmount, fSubtractFeeFromAmount, | ||||
std::move(mapValue), {} /* fromAccount */); | std::move(mapValue), {} /* fromAccount */); | ||||
▲ Show 20 Lines • Show All 369 Lines • ▼ Show 20 Lines | static UniValue getbalance(const Config &config, | ||||
} | } | ||||
// Make sure the results are valid at least up to the most recent block | // Make sure the results are valid at least up to the most recent block | ||||
// the user could have gotten from another RPC command prior to now | // the user could have gotten from another RPC command prior to now | ||||
pwallet->BlockUntilSyncedToCurrentChain(); | pwallet->BlockUntilSyncedToCurrentChain(); | ||||
LOCK2(cs_main, pwallet->cs_wallet); | LOCK2(cs_main, pwallet->cs_wallet); | ||||
if (request.params.size() == 0) { | const UniValue &account_value = request.params[0]; | ||||
const UniValue &minconf = request.params[1]; | |||||
const UniValue &include_watchonly = request.params[2]; | |||||
if (account_value.isNull()) { | |||||
if (!minconf.isNull()) { | |||||
throw JSONRPCError(RPC_INVALID_PARAMETER, | |||||
"getbalance minconf option is only currently " | |||||
"supported if an account is specified"); | |||||
} | |||||
if (!include_watchonly.isNull()) { | |||||
throw JSONRPCError( | |||||
RPC_INVALID_PARAMETER, | |||||
"getbalance include_watchonly option is only currently " | |||||
"supported if an account is specified"); | |||||
} | |||||
return ValueFromAmount(pwallet->GetBalance()); | return ValueFromAmount(pwallet->GetBalance()); | ||||
} | } | ||||
const std::string &account_param = request.params[0].get_str(); | const std::string &account_param = account_value.get_str(); | ||||
const std::string *account = | const std::string *account = | ||||
account_param != "*" ? &account_param : nullptr; | account_param != "*" ? &account_param : nullptr; | ||||
int nMinDepth = 1; | int nMinDepth = 1; | ||||
if (!request.params[1].isNull()) { | if (!minconf.isNull()) { | ||||
nMinDepth = request.params[1].get_int(); | nMinDepth = minconf.get_int(); | ||||
} | } | ||||
isminefilter filter = ISMINE_SPENDABLE; | isminefilter filter = ISMINE_SPENDABLE; | ||||
if (!request.params[2].isNull() && request.params[2].get_bool()) { | if (!include_watchonly.isNull() && include_watchonly.get_bool()) { | ||||
filter = filter | ISMINE_WATCH_ONLY; | filter = filter | ISMINE_WATCH_ONLY; | ||||
} | } | ||||
return ValueFromAmount( | return ValueFromAmount( | ||||
pwallet->GetLegacyBalance(filter, nMinDepth, account)); | pwallet->GetLegacyBalance(filter, nMinDepth, account)); | ||||
} | } | ||||
static UniValue getunconfirmedbalance(const Config &config, | static UniValue getunconfirmedbalance(const Config &config, | ||||
▲ Show 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | static UniValue movecmd(const Config &config, const JSONRPCRequest &request) { | ||||
LOCK2(cs_main, pwallet->cs_wallet); | LOCK2(cs_main, pwallet->cs_wallet); | ||||
std::string strFrom = LabelFromValue(request.params[0]); | std::string strFrom = LabelFromValue(request.params[0]); | ||||
std::string strTo = LabelFromValue(request.params[1]); | std::string strTo = LabelFromValue(request.params[1]); | ||||
Amount nAmount = AmountFromValue(request.params[2]); | Amount nAmount = AmountFromValue(request.params[2]); | ||||
if (nAmount <= Amount::zero()) { | if (nAmount <= Amount::zero()) { | ||||
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send"); | throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send"); | ||||
} | } | ||||
if (request.params.size() > 3) { | if (!request.params[3].isNull()) { | ||||
// Unused parameter, used to be nMinDepth, keep type-checking it though. | // Unused parameter, used to be nMinDepth, keep type-checking it though. | ||||
(void)request.params[3].get_int(); | (void)request.params[3].get_int(); | ||||
} | } | ||||
std::string strComment; | std::string strComment; | ||||
if (request.params.size() > 4) { | if (!request.params[4].isNull()) { | ||||
strComment = request.params[4].get_str(); | strComment = request.params[4].get_str(); | ||||
} | } | ||||
if (!pwallet->AccountMove(strFrom, strTo, nAmount, strComment)) { | if (!pwallet->AccountMove(strFrom, strTo, nAmount, strComment)) { | ||||
throw JSONRPCError(RPC_DATABASE_ERROR, "database error"); | throw JSONRPCError(RPC_DATABASE_ERROR, "database error"); | ||||
} | } | ||||
return true; | return true; | ||||
▲ Show 20 Lines • Show All 78 Lines • ▼ Show 20 Lines | if (!IsValidDestination(dest)) { | ||||
"Invalid Bitcoin address"); | "Invalid Bitcoin address"); | ||||
} | } | ||||
Amount nAmount = AmountFromValue(request.params[2]); | Amount nAmount = AmountFromValue(request.params[2]); | ||||
if (nAmount <= Amount::zero()) { | if (nAmount <= Amount::zero()) { | ||||
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send"); | throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send"); | ||||
} | } | ||||
int nMinDepth = 1; | int nMinDepth = 1; | ||||
if (request.params.size() > 3) { | if (!request.params[3].isNull()) { | ||||
nMinDepth = request.params[3].get_int(); | nMinDepth = request.params[3].get_int(); | ||||
} | } | ||||
mapValue_t mapValue; | mapValue_t mapValue; | ||||
if (request.params.size() > 4 && !request.params[4].isNull() && | if (!request.params[4].isNull() && !request.params[4].get_str().empty()) { | ||||
!request.params[4].get_str().empty()) { | |||||
mapValue["comment"] = request.params[4].get_str(); | mapValue["comment"] = request.params[4].get_str(); | ||||
} | } | ||||
if (request.params.size() > 5 && !request.params[5].isNull() && | if (!request.params[5].isNull() && !request.params[5].get_str().empty()) { | ||||
!request.params[5].get_str().empty()) { | |||||
mapValue["to"] = request.params[5].get_str(); | mapValue["to"] = request.params[5].get_str(); | ||||
} | } | ||||
EnsureWalletIsUnlocked(pwallet); | EnsureWalletIsUnlocked(pwallet); | ||||
// Check funds | // Check funds | ||||
Amount nBalance = | Amount nBalance = | ||||
pwallet->GetLegacyBalance(ISMINE_SPENDABLE, nMinDepth, &label); | pwallet->GetLegacyBalance(ISMINE_SPENDABLE, nMinDepth, &label); | ||||
▲ Show 20 Lines • Show All 103 Lines • ▼ Show 20 Lines | static UniValue sendmany(const Config &config, const JSONRPCRequest &request) { | ||||
std::string strAccount = LabelFromValue(request.params[0]); | std::string strAccount = LabelFromValue(request.params[0]); | ||||
UniValue sendTo = request.params[1].get_obj(); | UniValue sendTo = request.params[1].get_obj(); | ||||
int nMinDepth = 1; | int nMinDepth = 1; | ||||
if (!request.params[2].isNull()) { | if (!request.params[2].isNull()) { | ||||
nMinDepth = request.params[2].get_int(); | nMinDepth = request.params[2].get_int(); | ||||
} | } | ||||
mapValue_t mapValue; | mapValue_t mapValue; | ||||
if (request.params.size() > 3 && !request.params[3].isNull() && | if (!request.params[3].isNull() && !request.params[3].get_str().empty()) { | ||||
!request.params[3].get_str().empty()) { | |||||
mapValue["comment"] = request.params[3].get_str(); | mapValue["comment"] = request.params[3].get_str(); | ||||
} | } | ||||
UniValue subtractFeeFromAmount(UniValue::VARR); | UniValue subtractFeeFromAmount(UniValue::VARR); | ||||
if (request.params.size() > 4) { | if (!request.params[4].isNull()) { | ||||
subtractFeeFromAmount = request.params[4].get_array(); | subtractFeeFromAmount = request.params[4].get_array(); | ||||
} | } | ||||
std::set<CTxDestination> destinations; | std::set<CTxDestination> destinations; | ||||
std::vector<CRecipient> vecSend; | std::vector<CRecipient> vecSend; | ||||
Amount totalAmount = Amount::zero(); | Amount totalAmount = Amount::zero(); | ||||
std::vector<std::string> keys = sendTo.getKeys(); | std::vector<std::string> keys = sendTo.getKeys(); | ||||
▲ Show 20 Lines • Show All 794 Lines • ▼ Show 20 Lines | static UniValue listaccounts(const Config &config, | ||||
// Make sure the results are valid at least up to the most recent block | // Make sure the results are valid at least up to the most recent block | ||||
// the user could have gotten from another RPC command prior to now | // the user could have gotten from another RPC command prior to now | ||||
pwallet->BlockUntilSyncedToCurrentChain(); | pwallet->BlockUntilSyncedToCurrentChain(); | ||||
LOCK2(cs_main, pwallet->cs_wallet); | LOCK2(cs_main, pwallet->cs_wallet); | ||||
int nMinDepth = 1; | int nMinDepth = 1; | ||||
if (request.params.size() > 0) { | if (!request.params[0].isNull()) { | ||||
nMinDepth = request.params[0].get_int(); | nMinDepth = request.params[0].get_int(); | ||||
} | } | ||||
isminefilter includeWatchonly = ISMINE_SPENDABLE; | isminefilter includeWatchonly = ISMINE_SPENDABLE; | ||||
if (request.params.size() > 1 && request.params[1].get_bool()) { | if (!request.params[1].isNull() && request.params[1].get_bool()) { | ||||
includeWatchonly = includeWatchonly | ISMINE_WATCH_ONLY; | includeWatchonly = includeWatchonly | ISMINE_WATCH_ONLY; | ||||
} | } | ||||
std::map<std::string, Amount> mapAccountBalances; | std::map<std::string, Amount> mapAccountBalances; | ||||
for (const std::pair<const CTxDestination, CAddressBookData> &entry : | for (const std::pair<const CTxDestination, CAddressBookData> &entry : | ||||
pwallet->mapAddressBook) { | pwallet->mapAddressBook) { | ||||
// This address belongs to me | // This address belongs to me | ||||
if (IsMine(*pwallet, entry.first) & includeWatchonly) { | if (IsMine(*pwallet, entry.first) & includeWatchonly) { | ||||
▲ Show 20 Lines • Show All 881 Lines • ▼ Show 20 Lines | static UniValue lockunspent(const Config &config, | ||||
} | } | ||||
// Make sure the results are valid at least up to the most recent block | // Make sure the results are valid at least up to the most recent block | ||||
// the user could have gotten from another RPC command prior to now | // the user could have gotten from another RPC command prior to now | ||||
pwallet->BlockUntilSyncedToCurrentChain(); | pwallet->BlockUntilSyncedToCurrentChain(); | ||||
LOCK2(cs_main, pwallet->cs_wallet); | LOCK2(cs_main, pwallet->cs_wallet); | ||||
if (request.params.size() == 1) { | RPCTypeCheckArgument(request.params[0], UniValue::VBOOL); | ||||
RPCTypeCheck(request.params, {UniValue::VBOOL}); | |||||
} else { | |||||
RPCTypeCheck(request.params, {UniValue::VBOOL, UniValue::VARR}); | |||||
} | |||||
bool fUnlock = request.params[0].get_bool(); | bool fUnlock = request.params[0].get_bool(); | ||||
if (request.params.size() == 1) { | if (request.params[1].isNull()) { | ||||
if (fUnlock) { | if (fUnlock) { | ||||
pwallet->UnlockAllCoins(); | pwallet->UnlockAllCoins(); | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
RPCTypeCheckArgument(request.params[1], UniValue::VARR); | |||||
const UniValue &output_params = request.params[1]; | const UniValue &output_params = request.params[1]; | ||||
// Create and validate the COutPoints first. | // Create and validate the COutPoints first. | ||||
std::vector<COutPoint> outputs; | std::vector<COutPoint> outputs; | ||||
outputs.reserve(output_params.size()); | outputs.reserve(output_params.size()); | ||||
for (size_t idx = 0; idx < output_params.size(); idx++) { | for (size_t idx = 0; idx < output_params.size(); idx++) { | ||||
▲ Show 20 Lines • Show All 543 Lines • ▼ Show 20 Lines | if (request.fHelp || request.params.size() > 5) { | ||||
"listunspent", | "listunspent", | ||||
"6 9999999 '[]' true '{ \"minimumAmount\": 0.005 }'") + | "6 9999999 '[]' true '{ \"minimumAmount\": 0.005 }'") + | ||||
HelpExampleRpc( | HelpExampleRpc( | ||||
"listunspent", | "listunspent", | ||||
"6, 9999999, [] , true, { \"minimumAmount\": 0.005 } ")); | "6, 9999999, [] , true, { \"minimumAmount\": 0.005 } ")); | ||||
} | } | ||||
int nMinDepth = 1; | int nMinDepth = 1; | ||||
if (request.params.size() > 0 && !request.params[0].isNull()) { | if (!request.params[0].isNull()) { | ||||
RPCTypeCheckArgument(request.params[0], UniValue::VNUM); | RPCTypeCheckArgument(request.params[0], UniValue::VNUM); | ||||
nMinDepth = request.params[0].get_int(); | nMinDepth = request.params[0].get_int(); | ||||
} | } | ||||
int nMaxDepth = 9999999; | int nMaxDepth = 9999999; | ||||
if (request.params.size() > 1 && !request.params[1].isNull()) { | if (!request.params[1].isNull()) { | ||||
RPCTypeCheckArgument(request.params[1], UniValue::VNUM); | RPCTypeCheckArgument(request.params[1], UniValue::VNUM); | ||||
nMaxDepth = request.params[1].get_int(); | nMaxDepth = request.params[1].get_int(); | ||||
} | } | ||||
std::set<CTxDestination> destinations; | std::set<CTxDestination> destinations; | ||||
if (request.params.size() > 2 && !request.params[2].isNull()) { | if (!request.params[2].isNull()) { | ||||
RPCTypeCheckArgument(request.params[2], UniValue::VARR); | RPCTypeCheckArgument(request.params[2], UniValue::VARR); | ||||
UniValue inputs = request.params[2].get_array(); | UniValue inputs = request.params[2].get_array(); | ||||
for (size_t idx = 0; idx < inputs.size(); idx++) { | for (size_t idx = 0; idx < inputs.size(); idx++) { | ||||
const UniValue &input = inputs[idx]; | const UniValue &input = inputs[idx]; | ||||
CTxDestination dest = | CTxDestination dest = | ||||
DecodeDestination(input.get_str(), config.GetChainParams()); | DecodeDestination(input.get_str(), config.GetChainParams()); | ||||
if (!IsValidDestination(dest)) { | if (!IsValidDestination(dest)) { | ||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, | throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, | ||||
std::string("Invalid Bitcoin address: ") + | std::string("Invalid Bitcoin address: ") + | ||||
input.get_str()); | input.get_str()); | ||||
} | } | ||||
if (!destinations.insert(dest).second) { | if (!destinations.insert(dest).second) { | ||||
throw JSONRPCError( | throw JSONRPCError( | ||||
RPC_INVALID_PARAMETER, | RPC_INVALID_PARAMETER, | ||||
std::string("Invalid parameter, duplicated address: ") + | std::string("Invalid parameter, duplicated address: ") + | ||||
input.get_str()); | input.get_str()); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
bool include_unsafe = true; | bool include_unsafe = true; | ||||
if (request.params.size() > 3 && !request.params[3].isNull()) { | if (!request.params[3].isNull()) { | ||||
RPCTypeCheckArgument(request.params[3], UniValue::VBOOL); | RPCTypeCheckArgument(request.params[3], UniValue::VBOOL); | ||||
include_unsafe = request.params[3].get_bool(); | include_unsafe = request.params[3].get_bool(); | ||||
} | } | ||||
Amount nMinimumAmount = Amount::zero(); | Amount nMinimumAmount = Amount::zero(); | ||||
Amount nMaximumAmount = MAX_MONEY; | Amount nMaximumAmount = MAX_MONEY; | ||||
Amount nMinimumSumAmount = MAX_MONEY; | Amount nMinimumSumAmount = MAX_MONEY; | ||||
uint64_t nMaximumCount = 0; | uint64_t nMaximumCount = 0; | ||||
▲ Show 20 Lines • Show All 410 Lines • ▼ Show 20 Lines | if (request.fHelp || request.params.size() < 1 || | ||||
"[ blockhashes ] (array) hashes of blocks generated\n" | "[ blockhashes ] (array) hashes of blocks generated\n" | ||||
"\nExamples:\n" | "\nExamples:\n" | ||||
"\nGenerate 11 blocks\n" + | "\nGenerate 11 blocks\n" + | ||||
HelpExampleCli("generate", "11")); | HelpExampleCli("generate", "11")); | ||||
} | } | ||||
int num_generate = request.params[0].get_int(); | int num_generate = request.params[0].get_int(); | ||||
uint64_t max_tries = 1000000; | uint64_t max_tries = 1000000; | ||||
if (request.params.size() > 1 && !request.params[1].isNull()) { | if (!request.params[1].isNull()) { | ||||
max_tries = request.params[1].get_int(); | max_tries = request.params[1].get_int(); | ||||
} | } | ||||
std::shared_ptr<CReserveScript> coinbase_script; | std::shared_ptr<CReserveScript> coinbase_script; | ||||
pwallet->GetScriptForMining(coinbase_script); | pwallet->GetScriptForMining(coinbase_script); | ||||
// If the keypool is exhausted, no script is returned at all. Catch this. | // If the keypool is exhausted, no script is returned at all. Catch this. | ||||
if (!coinbase_script) { | if (!coinbase_script) { | ||||
▲ Show 20 Lines • Show All 489 Lines • Show Last 20 Lines |