Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/rpcwallet.cpp
Show First 20 Lines • Show All 155 Lines • ▼ Show 20 Lines | LegacyScriptPubKeyMan &EnsureLegacyScriptPubKeyMan(CWallet &wallet, | ||||
} | } | ||||
if (!spk_man) { | if (!spk_man) { | ||||
throw JSONRPCError(RPC_WALLET_ERROR, | throw JSONRPCError(RPC_WALLET_ERROR, | ||||
"This type of wallet does not support this command"); | "This type of wallet does not support this command"); | ||||
} | } | ||||
return *spk_man; | return *spk_man; | ||||
} | } | ||||
static void WalletTxToJSON(interfaces::Chain &chain, | static void WalletTxToJSON(interfaces::Chain &chain, const CWalletTx &wtx, | ||||
interfaces::Chain::Lock &locked_chain, | UniValue &entry) { | ||||
const CWalletTx &wtx, UniValue &entry) { | |||||
int confirms = wtx.GetDepthInMainChain(); | int confirms = wtx.GetDepthInMainChain(); | ||||
entry.pushKV("confirmations", confirms); | entry.pushKV("confirmations", confirms); | ||||
if (wtx.IsCoinBase()) { | if (wtx.IsCoinBase()) { | ||||
entry.pushKV("generated", true); | entry.pushKV("generated", true); | ||||
} | } | ||||
if (confirms > 0) { | if (confirms > 0) { | ||||
entry.pushKV("blockhash", wtx.m_confirm.hashBlock.GetHex()); | entry.pushKV("blockhash", wtx.m_confirm.hashBlock.GetHex()); | ||||
entry.pushKV("blockheight", wtx.m_confirm.block_height); | entry.pushKV("blockheight", wtx.m_confirm.block_height); | ||||
▲ Show 20 Lines • Show All 283 Lines • ▼ Show 20 Lines | RPCHelpMan{ | ||||
"outpost\"")}, | "outpost\"")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
// 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(); | ||||
auto locked_chain = pwallet->chain().lock(); | |||||
LOCK(pwallet->cs_wallet); | LOCK(pwallet->cs_wallet); | ||||
CTxDestination dest = | CTxDestination dest = | ||||
DecodeDestination(request.params[0].get_str(), wallet->chainParams); | DecodeDestination(request.params[0].get_str(), wallet->chainParams); | ||||
if (!IsValidDestination(dest)) { | if (!IsValidDestination(dest)) { | ||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); | throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | RPCHelpMan{ | ||||
HelpExampleRpc("listaddressgroupings", "")}, | HelpExampleRpc("listaddressgroupings", "")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
// 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(); | ||||
auto locked_chain = pwallet->chain().lock(); | |||||
LOCK(pwallet->cs_wallet); | LOCK(pwallet->cs_wallet); | ||||
UniValue jsonGroupings(UniValue::VARR); | UniValue jsonGroupings(UniValue::VARR); | ||||
std::map<CTxDestination, Amount> balances = | std::map<CTxDestination, Amount> balances = pwallet->GetAddressBalances(); | ||||
pwallet->GetAddressBalances(*locked_chain); | |||||
for (const std::set<CTxDestination> &grouping : | for (const std::set<CTxDestination> &grouping : | ||||
pwallet->GetAddressGroupings()) { | pwallet->GetAddressGroupings()) { | ||||
UniValue jsonGrouping(UniValue::VARR); | UniValue jsonGrouping(UniValue::VARR); | ||||
for (const CTxDestination &address : grouping) { | for (const CTxDestination &address : grouping) { | ||||
UniValue addressInfo(UniValue::VARR); | UniValue addressInfo(UniValue::VARR); | ||||
addressInfo.push_back(EncodeDestination(address, config)); | addressInfo.push_back(EncodeDestination(address, config)); | ||||
addressInfo.push_back(ValueFromAmount(balances[address])); | addressInfo.push_back(ValueFromAmount(balances[address])); | ||||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | RPCHelpMan{ | ||||
"\"signature\" \"my message\"") + | "\"signature\" \"my message\"") + | ||||
"\nAs a JSON-RPC call\n" + | "\nAs a JSON-RPC call\n" + | ||||
HelpExampleRpc( | HelpExampleRpc( | ||||
"signmessage", | "signmessage", | ||||
"\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"my message\"")}, | "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"my message\"")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
auto locked_chain = pwallet->chain().lock(); | |||||
LOCK(pwallet->cs_wallet); | LOCK(pwallet->cs_wallet); | ||||
EnsureWalletIsUnlocked(pwallet); | EnsureWalletIsUnlocked(pwallet); | ||||
std::string strAddress = request.params[0].get_str(); | std::string strAddress = request.params[0].get_str(); | ||||
std::string strMessage = request.params[1].get_str(); | std::string strMessage = request.params[1].get_str(); | ||||
CTxDestination dest = DecodeDestination(strAddress, wallet->chainParams); | CTxDestination dest = DecodeDestination(strAddress, wallet->chainParams); | ||||
▲ Show 20 Lines • Show All 122 Lines • ▼ Show 20 Lines | RPCHelpMan{ | ||||
"\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", 6")}, | "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", 6")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
// 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(); | ||||
auto locked_chain = pwallet->chain().lock(); | |||||
LOCK(pwallet->cs_wallet); | LOCK(pwallet->cs_wallet); | ||||
return ValueFromAmount(GetReceived(*pwallet, request.params, | return ValueFromAmount(GetReceived(*pwallet, request.params, | ||||
/* by_label */ false)); | /* by_label */ false)); | ||||
} | } | ||||
static UniValue getreceivedbylabel(const Config &config, | static UniValue getreceivedbylabel(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
Show All 28 Lines | RPCHelpMan{ | ||||
HelpExampleRpc("getreceivedbylabel", "\"tabby\", 6")}, | HelpExampleRpc("getreceivedbylabel", "\"tabby\", 6")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
// 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(); | ||||
auto locked_chain = pwallet->chain().lock(); | |||||
LOCK(pwallet->cs_wallet); | LOCK(pwallet->cs_wallet); | ||||
return ValueFromAmount(GetReceived(*pwallet, request.params, | return ValueFromAmount(GetReceived(*pwallet, request.params, | ||||
/* by_label */ true)); | /* by_label */ true)); | ||||
} | } | ||||
static UniValue getbalance(const Config &config, | static UniValue getbalance(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
Show All 37 Lines | RPCHelpMan{ | ||||
HelpExampleRpc("getbalance", "\"*\", 6")}, | HelpExampleRpc("getbalance", "\"*\", 6")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
// 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(); | ||||
auto locked_chain = pwallet->chain().lock(); | |||||
LOCK(pwallet->cs_wallet); | LOCK(pwallet->cs_wallet); | ||||
const UniValue &dummy_value = request.params[0]; | const UniValue &dummy_value = request.params[0]; | ||||
if (!dummy_value.isNull() && dummy_value.get_str() != "*") { | if (!dummy_value.isNull() && dummy_value.get_str() != "*") { | ||||
throw JSONRPCError( | throw JSONRPCError( | ||||
RPC_METHOD_DEPRECATED, | RPC_METHOD_DEPRECATED, | ||||
"dummy first argument must be excluded or set to \"*\"."); | "dummy first argument must be excluded or set to \"*\"."); | ||||
} | } | ||||
Show All 31 Lines | RPCHelpMan{ | ||||
RPCExamples{""}, | RPCExamples{""}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
// 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(); | ||||
auto locked_chain = pwallet->chain().lock(); | |||||
LOCK(pwallet->cs_wallet); | LOCK(pwallet->cs_wallet); | ||||
return ValueFromAmount(pwallet->GetBalance().m_mine_untrusted_pending); | return ValueFromAmount(pwallet->GetBalance().m_mine_untrusted_pending); | ||||
} | } | ||||
static UniValue sendmany(const Config &config, const JSONRPCRequest &request) { | static UniValue sendmany(const Config &config, const JSONRPCRequest &request) { | ||||
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); | std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); | ||||
CWallet *const pwallet = wallet.get(); | CWallet *const pwallet = wallet.get(); | ||||
▲ Show 20 Lines • Show All 78 Lines • ▼ Show 20 Lines | RPCHelpMan{ | ||||
" 6, \"testing\"")}, | " 6, \"testing\"")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
// 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(); | ||||
auto locked_chain = pwallet->chain().lock(); | |||||
LOCK(pwallet->cs_wallet); | LOCK(pwallet->cs_wallet); | ||||
if (!request.params[0].isNull() && !request.params[0].get_str().empty()) { | if (!request.params[0].isNull() && !request.params[0].get_str().empty()) { | ||||
throw JSONRPCError(RPC_INVALID_PARAMETER, | throw JSONRPCError(RPC_INVALID_PARAMETER, | ||||
"Dummy value must be set to \"\""); | "Dummy value must be set to \"\""); | ||||
} | } | ||||
UniValue sendTo = request.params[1].get_obj(); | UniValue sendTo = request.params[1].get_obj(); | ||||
▲ Show 20 Lines • Show All 113 Lines • ▼ Show 20 Lines | RPCHelpMan{ | ||||
"2, " | "2, " | ||||
"\"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\"," | "\"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\"," | ||||
"\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"")}, | "\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
LegacyScriptPubKeyMan &spk_man = EnsureLegacyScriptPubKeyMan(*pwallet); | LegacyScriptPubKeyMan &spk_man = EnsureLegacyScriptPubKeyMan(*pwallet); | ||||
auto locked_chain = pwallet->chain().lock(); | |||||
LOCK2(pwallet->cs_wallet, spk_man.cs_KeyStore); | LOCK2(pwallet->cs_wallet, spk_man.cs_KeyStore); | ||||
std::string label; | std::string label; | ||||
if (!request.params[2].isNull()) { | if (!request.params[2].isNull()) { | ||||
label = LabelFromValue(request.params[2]); | label = LabelFromValue(request.params[2]); | ||||
} | } | ||||
int required = request.params[0].get_int(); | int required = request.params[0].get_int(); | ||||
Show All 29 Lines | |||||
struct tallyitem { | struct tallyitem { | ||||
Amount nAmount{Amount::zero()}; | Amount nAmount{Amount::zero()}; | ||||
int nConf{std::numeric_limits<int>::max()}; | int nConf{std::numeric_limits<int>::max()}; | ||||
std::vector<uint256> txids; | std::vector<uint256> txids; | ||||
bool fIsWatchonly{false}; | bool fIsWatchonly{false}; | ||||
tallyitem() {} | tallyitem() {} | ||||
}; | }; | ||||
static UniValue | static UniValue ListReceived(const Config &config, CWallet *const pwallet, | ||||
ListReceived(const Config &config, interfaces::Chain::Lock &locked_chain, | const UniValue ¶ms, bool by_label) | ||||
CWallet *const pwallet, const UniValue ¶ms, bool by_label) | |||||
EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet) { | EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet) { | ||||
// Minimum confirmations | // Minimum confirmations | ||||
int nMinDepth = 1; | int nMinDepth = 1; | ||||
if (!params[0].isNull()) { | if (!params[0].isNull()) { | ||||
nMinDepth = params[0].get_int(); | nMinDepth = params[0].get_int(); | ||||
} | } | ||||
// Whether to include empty labels | // Whether to include empty labels | ||||
▲ Show 20 Lines • Show All 202 Lines • ▼ Show 20 Lines | RPCHelpMan{ | ||||
"6, true, true, \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\"")}, | "6, true, true, \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\"")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
// 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(); | ||||
auto locked_chain = pwallet->chain().lock(); | |||||
LOCK(pwallet->cs_wallet); | LOCK(pwallet->cs_wallet); | ||||
return ListReceived(config, *locked_chain, pwallet, request.params, false); | return ListReceived(config, pwallet, request.params, false); | ||||
} | } | ||||
static UniValue listreceivedbylabel(const Config &config, | static UniValue listreceivedbylabel(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); | std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); | ||||
CWallet *const pwallet = wallet.get(); | CWallet *const pwallet = wallet.get(); | ||||
if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { | if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { | ||||
Show All 31 Lines | RPCHelpMan{ | ||||
HelpExampleRpc("listreceivedbylabel", "6, true, true")}, | HelpExampleRpc("listreceivedbylabel", "6, true, true")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
// 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(); | ||||
auto locked_chain = pwallet->chain().lock(); | |||||
LOCK(pwallet->cs_wallet); | LOCK(pwallet->cs_wallet); | ||||
return ListReceived(config, *locked_chain, pwallet, request.params, true); | return ListReceived(config, pwallet, request.params, true); | ||||
} | } | ||||
static void MaybePushAddress(UniValue &entry, const CTxDestination &dest) { | static void MaybePushAddress(UniValue &entry, const CTxDestination &dest) { | ||||
if (IsValidDestination(dest)) { | if (IsValidDestination(dest)) { | ||||
entry.pushKV("address", EncodeDestination(dest, GetConfig())); | entry.pushKV("address", EncodeDestination(dest, GetConfig())); | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* List transactions based on the given criteria. | * List transactions based on the given criteria. | ||||
* | * | ||||
* @param pwallet The wallet. | * @param pwallet The wallet. | ||||
* @param wtx The wallet transaction. | * @param wtx The wallet transaction. | ||||
* @param nMinDepth The minimum confirmation depth. | * @param nMinDepth The minimum confirmation depth. | ||||
* @param fLong Whether to include the JSON version of the | * @param fLong Whether to include the JSON version of the | ||||
* transaction. | * transaction. | ||||
* @param ret The UniValue into which the result is stored. | * @param ret The UniValue into which the result is stored. | ||||
* @param filter_ismine The "is mine" filter flags. | * @param filter_ismine The "is mine" filter flags. | ||||
* @param filter_label Optional label string to filter incoming transactions. | * @param filter_label Optional label string to filter incoming transactions. | ||||
*/ | */ | ||||
static void ListTransactions(interfaces::Chain::Lock &locked_chain, | static void ListTransactions(CWallet *const pwallet, const CWalletTx &wtx, | ||||
CWallet *const pwallet, const CWalletTx &wtx, | |||||
int nMinDepth, bool fLong, UniValue &ret, | int nMinDepth, bool fLong, UniValue &ret, | ||||
const isminefilter &filter_ismine, | const isminefilter &filter_ismine, | ||||
const std::string *filter_label) | const std::string *filter_label) | ||||
EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet) { | EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet) { | ||||
Amount nFee; | Amount nFee; | ||||
std::list<COutputEntry> listReceived; | std::list<COutputEntry> listReceived; | ||||
std::list<COutputEntry> listSent; | std::list<COutputEntry> listSent; | ||||
Show All 15 Lines | if (!filter_label) { | ||||
const auto *address_book_entry = | const auto *address_book_entry = | ||||
pwallet->FindAddressBookEntry(s.destination); | pwallet->FindAddressBookEntry(s.destination); | ||||
if (address_book_entry) { | if (address_book_entry) { | ||||
entry.pushKV("label", address_book_entry->GetLabel()); | entry.pushKV("label", address_book_entry->GetLabel()); | ||||
} | } | ||||
entry.pushKV("vout", s.vout); | entry.pushKV("vout", s.vout); | ||||
entry.pushKV("fee", ValueFromAmount(-1 * nFee)); | entry.pushKV("fee", ValueFromAmount(-1 * nFee)); | ||||
if (fLong) { | if (fLong) { | ||||
WalletTxToJSON(pwallet->chain(), locked_chain, wtx, entry); | WalletTxToJSON(pwallet->chain(), wtx, entry); | ||||
} | } | ||||
entry.pushKV("abandoned", wtx.isAbandoned()); | entry.pushKV("abandoned", wtx.isAbandoned()); | ||||
ret.push_back(entry); | ret.push_back(entry); | ||||
} | } | ||||
} | } | ||||
// Received | // Received | ||||
if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth) { | if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth) { | ||||
Show All 25 Lines | if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth) { | ||||
entry.pushKV("category", "receive"); | entry.pushKV("category", "receive"); | ||||
} | } | ||||
entry.pushKV("amount", ValueFromAmount(r.amount)); | entry.pushKV("amount", ValueFromAmount(r.amount)); | ||||
if (address_book_entry) { | if (address_book_entry) { | ||||
entry.pushKV("label", label); | entry.pushKV("label", label); | ||||
} | } | ||||
entry.pushKV("vout", r.vout); | entry.pushKV("vout", r.vout); | ||||
if (fLong) { | if (fLong) { | ||||
WalletTxToJSON(pwallet->chain(), locked_chain, wtx, entry); | WalletTxToJSON(pwallet->chain(), wtx, entry); | ||||
} | } | ||||
ret.push_back(entry); | ret.push_back(entry); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
static const std::string TransactionDescriptionString() { | static const std::string TransactionDescriptionString() { | ||||
return " \"confirmations\": n, (numeric) The " | return " \"confirmations\": n, (numeric) The " | ||||
▲ Show 20 Lines • Show All 145 Lines • ▼ Show 20 Lines | if (nCount < 0) { | ||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative count"); | throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative count"); | ||||
} | } | ||||
if (nFrom < 0) { | if (nFrom < 0) { | ||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative from"); | throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative from"); | ||||
} | } | ||||
UniValue ret(UniValue::VARR); | UniValue ret(UniValue::VARR); | ||||
{ | { | ||||
auto locked_chain = pwallet->chain().lock(); | |||||
LOCK(pwallet->cs_wallet); | LOCK(pwallet->cs_wallet); | ||||
const CWallet::TxItems &txOrdered = pwallet->wtxOrdered; | const CWallet::TxItems &txOrdered = pwallet->wtxOrdered; | ||||
// iterate backwards until we have nCount items to return: | // iterate backwards until we have nCount items to return: | ||||
for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin(); | for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin(); | ||||
it != txOrdered.rend(); ++it) { | it != txOrdered.rend(); ++it) { | ||||
CWalletTx *const pwtx = (*it).second; | CWalletTx *const pwtx = (*it).second; | ||||
ListTransactions(*locked_chain, pwallet, *pwtx, 0, true, ret, | ListTransactions(pwallet, *pwtx, 0, true, ret, filter, | ||||
filter, filter_label); | filter_label); | ||||
if (int(ret.size()) >= (nCount + nFrom)) { | if (int(ret.size()) >= (nCount + nFrom)) { | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
// ret is newest to oldest | // ret is newest to oldest | ||||
▲ Show 20 Lines • Show All 111 Lines • ▼ Show 20 Lines | RPCHelpMan{ | ||||
"7d38571037cdb1a57f663ad\", 6")}, | "7d38571037cdb1a57f663ad\", 6")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
// 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(); | ||||
auto locked_chain = pwallet->chain().lock(); | |||||
LOCK(pwallet->cs_wallet); | LOCK(pwallet->cs_wallet); | ||||
// The way the 'height' is initialized is just a workaround for the gcc bug | // The way the 'height' is initialized is just a workaround for the gcc bug | ||||
// #47679 since version 4.6.0. Height of the specified block or the common | // #47679 since version 4.6.0. Height of the specified block or the common | ||||
// ancestor, if the block provided was in a deactivated chain. | // ancestor, if the block provided was in a deactivated chain. | ||||
Optional<int> height = MakeOptional(false, int()); | Optional<int> height = MakeOptional(false, int()); | ||||
// Height of the specified block, even if it's in a deactivated chain. | // Height of the specified block, even if it's in a deactivated chain. | ||||
Show All 32 Lines | static UniValue listsinceblock(const Config &config, | ||||
int depth = height ? pwallet->GetLastBlockHeight() + 1 - *height : -1; | int depth = height ? pwallet->GetLastBlockHeight() + 1 - *height : -1; | ||||
UniValue transactions(UniValue::VARR); | UniValue transactions(UniValue::VARR); | ||||
for (const std::pair<const TxId, CWalletTx> &pairWtx : pwallet->mapWallet) { | for (const std::pair<const TxId, CWalletTx> &pairWtx : pwallet->mapWallet) { | ||||
CWalletTx tx = pairWtx.second; | CWalletTx tx = pairWtx.second; | ||||
if (depth == -1 || tx.GetDepthInMainChain() < depth) { | if (depth == -1 || tx.GetDepthInMainChain() < depth) { | ||||
ListTransactions(*locked_chain, pwallet, tx, 0, true, transactions, | ListTransactions(pwallet, tx, 0, true, transactions, filter, | ||||
filter, nullptr /* filter_label */); | nullptr /* filter_label */); | ||||
} | } | ||||
} | } | ||||
// when a reorg'd block is requested, we also list any relevant transactions | // when a reorg'd block is requested, we also list any relevant transactions | ||||
// in the blocks of the chain that was detached | // in the blocks of the chain that was detached | ||||
UniValue removed(UniValue::VARR); | UniValue removed(UniValue::VARR); | ||||
while (include_removed && altheight && *altheight > *height) { | while (include_removed && altheight && *altheight > *height) { | ||||
CBlock block; | CBlock block; | ||||
if (!pwallet->chain().findBlock(blockId, FoundBlock().data(block)) || | if (!pwallet->chain().findBlock(blockId, FoundBlock().data(block)) || | ||||
block.IsNull()) { | block.IsNull()) { | ||||
throw JSONRPCError(RPC_INTERNAL_ERROR, | throw JSONRPCError(RPC_INTERNAL_ERROR, | ||||
"Can't read block from disk"); | "Can't read block from disk"); | ||||
} | } | ||||
for (const CTransactionRef &tx : block.vtx) { | for (const CTransactionRef &tx : block.vtx) { | ||||
auto it = pwallet->mapWallet.find(tx->GetId()); | auto it = pwallet->mapWallet.find(tx->GetId()); | ||||
if (it != pwallet->mapWallet.end()) { | if (it != pwallet->mapWallet.end()) { | ||||
// We want all transactions regardless of confirmation count to | // We want all transactions regardless of confirmation count to | ||||
// appear here, even negative confirmation ones, hence the big | // appear here, even negative confirmation ones, hence the big | ||||
// negative. | // negative. | ||||
ListTransactions(*locked_chain, pwallet, it->second, -100000000, | ListTransactions(pwallet, it->second, -100000000, true, removed, | ||||
true, removed, filter, | filter, nullptr /* filter_label */); | ||||
nullptr /* filter_label */); | |||||
} | } | ||||
} | } | ||||
blockId = block.hashPrevBlock; | blockId = block.hashPrevBlock; | ||||
--*altheight; | --*altheight; | ||||
} | } | ||||
BlockHash lastblock; | BlockHash lastblock; | ||||
CHECK_NONFATAL(pwallet->chain().findAncestorByHeight( | CHECK_NONFATAL(pwallet->chain().findAncestorByHeight( | ||||
▲ Show 20 Lines • Show All 108 Lines • ▼ Show 20 Lines | RPCHelpMan{ | ||||
"5cf302fc80e9d5fbf5d48d\"")}, | "5cf302fc80e9d5fbf5d48d\"")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
// 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(); | ||||
auto locked_chain = pwallet->chain().lock(); | |||||
LOCK(pwallet->cs_wallet); | LOCK(pwallet->cs_wallet); | ||||
TxId txid(ParseHashV(request.params[0], "txid")); | TxId txid(ParseHashV(request.params[0], "txid")); | ||||
isminefilter filter = ISMINE_SPENDABLE; | isminefilter filter = ISMINE_SPENDABLE; | ||||
if (ParseIncludeWatchonly(request.params[1], *pwallet)) { | if (ParseIncludeWatchonly(request.params[1], *pwallet)) { | ||||
filter |= ISMINE_WATCH_ONLY; | filter |= ISMINE_WATCH_ONLY; | ||||
} | } | ||||
Show All 15 Lines | static UniValue gettransaction(const Config &config, | ||||
Amount nFee = (wtx.IsFromMe(filter) ? wtx.tx->GetValueOut() - nDebit | Amount nFee = (wtx.IsFromMe(filter) ? wtx.tx->GetValueOut() - nDebit | ||||
: Amount::zero()); | : Amount::zero()); | ||||
entry.pushKV("amount", ValueFromAmount(nNet - nFee)); | entry.pushKV("amount", ValueFromAmount(nNet - nFee)); | ||||
if (wtx.IsFromMe(filter)) { | if (wtx.IsFromMe(filter)) { | ||||
entry.pushKV("fee", ValueFromAmount(nFee)); | entry.pushKV("fee", ValueFromAmount(nFee)); | ||||
} | } | ||||
WalletTxToJSON(pwallet->chain(), *locked_chain, wtx, entry); | WalletTxToJSON(pwallet->chain(), wtx, entry); | ||||
UniValue details(UniValue::VARR); | UniValue details(UniValue::VARR); | ||||
ListTransactions(*locked_chain, pwallet, wtx, 0, false, details, filter, | ListTransactions(pwallet, wtx, 0, false, details, filter, | ||||
nullptr /* filter_label */); | nullptr /* filter_label */); | ||||
entry.pushKV("details", details); | entry.pushKV("details", details); | ||||
std::string strHex = | std::string strHex = | ||||
EncodeHexTx(*wtx.tx, pwallet->chain().rpcSerializationFlags()); | EncodeHexTx(*wtx.tx, pwallet->chain().rpcSerializationFlags()); | ||||
entry.pushKV("hex", strHex); | entry.pushKV("hex", strHex); | ||||
if (verbose) { | if (verbose) { | ||||
Show All 37 Lines | RPCHelpMan{ | ||||
"5cf302fc80e9d5fbf5d48d\"")}, | "5cf302fc80e9d5fbf5d48d\"")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
// 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(); | ||||
auto locked_chain = pwallet->chain().lock(); | |||||
LOCK(pwallet->cs_wallet); | LOCK(pwallet->cs_wallet); | ||||
TxId txid(ParseHashV(request.params[0], "txid")); | TxId txid(ParseHashV(request.params[0], "txid")); | ||||
if (!pwallet->mapWallet.count(txid)) { | if (!pwallet->mapWallet.count(txid)) { | ||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, | throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, | ||||
"Invalid or non-wallet transaction id"); | "Invalid or non-wallet transaction id"); | ||||
} | } | ||||
Show All 28 Lines | RPCHelpMan{ | ||||
HelpExampleRpc("backupwallet", "\"backup.dat\"")}, | HelpExampleRpc("backupwallet", "\"backup.dat\"")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
// 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(); | ||||
auto locked_chain = pwallet->chain().lock(); | |||||
LOCK(pwallet->cs_wallet); | LOCK(pwallet->cs_wallet); | ||||
std::string strDest = request.params[0].get_str(); | std::string strDest = request.params[0].get_str(); | ||||
if (!pwallet->BackupWallet(strDest)) { | if (!pwallet->BackupWallet(strDest)) { | ||||
throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!"); | throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!"); | ||||
} | } | ||||
return NullUniValue; | return NullUniValue; | ||||
Show All 21 Lines | static UniValue keypoolrefill(const Config &config, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
if (pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) { | if (pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) { | ||||
throw JSONRPCError(RPC_WALLET_ERROR, | throw JSONRPCError(RPC_WALLET_ERROR, | ||||
"Error: Private keys are disabled for this wallet"); | "Error: Private keys are disabled for this wallet"); | ||||
} | } | ||||
auto locked_chain = pwallet->chain().lock(); | |||||
LOCK(pwallet->cs_wallet); | LOCK(pwallet->cs_wallet); | ||||
// 0 is interpreted by TopUpKeyPool() as the default keypool size given by | // 0 is interpreted by TopUpKeyPool() as the default keypool size given by | ||||
// -keypool | // -keypool | ||||
unsigned int kpSize = 0; | unsigned int kpSize = 0; | ||||
if (!request.params[0].isNull()) { | if (!request.params[0].isNull()) { | ||||
if (request.params[0].get_int() < 0) { | if (request.params[0].get_int() < 0) { | ||||
throw JSONRPCError(RPC_INVALID_PARAMETER, | throw JSONRPCError(RPC_INVALID_PARAMETER, | ||||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | RPCHelpMan{ | ||||
"\nLock the wallet again (before 60 seconds)\n" + | "\nLock the wallet again (before 60 seconds)\n" + | ||||
HelpExampleCli("walletlock", "") + "\nAs a JSON-RPC call\n" + | HelpExampleCli("walletlock", "") + "\nAs a JSON-RPC call\n" + | ||||
HelpExampleRpc("walletpassphrase", "\"my pass phrase\", 60")}, | HelpExampleRpc("walletpassphrase", "\"my pass phrase\", 60")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
int64_t nSleepTime; | int64_t nSleepTime; | ||||
{ | { | ||||
auto locked_chain = pwallet->chain().lock(); | |||||
LOCK(pwallet->cs_wallet); | LOCK(pwallet->cs_wallet); | ||||
if (!pwallet->IsCrypted()) { | if (!pwallet->IsCrypted()) { | ||||
throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, | throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, | ||||
"Error: running with an unencrypted wallet, but " | "Error: running with an unencrypted wallet, but " | ||||
"walletpassphrase was called."); | "walletpassphrase was called."); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | RPCHelpMan{ | ||||
RPCResults{}, | RPCResults{}, | ||||
RPCExamples{HelpExampleCli("walletpassphrasechange", | RPCExamples{HelpExampleCli("walletpassphrasechange", | ||||
"\"old one\" \"new one\"") + | "\"old one\" \"new one\"") + | ||||
HelpExampleRpc("walletpassphrasechange", | HelpExampleRpc("walletpassphrasechange", | ||||
"\"old one\", \"new one\"")}, | "\"old one\", \"new one\"")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
auto locked_chain = pwallet->chain().lock(); | |||||
LOCK(pwallet->cs_wallet); | LOCK(pwallet->cs_wallet); | ||||
if (!pwallet->IsCrypted()) { | if (!pwallet->IsCrypted()) { | ||||
throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, | throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, | ||||
"Error: running with an unencrypted wallet, but " | "Error: running with an unencrypted wallet, but " | ||||
"walletpassphrasechange was called."); | "walletpassphrasechange was called."); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | RPCHelpMan{ | ||||
"\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 1.0") + | "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 1.0") + | ||||
"\nClear the passphrase since we are done before 2 minutes is " | "\nClear the passphrase since we are done before 2 minutes is " | ||||
"up\n" + | "up\n" + | ||||
HelpExampleCli("walletlock", "") + "\nAs a JSON-RPC call\n" + | HelpExampleCli("walletlock", "") + "\nAs a JSON-RPC call\n" + | ||||
HelpExampleRpc("walletlock", "")}, | HelpExampleRpc("walletlock", "")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
auto locked_chain = pwallet->chain().lock(); | |||||
LOCK(pwallet->cs_wallet); | LOCK(pwallet->cs_wallet); | ||||
if (!pwallet->IsCrypted()) { | if (!pwallet->IsCrypted()) { | ||||
throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, | throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, | ||||
"Error: running with an unencrypted wallet, but " | "Error: running with an unencrypted wallet, but " | ||||
"walletlock was called."); | "walletlock was called."); | ||||
} | } | ||||
Show All 37 Lines | RPCHelpMan{ | ||||
"\nNow we can do something like sign\n" + | "\nNow we can do something like sign\n" + | ||||
HelpExampleCli("signmessage", "\"address\" \"test message\"") + | HelpExampleCli("signmessage", "\"address\" \"test message\"") + | ||||
"\nNow lock the wallet again by removing the passphrase\n" + | "\nNow lock the wallet again by removing the passphrase\n" + | ||||
HelpExampleCli("walletlock", "") + "\nAs a JSON-RPC call\n" + | HelpExampleCli("walletlock", "") + "\nAs a JSON-RPC call\n" + | ||||
HelpExampleRpc("encryptwallet", "\"my pass phrase\"")}, | HelpExampleRpc("encryptwallet", "\"my pass phrase\"")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
auto locked_chain = pwallet->chain().lock(); | |||||
LOCK(pwallet->cs_wallet); | LOCK(pwallet->cs_wallet); | ||||
if (pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) { | if (pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) { | ||||
throw JSONRPCError( | throw JSONRPCError( | ||||
RPC_WALLET_ENCRYPTION_FAILED, | RPC_WALLET_ENCRYPTION_FAILED, | ||||
"Error: wallet does not contain private keys, nothing to encrypt."); | "Error: wallet does not contain private keys, nothing to encrypt."); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 102 Lines • ▼ Show 20 Lines | RPCHelpMan{ | ||||
",\\\"vout\\\":1}]\"")}, | ",\\\"vout\\\":1}]\"")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
// 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(); | ||||
auto locked_chain = pwallet->chain().lock(); | |||||
LOCK(pwallet->cs_wallet); | LOCK(pwallet->cs_wallet); | ||||
RPCTypeCheckArgument(request.params[0], UniValue::VBOOL); | RPCTypeCheckArgument(request.params[0], UniValue::VBOOL); | ||||
bool fUnlock = request.params[0].get_bool(); | bool fUnlock = request.params[0].get_bool(); | ||||
if (request.params[1].isNull()) { | if (request.params[1].isNull()) { | ||||
if (fUnlock) { | if (fUnlock) { | ||||
▲ Show 20 Lines • Show All 110 Lines • ▼ Show 20 Lines | RPCHelpMan{ | ||||
"\"[{\\\"txid\\\":" | "\"[{\\\"txid\\\":" | ||||
"\\\"a08e6907dbbd3d809776dbfc5d82e371" | "\\\"a08e6907dbbd3d809776dbfc5d82e371" | ||||
"b764ed838b5655e72f463568df1aadf0\\\"" | "b764ed838b5655e72f463568df1aadf0\\\"" | ||||
",\\\"vout\\\":1}]\"") + | ",\\\"vout\\\":1}]\"") + | ||||
"\nAs a JSON-RPC call\n" + HelpExampleRpc("listlockunspent", "")}, | "\nAs a JSON-RPC call\n" + HelpExampleRpc("listlockunspent", "")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
auto locked_chain = pwallet->chain().lock(); | |||||
LOCK(pwallet->cs_wallet); | LOCK(pwallet->cs_wallet); | ||||
std::vector<COutPoint> vOutpts; | std::vector<COutPoint> vOutpts; | ||||
pwallet->ListLockedCoins(vOutpts); | pwallet->ListLockedCoins(vOutpts); | ||||
UniValue ret(UniValue::VARR); | UniValue ret(UniValue::VARR); | ||||
for (const COutPoint &output : vOutpts) { | for (const COutPoint &output : vOutpts) { | ||||
Show All 24 Lines | RPCHelpMan{ | ||||
"The transaction fee in " + CURRENCY_UNIT + "/kB"}, | "The transaction fee in " + CURRENCY_UNIT + "/kB"}, | ||||
}, | }, | ||||
RPCResult{"true|false (boolean) Returns true if successful\n"}, | RPCResult{"true|false (boolean) Returns true if successful\n"}, | ||||
RPCExamples{HelpExampleCli("settxfee", "0.00001") + | RPCExamples{HelpExampleCli("settxfee", "0.00001") + | ||||
HelpExampleRpc("settxfee", "0.00001")}, | HelpExampleRpc("settxfee", "0.00001")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
auto locked_chain = pwallet->chain().lock(); | |||||
LOCK(pwallet->cs_wallet); | LOCK(pwallet->cs_wallet); | ||||
Amount nAmount = AmountFromValue(request.params[0]); | Amount nAmount = AmountFromValue(request.params[0]); | ||||
CFeeRate tx_fee_rate(nAmount, 1000); | CFeeRate tx_fee_rate(nAmount, 1000); | ||||
if (tx_fee_rate == CFeeRate()) { | if (tx_fee_rate == CFeeRate()) { | ||||
// automatic selection | // automatic selection | ||||
} else if (tx_fee_rate < pwallet->chain().relayMinFee()) { | } else if (tx_fee_rate < pwallet->chain().relayMinFee()) { | ||||
throw JSONRPCError( | throw JSONRPCError( | ||||
▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | RPCHelpMan{ | ||||
HelpExampleRpc("getbalances", "")}, | HelpExampleRpc("getbalances", "")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
// 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 | ||||
wallet.BlockUntilSyncedToCurrentChain(); | wallet.BlockUntilSyncedToCurrentChain(); | ||||
auto locked_chain = wallet.chain().lock(); | |||||
LOCK(wallet.cs_wallet); | LOCK(wallet.cs_wallet); | ||||
UniValue obj(UniValue::VOBJ); | UniValue obj(UniValue::VOBJ); | ||||
const auto bal = wallet.GetBalance(); | const auto bal = wallet.GetBalance(); | ||||
UniValue balances{UniValue::VOBJ}; | UniValue balances{UniValue::VOBJ}; | ||||
{ | { | ||||
UniValue balances_mine{UniValue::VOBJ}; | UniValue balances_mine{UniValue::VOBJ}; | ||||
▲ Show 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | RPCHelpMan{ | ||||
HelpExampleRpc("getwalletinfo", "")}, | HelpExampleRpc("getwalletinfo", "")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
// 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(); | ||||
auto locked_chain = pwallet->chain().lock(); | |||||
LOCK(pwallet->cs_wallet); | LOCK(pwallet->cs_wallet); | ||||
UniValue obj(UniValue::VOBJ); | UniValue obj(UniValue::VOBJ); | ||||
size_t kpExternalSize = pwallet->KeypoolCountExternalKeys(); | size_t kpExternalSize = pwallet->KeypoolCountExternalKeys(); | ||||
const auto bal = pwallet->GetBalance(); | const auto bal = pwallet->GetBalance(); | ||||
obj.pushKV("walletname", pwallet->GetName()); | obj.pushKV("walletname", pwallet->GetName()); | ||||
obj.pushKV("walletversion", pwallet->GetVersion()); | obj.pushKV("walletversion", pwallet->GetVersion()); | ||||
▲ Show 20 Lines • Show All 535 Lines • ▼ Show 20 Lines | static UniValue listunspent(const Config &config, | ||||
UniValue results(UniValue::VARR); | UniValue results(UniValue::VARR); | ||||
std::vector<COutput> vecOutputs; | std::vector<COutput> vecOutputs; | ||||
{ | { | ||||
CCoinControl cctl; | CCoinControl cctl; | ||||
cctl.m_avoid_address_reuse = false; | cctl.m_avoid_address_reuse = false; | ||||
cctl.m_min_depth = nMinDepth; | cctl.m_min_depth = nMinDepth; | ||||
cctl.m_max_depth = nMaxDepth; | cctl.m_max_depth = nMaxDepth; | ||||
auto locked_chain = pwallet->chain().lock(); | |||||
LOCK(pwallet->cs_wallet); | LOCK(pwallet->cs_wallet); | ||||
pwallet->AvailableCoins(vecOutputs, !include_unsafe, &cctl, | pwallet->AvailableCoins(vecOutputs, !include_unsafe, &cctl, | ||||
nMinimumAmount, nMaximumAmount, | nMinimumAmount, nMaximumAmount, | ||||
nMinimumSumAmount, nMaximumCount); | nMinimumSumAmount, nMaximumCount); | ||||
} | } | ||||
LOCK(pwallet->cs_wallet); | LOCK(pwallet->cs_wallet); | ||||
▲ Show 20 Lines • Show All 386 Lines • ▼ Show 20 Lines | RPCTypeCheck(request.params, | ||||
{UniValue::VSTR, UniValue::VARR, UniValue::VSTR}, true); | {UniValue::VSTR, UniValue::VARR, UniValue::VSTR}, true); | ||||
CMutableTransaction mtx; | CMutableTransaction mtx; | ||||
if (!DecodeHexTx(mtx, request.params[0].get_str())) { | if (!DecodeHexTx(mtx, request.params[0].get_str())) { | ||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); | throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); | ||||
} | } | ||||
// Sign the transaction | // Sign the transaction | ||||
auto locked_chain = pwallet->chain().lock(); | |||||
LOCK(pwallet->cs_wallet); | LOCK(pwallet->cs_wallet); | ||||
EnsureWalletIsUnlocked(pwallet); | EnsureWalletIsUnlocked(pwallet); | ||||
// Fetch previous transactions (inputs): | // Fetch previous transactions (inputs): | ||||
std::map<COutPoint, Coin> coins; | std::map<COutPoint, Coin> coins; | ||||
for (const CTxIn &txin : mtx.vin) { | for (const CTxIn &txin : mtx.vin) { | ||||
// Create empty map entry keyed by prevout. | // Create empty map entry keyed by prevout. | ||||
coins[txin.prevout]; | coins[txin.prevout]; | ||||
▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | if (!reserver.reserve()) { | ||||
RPC_WALLET_ERROR, | RPC_WALLET_ERROR, | ||||
"Wallet is currently rescanning. Abort existing rescan or wait."); | "Wallet is currently rescanning. Abort existing rescan or wait."); | ||||
} | } | ||||
int start_height = 0; | int start_height = 0; | ||||
Optional<int> stop_height; | Optional<int> stop_height; | ||||
BlockHash start_block; | BlockHash start_block; | ||||
{ | { | ||||
auto locked_chain = pwallet->chain().lock(); | |||||
LOCK(pwallet->cs_wallet); | LOCK(pwallet->cs_wallet); | ||||
int tip_height = pwallet->GetLastBlockHeight(); | int tip_height = pwallet->GetLastBlockHeight(); | ||||
if (!request.params[0].isNull()) { | if (!request.params[0].isNull()) { | ||||
start_height = request.params[0].get_int(); | start_height = request.params[0].get_int(); | ||||
if (start_height < 0 || start_height > tip_height) { | if (start_height < 0 || start_height > tip_height) { | ||||
throw JSONRPCError(RPC_INVALID_PARAMETER, | throw JSONRPCError(RPC_INVALID_PARAMETER, | ||||
"Invalid start_height"); | "Invalid start_height"); | ||||
▲ Show 20 Lines • Show All 505 Lines • ▼ Show 20 Lines | static UniValue sethdseed(const Config &config, const JSONRPCRequest &request) { | ||||
} | } | ||||
if (pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) { | if (pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) { | ||||
throw JSONRPCError( | throw JSONRPCError( | ||||
RPC_WALLET_ERROR, | RPC_WALLET_ERROR, | ||||
"Cannot set a HD seed to a wallet with private keys disabled"); | "Cannot set a HD seed to a wallet with private keys disabled"); | ||||
} | } | ||||
auto locked_chain = pwallet->chain().lock(); | |||||
LOCK2(pwallet->cs_wallet, spk_man.cs_KeyStore); | LOCK2(pwallet->cs_wallet, spk_man.cs_KeyStore); | ||||
// Do not do anything to non-HD wallets | // Do not do anything to non-HD wallets | ||||
if (!pwallet->CanSupportFeature(FEATURE_HD)) { | if (!pwallet->CanSupportFeature(FEATURE_HD)) { | ||||
throw JSONRPCError( | throw JSONRPCError( | ||||
RPC_WALLET_ERROR, | RPC_WALLET_ERROR, | ||||
"Cannot set a HD seed on a non-HD wallet. Use the upgradewallet " | "Cannot set a HD seed on a non-HD wallet. Use the upgradewallet " | ||||
"RPC in order to upgrade a non-HD wallet to HD"); | "RPC in order to upgrade a non-HD wallet to HD"); | ||||
▲ Show 20 Lines • Show All 400 Lines • Show Last 20 Lines |