diff options
Diffstat (limited to 'src/wallet/rpcwallet.cpp')
-rw-r--r-- | src/wallet/rpcwallet.cpp | 187 |
1 files changed, 52 insertions, 135 deletions
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index df10fb48cc..dc39ba3001 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -982,131 +982,6 @@ static UniValue addmultisigaddress(const JSONRPCRequest& request) return result; } -class Witnessifier : public boost::static_visitor<bool> -{ -public: - CWallet * const pwallet; - CTxDestination result; - bool already_witness; - - explicit Witnessifier(CWallet *_pwallet) : pwallet(_pwallet), already_witness(false) {} - - bool operator()(const CKeyID &keyID) { - if (pwallet) { - CScript basescript = GetScriptForDestination(keyID); - CScript witscript = GetScriptForWitness(basescript); - if (!IsSolvable(*pwallet, witscript)) { - return false; - } - return ExtractDestination(witscript, result); - } - return false; - } - - bool operator()(const CScriptID &scriptID) { - CScript subscript; - if (pwallet && pwallet->GetCScript(scriptID, subscript)) { - int witnessversion; - std::vector<unsigned char> witprog; - if (subscript.IsWitnessProgram(witnessversion, witprog)) { - ExtractDestination(subscript, result); - already_witness = true; - return true; - } - CScript witscript = GetScriptForWitness(subscript); - if (!IsSolvable(*pwallet, witscript)) { - return false; - } - return ExtractDestination(witscript, result); - } - return false; - } - - bool operator()(const WitnessV0KeyHash& id) - { - already_witness = true; - result = id; - return true; - } - - bool operator()(const WitnessV0ScriptHash& id) - { - already_witness = true; - result = id; - return true; - } - - template<typename T> - bool operator()(const T& dest) { return false; } -}; - -static UniValue addwitnessaddress(const JSONRPCRequest& request) -{ - std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); - CWallet* const pwallet = wallet.get(); - - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { - return NullUniValue; - } - - if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) - { - std::string msg = "addwitnessaddress \"address\" ( p2sh )\n" - "\nDEPRECATED: set the address_type argument of getnewaddress, or option -addresstype=[bech32|p2sh-segwit] instead.\n" - "Add a witness address for a script (with pubkey or redeemscript known). Requires a new wallet backup.\n" - "It returns the witness script.\n" - - "\nArguments:\n" - "1. \"address\" (string, required) An address known to the wallet\n" - "2. p2sh (bool, optional, default=true) Embed inside P2SH\n" - - "\nResult:\n" - "\"witnessaddress\", (string) The value of the new address (P2SH or BIP173).\n" - "}\n" - ; - throw std::runtime_error(msg); - } - - if (!IsDeprecatedRPCEnabled("addwitnessaddress")) { - throw JSONRPCError(RPC_METHOD_DEPRECATED, "addwitnessaddress is deprecated and will be fully removed in v0.17. " - "To use addwitnessaddress in v0.16, restart bitcoind with -deprecatedrpc=addwitnessaddress.\n" - "Projects should transition to using the address_type argument of getnewaddress, or option -addresstype=[bech32|p2sh-segwit] instead.\n"); - } - - CTxDestination dest = DecodeDestination(request.params[0].get_str()); - if (!IsValidDestination(dest)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); - } - - bool p2sh = true; - if (!request.params[1].isNull()) { - p2sh = request.params[1].get_bool(); - } - - Witnessifier w(pwallet); - bool ret = boost::apply_visitor(w, dest); - if (!ret) { - throw JSONRPCError(RPC_WALLET_ERROR, "Public key or redeemscript not known to wallet, or the key is uncompressed"); - } - - CScript witprogram = GetScriptForDestination(w.result); - - if (p2sh) { - w.result = CScriptID(witprogram); - } - - if (w.already_witness) { - if (!(dest == w.result)) { - throw JSONRPCError(RPC_WALLET_ERROR, "Cannot convert between witness address types"); - } - } else { - pwallet->AddCScript(witprogram); // Implicit for single-key now, but necessary for multisig and for compatibility with older software - pwallet->SetAddressBook(w.result, "", "receive"); - } - - return EncodeDestination(w.result); -} - struct tallyitem { CAmount nAmount; @@ -1121,7 +996,7 @@ struct tallyitem } }; -static UniValue ListReceived(CWallet * const pwallet, const UniValue& params, bool by_label) EXCLUSIVE_LOCKS_REQUIRED(cs_main) +static UniValue ListReceived(CWallet * const pwallet, const UniValue& params, bool by_label) EXCLUSIVE_LOCKS_REQUIRED(cs_main, pwallet->cs_wallet) { // Minimum confirmations int nMinDepth = 1; @@ -1928,13 +1803,6 @@ static UniValue keypoolrefill(const JSONRPCRequest& request) } -static void LockWallet(CWallet* pWallet) -{ - LOCK(pWallet->cs_wallet); - pWallet->nRelockTime = 0; - pWallet->Lock(); -} - static UniValue walletpassphrase(const JSONRPCRequest& request) { std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); @@ -2004,7 +1872,18 @@ static UniValue walletpassphrase(const JSONRPCRequest& request) pwallet->TopUpKeyPool(); pwallet->nRelockTime = GetTime() + nSleepTime; - RPCRunLater(strprintf("lockwallet(%s)", pwallet->GetName()), std::bind(LockWallet, pwallet), nSleepTime); + + // Keep a weak pointer to the wallet so that it is possible to unload the + // wallet before the following callback is called. If a valid shared pointer + // is acquired in the callback then the wallet is still loaded. + std::weak_ptr<CWallet> weak_wallet = wallet; + RPCRunLater(strprintf("lockwallet(%s)", pwallet->GetName()), [weak_wallet] { + if (auto shared_wallet = weak_wallet.lock()) { + LOCK(shared_wallet->cs_wallet); + shared_wallet->Lock(); + shared_wallet->nRelockTime = 0; + } + }, nSleepTime); return NullUniValue; } @@ -2443,6 +2322,38 @@ static UniValue getwalletinfo(const JSONRPCRequest& request) return obj; } +static UniValue listwalletdir(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 0) { + throw std::runtime_error( + "listwalletdir\n" + "Returns a list of wallets in the wallet directory.\n" + "{\n" + " \"wallets\" : [ (json array of objects)\n" + " {\n" + " \"name\" : \"name\" (string) The wallet name\n" + " }\n" + " ,...\n" + " ]\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("listwalletdir", "") + + HelpExampleRpc("listwalletdir", "") + ); + } + + UniValue wallets(UniValue::VARR); + for (const auto& path : ListWalletDir()) { + UniValue wallet(UniValue::VOBJ); + wallet.pushKV("name", path.string()); + wallets.push_back(wallet); + } + + UniValue result(UniValue::VOBJ); + result.pushKV("wallets", wallets); + return result; +} + static UniValue listwallets(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() != 0) @@ -3289,6 +3200,12 @@ UniValue generate(const JSONRPCRequest& request) ); } + if (!IsDeprecatedRPCEnabled("generate")) { + throw JSONRPCError(RPC_METHOD_DEPRECATED, "The wallet generate rpc method is deprecated and will be fully removed in v0.19. " + "To use generate in v0.18, restart bitcoind with -deprecatedrpc=generate.\n" + "Clients should transition to using the node rpc method generatetoaddress\n"); + } + int num_generate = request.params[0].get_int(); uint64_t max_tries = 1000000; if (!request.params[1].isNull()) { @@ -4059,7 +3976,6 @@ static const CRPCCommand commands[] = { // category name actor (function) argNames // --------------------- ------------------------ ----------------------- ---------- { "generating", "generate", &generate, {"nblocks","maxtries"} }, - { "hidden", "addwitnessaddress", &addwitnessaddress, {"address","p2sh"} }, { "hidden", "resendwallettransactions", &resendwallettransactions, {} }, { "rawtransactions", "fundrawtransaction", &fundrawtransaction, {"hexstring","options","iswitness"} }, { "wallet", "abandontransaction", &abandontransaction, {"txid"} }, @@ -4096,6 +4012,7 @@ static const CRPCCommand commands[] = { "wallet", "listsinceblock", &listsinceblock, {"blockhash","target_confirmations","include_watchonly","include_removed"} }, { "wallet", "listtransactions", &listtransactions, {"dummy","count","skip","include_watchonly"} }, { "wallet", "listunspent", &listunspent, {"minconf","maxconf","addresses","include_unsafe","query_options"} }, + { "wallet", "listwalletdir", &listwalletdir, {} }, { "wallet", "listwallets", &listwallets, {} }, { "wallet", "loadwallet", &loadwallet, {"filename"} }, { "wallet", "lockunspent", &lockunspent, {"unlock","transactions"} }, |