From eca550f2501f3f2bbe682bdc3cb8b90c90c90275 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Fri, 9 Sep 2016 05:32:12 +0000 Subject: RPC/Wallet: Pass CWallet as pointer to helper functions --- src/rpc/misc.cpp | 18 ++-- src/rpc/rawtransaction.cpp | 4 +- src/rpc/server.h | 11 ++- src/wallet/rpcdump.cpp | 125 ++++++++++++++-------------- src/wallet/rpcwallet.cpp | 199 +++++++++++++++++++++++---------------------- 5 files changed, 184 insertions(+), 173 deletions(-) (limited to 'src') diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 140cb4840b..f8e9acb08c 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -112,13 +112,17 @@ UniValue getinfo(const JSONRPCRequest& request) class DescribeAddressVisitor : public boost::static_visitor { public: + CWallet * const pwallet; + + DescribeAddressVisitor(CWallet *_pwallet) : pwallet(_pwallet) {} + UniValue operator()(const CNoDestination &dest) const { return UniValue(UniValue::VOBJ); } UniValue operator()(const CKeyID &keyID) const { UniValue obj(UniValue::VOBJ); CPubKey vchPubKey; obj.push_back(Pair("isscript", false)); - if (pwalletMain && pwalletMain->GetPubKey(keyID, vchPubKey)) { + if (pwallet && pwallet->GetPubKey(keyID, vchPubKey)) { obj.push_back(Pair("pubkey", HexStr(vchPubKey))); obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed())); } @@ -129,7 +133,7 @@ public: UniValue obj(UniValue::VOBJ); CScript subscript; obj.push_back(Pair("isscript", true)); - if (pwalletMain && pwalletMain->GetCScript(scriptID, subscript)) { + if (pwallet && pwallet->GetCScript(scriptID, subscript)) { std::vector addresses; txnouttype whichType; int nRequired; @@ -200,7 +204,7 @@ UniValue validateaddress(const JSONRPCRequest& request) isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : ISMINE_NO; ret.push_back(Pair("ismine", (mine & ISMINE_SPENDABLE) ? true : false)); ret.push_back(Pair("iswatchonly", (mine & ISMINE_WATCH_ONLY) ? true: false)); - UniValue detail = boost::apply_visitor(DescribeAddressVisitor(), dest); + UniValue detail = boost::apply_visitor(DescribeAddressVisitor(pwalletMain), dest); ret.pushKVs(detail); if (pwalletMain && pwalletMain->mapAddressBook.count(dest)) ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name)); @@ -227,7 +231,7 @@ UniValue validateaddress(const JSONRPCRequest& request) /** * Used by addmultisigaddress / createmultisig: */ -CScript _createmultisig_redeemScript(const UniValue& params) +CScript _createmultisig_redeemScript(CWallet * const pwallet, const UniValue& params) { int nRequired = params[0].get_int(); const UniValue& keys = params[1].get_array(); @@ -249,14 +253,14 @@ CScript _createmultisig_redeemScript(const UniValue& params) #ifdef ENABLE_WALLET // Case 1: Bitcoin address and we have full public key: CBitcoinAddress address(ks); - if (pwalletMain && address.IsValid()) + if (pwallet && address.IsValid()) { CKeyID keyID; if (!address.GetKeyID(keyID)) throw runtime_error( strprintf("%s does not refer to a key",ks)); CPubKey vchPubKey; - if (!pwalletMain->GetPubKey(keyID, vchPubKey)) + if (!pwallet->GetPubKey(keyID, vchPubKey)) throw runtime_error( strprintf("no full public key for address %s",ks)); if (!vchPubKey.IsFullyValid()) @@ -320,7 +324,7 @@ UniValue createmultisig(const JSONRPCRequest& request) } // Construct using pay-to-script-hash: - CScript inner = _createmultisig_redeemScript(request.params); + CScript inner = _createmultisig_redeemScript(pwalletMain, request.params); CScriptID innerID(inner); CBitcoinAddress address(innerID); diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index bf16f27498..faafe9829b 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -603,7 +603,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request) "The third optional argument (may be null) is an array of base58-encoded private\n" "keys that, if given, will be the only keys used to sign the transaction.\n" #ifdef ENABLE_WALLET - + HelpRequiringPassphrase() + "\n" + + HelpRequiringPassphrase(pwalletMain) + "\n" #endif "\nArguments:\n" @@ -718,7 +718,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request) } #ifdef ENABLE_WALLET else if (pwalletMain) - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); #endif // Add previous txouts given in the RPC call: diff --git a/src/rpc/server.h b/src/rpc/server.h index 52f82866dc..b32eaaa133 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -194,11 +194,18 @@ extern int64_t nWalletUnlockTime; extern CAmount AmountFromValue(const UniValue& value); extern UniValue ValueFromAmount(const CAmount& amount); extern double GetDifficulty(const CBlockIndex* blockindex = NULL); -extern std::string HelpRequiringPassphrase(); extern std::string HelpExampleCli(const std::string& methodname, const std::string& args); extern std::string HelpExampleRpc(const std::string& methodname, const std::string& args); -extern void EnsureWalletIsUnlocked(); +// Needed even with !ENABLE_WALLET, to pass (ignored) pointers around +class CWallet; + +#ifdef ENABLE_WALLET +// New code should accessing the wallet should be under the ../wallet/ directory +std::string HelpRequiringPassphrase(CWallet *); +void EnsureWalletIsUnlocked(CWallet *); +bool EnsureWalletIsAvailable(CWallet *, bool avoidException); +#endif bool StartRPC(); void InterruptRPC(); diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 8a9e7d1444..9f71d74e32 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -29,9 +29,6 @@ using namespace std; -void EnsureWalletIsUnlocked(); -bool EnsureWalletIsAvailable(bool avoidException); - std::string static EncodeDumpTime(int64_t nTime) { return DateTimeStrFormat("%Y-%m-%dT%H:%M:%SZ", nTime); } @@ -77,7 +74,7 @@ std::string DecodeDumpString(const std::string &str) { UniValue importprivkey(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 3) @@ -103,7 +100,7 @@ UniValue importprivkey(const JSONRPCRequest& request) LOCK2(cs_main, pwalletMain->cs_wallet); - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); string strSecret = request.params[0].get_str(); string strLabel = ""; @@ -153,41 +150,41 @@ UniValue importprivkey(const JSONRPCRequest& request) return NullUniValue; } -void ImportAddress(const CBitcoinAddress& address, const string& strLabel); -void ImportScript(const CScript& script, const string& strLabel, bool isRedeemScript) +void ImportAddress(CWallet*, const CBitcoinAddress& address, const string& strLabel); +void ImportScript(CWallet * const pwallet, const CScript& script, const string& strLabel, bool isRedeemScript) { - if (!isRedeemScript && ::IsMine(*pwalletMain, script) == ISMINE_SPENDABLE) + if (!isRedeemScript && ::IsMine(*pwallet, script) == ISMINE_SPENDABLE) throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script"); - pwalletMain->MarkDirty(); + pwallet->MarkDirty(); - if (!pwalletMain->HaveWatchOnly(script) && !pwalletMain->AddWatchOnly(script, 0 /* nCreateTime */)) + if (!pwallet->HaveWatchOnly(script) && !pwallet->AddWatchOnly(script, 0 /* nCreateTime */)) throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); if (isRedeemScript) { - if (!pwalletMain->HaveCScript(script) && !pwalletMain->AddCScript(script)) + if (!pwallet->HaveCScript(script) && !pwallet->AddCScript(script)) throw JSONRPCError(RPC_WALLET_ERROR, "Error adding p2sh redeemScript to wallet"); - ImportAddress(CBitcoinAddress(CScriptID(script)), strLabel); + ImportAddress(pwallet, CBitcoinAddress(CScriptID(script)), strLabel); } else { CTxDestination destination; if (ExtractDestination(script, destination)) { - pwalletMain->SetAddressBook(destination, strLabel, "receive"); + pwallet->SetAddressBook(destination, strLabel, "receive"); } } } -void ImportAddress(const CBitcoinAddress& address, const string& strLabel) +void ImportAddress(CWallet * const pwallet, const CBitcoinAddress& address, const string& strLabel) { CScript script = GetScriptForDestination(address.Get()); - ImportScript(script, strLabel, false); + ImportScript(pwallet, script, strLabel, false); // add to address book or update label if (address.IsValid()) - pwalletMain->SetAddressBook(address.Get(), strLabel, "receive"); + pwallet->SetAddressBook(address.Get(), strLabel, "receive"); } UniValue importaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) @@ -236,10 +233,10 @@ UniValue importaddress(const JSONRPCRequest& request) if (address.IsValid()) { if (fP2SH) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Cannot use the p2sh flag with an address - use a script instead"); - ImportAddress(address, strLabel); + ImportAddress(pwalletMain, address, strLabel); } else if (IsHex(request.params[0].get_str())) { std::vector data(ParseHex(request.params[0].get_str())); - ImportScript(CScript(data.begin(), data.end()), strLabel, fP2SH); + ImportScript(pwalletMain, CScript(data.begin(), data.end()), strLabel, fP2SH); } else { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address or script"); } @@ -255,7 +252,7 @@ UniValue importaddress(const JSONRPCRequest& request) UniValue importprunedfunds(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 2) @@ -314,7 +311,7 @@ UniValue importprunedfunds(const JSONRPCRequest& request) UniValue removeprunedfunds(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 1) @@ -350,7 +347,7 @@ UniValue removeprunedfunds(const JSONRPCRequest& request) UniValue importpubkey(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) @@ -393,8 +390,8 @@ UniValue importpubkey(const JSONRPCRequest& request) LOCK2(cs_main, pwalletMain->cs_wallet); - ImportAddress(CBitcoinAddress(pubKey.GetID()), strLabel); - ImportScript(GetScriptForRawPubKey(pubKey), strLabel, false); + ImportAddress(pwalletMain, CBitcoinAddress(pubKey.GetID()), strLabel); + ImportScript(pwalletMain, GetScriptForRawPubKey(pubKey), strLabel, false); if (fRescan) { @@ -408,7 +405,7 @@ UniValue importpubkey(const JSONRPCRequest& request) UniValue importwallet(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 1) @@ -431,7 +428,7 @@ UniValue importwallet(const JSONRPCRequest& request) LOCK2(cs_main, pwalletMain->cs_wallet); - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); ifstream file; file.open(request.params[0].get_str().c_str(), std::ios::in | std::ios::ate); @@ -514,7 +511,7 @@ UniValue importwallet(const JSONRPCRequest& request) UniValue dumpprivkey(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 1) @@ -534,7 +531,7 @@ UniValue dumpprivkey(const JSONRPCRequest& request) LOCK2(cs_main, pwalletMain->cs_wallet); - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); string strAddress = request.params[0].get_str(); CBitcoinAddress address; @@ -552,7 +549,7 @@ UniValue dumpprivkey(const JSONRPCRequest& request) UniValue dumpwallet(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 1) @@ -568,7 +565,7 @@ UniValue dumpwallet(const JSONRPCRequest& request) LOCK2(cs_main, pwalletMain->cs_wallet); - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); ofstream file; file.open(request.params[0].get_str().c_str()); @@ -641,7 +638,7 @@ UniValue dumpwallet(const JSONRPCRequest& request) } -UniValue ProcessImport(const UniValue& data, const int64_t timestamp) +UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int64_t timestamp) { try { bool success = false; @@ -723,32 +720,32 @@ UniValue ProcessImport(const UniValue& data, const int64_t timestamp) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid P2SH address / script"); } - pwalletMain->MarkDirty(); + pwallet->MarkDirty(); - if (!pwalletMain->HaveWatchOnly(redeemScript) && !pwalletMain->AddWatchOnly(redeemScript, timestamp)) { + if (!pwallet->HaveWatchOnly(redeemScript) && !pwallet->AddWatchOnly(redeemScript, timestamp)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); } - if (!pwalletMain->HaveCScript(redeemScript) && !pwalletMain->AddCScript(redeemScript)) { + if (!pwallet->HaveCScript(redeemScript) && !pwallet->AddCScript(redeemScript)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding p2sh redeemScript to wallet"); } CBitcoinAddress redeemAddress = CBitcoinAddress(CScriptID(redeemScript)); CScript redeemDestination = GetScriptForDestination(redeemAddress.Get()); - if (::IsMine(*pwalletMain, redeemDestination) == ISMINE_SPENDABLE) { + if (::IsMine(*pwallet, redeemDestination) == ISMINE_SPENDABLE) { throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script"); } - pwalletMain->MarkDirty(); + pwallet->MarkDirty(); - if (!pwalletMain->HaveWatchOnly(redeemDestination) && !pwalletMain->AddWatchOnly(redeemDestination, timestamp)) { + if (!pwallet->HaveWatchOnly(redeemDestination) && !pwallet->AddWatchOnly(redeemDestination, timestamp)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); } // add to address book or update label if (address.IsValid()) { - pwalletMain->SetAddressBook(address.Get(), label, "receive"); + pwallet->SetAddressBook(address.Get(), label, "receive"); } // Import private keys. @@ -773,20 +770,20 @@ UniValue ProcessImport(const UniValue& data, const int64_t timestamp) assert(key.VerifyPubKey(pubkey)); CKeyID vchAddress = pubkey.GetID(); - pwalletMain->MarkDirty(); - pwalletMain->SetAddressBook(vchAddress, label, "receive"); + pwallet->MarkDirty(); + pwallet->SetAddressBook(vchAddress, label, "receive"); - if (pwalletMain->HaveKey(vchAddress)) { + if (pwallet->HaveKey(vchAddress)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Already have this key"); } - pwalletMain->mapKeyMetadata[vchAddress].nCreateTime = timestamp; + pwallet->mapKeyMetadata[vchAddress].nCreateTime = timestamp; - if (!pwalletMain->AddKeyPubKey(key, pubkey)) { + if (!pwallet->AddKeyPubKey(key, pubkey)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet"); } - pwalletMain->UpdateTimeFirstKey(timestamp); + pwallet->UpdateTimeFirstKey(timestamp); } } @@ -829,31 +826,31 @@ UniValue ProcessImport(const UniValue& data, const int64_t timestamp) CScript pubKeyScript = GetScriptForDestination(pubKeyAddress.Get()); - if (::IsMine(*pwalletMain, pubKeyScript) == ISMINE_SPENDABLE) { + if (::IsMine(*pwallet, pubKeyScript) == ISMINE_SPENDABLE) { throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script"); } - pwalletMain->MarkDirty(); + pwallet->MarkDirty(); - if (!pwalletMain->HaveWatchOnly(pubKeyScript) && !pwalletMain->AddWatchOnly(pubKeyScript, timestamp)) { + if (!pwallet->HaveWatchOnly(pubKeyScript) && !pwallet->AddWatchOnly(pubKeyScript, timestamp)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); } // add to address book or update label if (pubKeyAddress.IsValid()) { - pwalletMain->SetAddressBook(pubKeyAddress.Get(), label, "receive"); + pwallet->SetAddressBook(pubKeyAddress.Get(), label, "receive"); } // TODO Is this necessary? CScript scriptRawPubKey = GetScriptForRawPubKey(pubKey); - if (::IsMine(*pwalletMain, scriptRawPubKey) == ISMINE_SPENDABLE) { + if (::IsMine(*pwallet, scriptRawPubKey) == ISMINE_SPENDABLE) { throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script"); } - pwalletMain->MarkDirty(); + pwallet->MarkDirty(); - if (!pwalletMain->HaveWatchOnly(scriptRawPubKey) && !pwalletMain->AddWatchOnly(scriptRawPubKey, timestamp)) { + if (!pwallet->HaveWatchOnly(scriptRawPubKey) && !pwallet->AddWatchOnly(scriptRawPubKey, timestamp)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); } @@ -901,40 +898,40 @@ UniValue ProcessImport(const UniValue& data, const int64_t timestamp) } CKeyID vchAddress = pubKey.GetID(); - pwalletMain->MarkDirty(); - pwalletMain->SetAddressBook(vchAddress, label, "receive"); + pwallet->MarkDirty(); + pwallet->SetAddressBook(vchAddress, label, "receive"); - if (pwalletMain->HaveKey(vchAddress)) { + if (pwallet->HaveKey(vchAddress)) { return false; } - pwalletMain->mapKeyMetadata[vchAddress].nCreateTime = timestamp; + pwallet->mapKeyMetadata[vchAddress].nCreateTime = timestamp; - if (!pwalletMain->AddKeyPubKey(key, pubKey)) { + if (!pwallet->AddKeyPubKey(key, pubKey)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet"); } - pwalletMain->UpdateTimeFirstKey(timestamp); + pwallet->UpdateTimeFirstKey(timestamp); success = true; } // Import scriptPubKey only. if (pubKeys.size() == 0 && keys.size() == 0) { - if (::IsMine(*pwalletMain, script) == ISMINE_SPENDABLE) { + if (::IsMine(*pwallet, script) == ISMINE_SPENDABLE) { throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script"); } - pwalletMain->MarkDirty(); + pwallet->MarkDirty(); - if (!pwalletMain->HaveWatchOnly(script) && !pwalletMain->AddWatchOnly(script, timestamp)) { + if (!pwallet->HaveWatchOnly(script) && !pwallet->AddWatchOnly(script, timestamp)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); } if (scriptPubKey.getType() == UniValue::VOBJ) { // add to address book or update label if (address.IsValid()) { - pwalletMain->SetAddressBook(address.Get(), label, "receive"); + pwallet->SetAddressBook(address.Get(), label, "receive"); } } @@ -1012,7 +1009,7 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) " [{ \"success\": true } , { \"success\": false, \"error\": { \"code\": -1, \"message\": \"Internal Server Error\"} }, ... ]\n"); // clang-format on - if (!EnsureWalletIsAvailable(mainRequest.fHelp)) { + if (!EnsureWalletIsAvailable(pwalletMain, mainRequest.fHelp)) { return NullUniValue; } @@ -1032,7 +1029,7 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) } LOCK2(cs_main, pwalletMain->cs_wallet); - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); // Verify all timestamps are present before importing any keys. const int64_t now = chainActive.Tip() ? chainActive.Tip()->GetMedianTimePast() : 0; @@ -1054,7 +1051,7 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) BOOST_FOREACH (const UniValue& data, requests.getValues()) { const int64_t timestamp = std::max(GetImportTimestamp(data, now), minimumTimestamp); - const UniValue result = ProcessImport(data, timestamp); + const UniValue result = ProcessImport(pwalletMain, data, timestamp); response.push_back(result); if (!fRescan) { diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 6b9e49038b..179d42fca9 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -32,16 +32,16 @@ using namespace std; int64_t nWalletUnlockTime; static CCriticalSection cs_nWalletUnlockTime; -std::string HelpRequiringPassphrase() +std::string HelpRequiringPassphrase(CWallet * const pwallet) { - return pwalletMain && pwalletMain->IsCrypted() + return pwallet && pwallet->IsCrypted() ? "\nRequires wallet passphrase to be set with walletpassphrase call." : ""; } -bool EnsureWalletIsAvailable(bool avoidException) +bool EnsureWalletIsAvailable(CWallet * const pwallet, bool avoidException) { - if (!pwalletMain) + if (!pwallet) { if (!avoidException) throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)"); @@ -51,9 +51,9 @@ bool EnsureWalletIsAvailable(bool avoidException) return true; } -void EnsureWalletIsUnlocked() +void EnsureWalletIsUnlocked(CWallet * const pwallet) { - if (pwalletMain->IsLocked()) + if (pwallet->IsLocked()) throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first."); } @@ -106,7 +106,7 @@ string AccountFromValue(const UniValue& value) UniValue getnewaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 1) @@ -146,10 +146,10 @@ UniValue getnewaddress(const JSONRPCRequest& request) } -CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false) +CBitcoinAddress GetAccountAddress(CWallet * const pwallet, string strAccount, bool bForceNew=false) { CPubKey pubKey; - if (!pwalletMain->GetAccountPubkey(pubKey, strAccount, bForceNew)) { + if (!pwallet->GetAccountPubkey(pubKey, strAccount, bForceNew)) { throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); } @@ -158,7 +158,7 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false) UniValue getaccountaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 1) @@ -183,14 +183,14 @@ UniValue getaccountaddress(const JSONRPCRequest& request) UniValue ret(UniValue::VSTR); - ret = GetAccountAddress(strAccount).ToString(); + ret = GetAccountAddress(pwalletMain, strAccount).ToString(); return ret; } UniValue getrawchangeaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 1) @@ -225,7 +225,7 @@ UniValue getrawchangeaddress(const JSONRPCRequest& request) UniValue setaccount(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) @@ -257,8 +257,8 @@ UniValue setaccount(const JSONRPCRequest& request) if (pwalletMain->mapAddressBook.count(address.Get())) { string strOldAccount = pwalletMain->mapAddressBook[address.Get()].name; - if (address == GetAccountAddress(strOldAccount)) - GetAccountAddress(strOldAccount, true); + if (address == GetAccountAddress(pwalletMain, strOldAccount)) + GetAccountAddress(pwalletMain, strOldAccount, true); } pwalletMain->SetAddressBook(address.Get(), strAccount, "receive"); } @@ -271,7 +271,7 @@ UniValue setaccount(const JSONRPCRequest& request) UniValue getaccount(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 1) @@ -303,7 +303,7 @@ UniValue getaccount(const JSONRPCRequest& request) UniValue getaddressesbyaccount(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 1) @@ -338,9 +338,9 @@ UniValue getaddressesbyaccount(const JSONRPCRequest& request) return ret; } -static void SendMoney(const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, CWalletTx& wtxNew) +static void SendMoney(CWallet * const pwallet, const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, CWalletTx& wtxNew) { - CAmount curBalance = pwalletMain->GetBalance(); + CAmount curBalance = pwallet->GetBalance(); // Check amount if (nValue <= 0) @@ -349,27 +349,27 @@ static void SendMoney(const CTxDestination &address, CAmount nValue, bool fSubtr if (nValue > curBalance) throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds"); - if (pwalletMain->GetBroadcastTransactions() && !g_connman) + if (pwallet->GetBroadcastTransactions() && !g_connman) throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); // Parse Bitcoin address CScript scriptPubKey = GetScriptForDestination(address); // Create and send the transaction - CReserveKey reservekey(pwalletMain); + CReserveKey reservekey(pwallet); CAmount nFeeRequired; std::string strError; vector vecSend; int nChangePosRet = -1; CRecipient recipient = {scriptPubKey, nValue, fSubtractFeeFromAmount}; vecSend.push_back(recipient); - if (!pwalletMain->CreateTransaction(vecSend, wtxNew, reservekey, nFeeRequired, nChangePosRet, strError)) { + if (!pwallet->CreateTransaction(vecSend, wtxNew, reservekey, nFeeRequired, nChangePosRet, strError)) { if (!fSubtractFeeFromAmount && nValue + nFeeRequired > curBalance) strError = strprintf("Error: This transaction requires a transaction fee of at least %s", FormatMoney(nFeeRequired)); throw JSONRPCError(RPC_WALLET_ERROR, strError); } CValidationState state; - if (!pwalletMain->CommitTransaction(wtxNew, reservekey, g_connman.get(), state)) { + if (!pwallet->CommitTransaction(wtxNew, reservekey, g_connman.get(), state)) { strError = strprintf("Error: The transaction was rejected! Reason given: %s", state.GetRejectReason()); throw JSONRPCError(RPC_WALLET_ERROR, strError); } @@ -377,14 +377,14 @@ static void SendMoney(const CTxDestination &address, CAmount nValue, bool fSubtr UniValue sendtoaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 2 || request.params.size() > 5) throw runtime_error( "sendtoaddress \"address\" amount ( \"comment\" \"comment_to\" subtractfeefromamount )\n" "\nSend an amount to a given address.\n" - + HelpRequiringPassphrase() + + + HelpRequiringPassphrase(pwalletMain) + "\nArguments:\n" "1. \"address\" (string, required) The bitcoin address to send to.\n" "2. \"amount\" (numeric or string, required) The amount in " + CURRENCY_UNIT + " to send. eg 0.1\n" @@ -426,16 +426,16 @@ UniValue sendtoaddress(const JSONRPCRequest& request) if (request.params.size() > 4) fSubtractFeeFromAmount = request.params[4].get_bool(); - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); - SendMoney(address.Get(), nAmount, fSubtractFeeFromAmount, wtx); + SendMoney(pwalletMain, address.Get(), nAmount, fSubtractFeeFromAmount, wtx); return wtx.GetHash().GetHex(); } UniValue listaddressgroupings(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp) @@ -486,14 +486,14 @@ UniValue listaddressgroupings(const JSONRPCRequest& request) UniValue signmessage(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 2) throw runtime_error( "signmessage \"address\" \"message\"\n" "\nSign a message with the private key of an address" - + HelpRequiringPassphrase() + "\n" + + HelpRequiringPassphrase(pwalletMain) + "\n" "\nArguments:\n" "1. \"address\" (string, required) The bitcoin address to use for the private key.\n" "2. \"message\" (string, required) The message to create a signature of.\n" @@ -512,7 +512,7 @@ UniValue signmessage(const JSONRPCRequest& request) LOCK2(cs_main, pwalletMain->cs_wallet); - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); string strAddress = request.params[0].get_str(); string strMessage = request.params[1].get_str(); @@ -542,7 +542,7 @@ UniValue signmessage(const JSONRPCRequest& request) UniValue getreceivedbyaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) @@ -600,7 +600,7 @@ UniValue getreceivedbyaddress(const JSONRPCRequest& request) UniValue getreceivedbyaccount(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) @@ -657,7 +657,7 @@ UniValue getreceivedbyaccount(const JSONRPCRequest& request) UniValue getbalance(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 3) @@ -746,7 +746,7 @@ UniValue getbalance(const JSONRPCRequest& request) UniValue getunconfirmedbalance(const JSONRPCRequest &request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 0) @@ -762,7 +762,7 @@ UniValue getunconfirmedbalance(const JSONRPCRequest &request) UniValue movecmd(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 3 || request.params.size() > 5) @@ -809,14 +809,14 @@ UniValue movecmd(const JSONRPCRequest& request) UniValue sendfrom(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 3 || request.params.size() > 6) throw runtime_error( "sendfrom \"fromaccount\" \"toaddress\" amount ( minconf \"comment\" \"comment_to\" )\n" "\nDEPRECATED (use sendtoaddress). Sent an amount from an account to a bitcoin address." - + HelpRequiringPassphrase() + "\n" + + HelpRequiringPassphrase(pwalletMain) + "\n" "\nArguments:\n" "1. \"fromaccount\" (string, required) The name of the account to send funds from. May be the default account using \"\".\n" " Specifying an account does not influence coin selection, but it does associate the newly created\n" @@ -861,14 +861,14 @@ UniValue sendfrom(const JSONRPCRequest& request) if (request.params.size() > 5 && !request.params[5].isNull() && !request.params[5].get_str().empty()) wtx.mapValue["to"] = request.params[5].get_str(); - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); // Check funds CAmount nBalance = pwalletMain->GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE); if (nAmount > nBalance) throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds"); - SendMoney(address.Get(), nAmount, false, wtx); + SendMoney(pwalletMain, address.Get(), nAmount, false, wtx); return wtx.GetHash().GetHex(); } @@ -876,14 +876,14 @@ UniValue sendfrom(const JSONRPCRequest& request) UniValue sendmany(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 2 || request.params.size() > 5) throw runtime_error( "sendmany \"fromaccount\" {\"address\":amount,...} ( minconf \"comment\" [\"address\",...] )\n" "\nSend multiple times. Amounts are double-precision floating point numbers." - + HelpRequiringPassphrase() + "\n" + + HelpRequiringPassphrase(pwalletMain) + "\n" "\nArguments:\n" "1. \"fromaccount\" (string, required) DEPRECATED. The account to send the funds from. Should be \"\" for the default account\n" "2. \"amounts\" (string, required) A json object with addresses and amounts\n" @@ -967,7 +967,7 @@ UniValue sendmany(const JSONRPCRequest& request) vecSend.push_back(recipient); } - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); // Check funds CAmount nBalance = pwalletMain->GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE); @@ -992,11 +992,11 @@ UniValue sendmany(const JSONRPCRequest& request) } // Defined in rpc/misc.cpp -extern CScript _createmultisig_redeemScript(const UniValue& params); +extern CScript _createmultisig_redeemScript(CWallet * const pwallet, const UniValue& params); UniValue addmultisigaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 2 || request.params.size() > 3) @@ -1034,7 +1034,7 @@ UniValue addmultisigaddress(const JSONRPCRequest& request) strAccount = AccountFromValue(request.params[2]); // Construct using pay-to-script-hash: - CScript inner = _createmultisig_redeemScript(request.params); + CScript inner = _createmultisig_redeemScript(pwalletMain, request.params); CScriptID innerID(inner); pwalletMain->AddCScript(inner); @@ -1045,20 +1045,23 @@ UniValue addmultisigaddress(const JSONRPCRequest& request) class Witnessifier : public boost::static_visitor { public: + CWallet * const pwallet; CScriptID result; + Witnessifier(CWallet *_pwallet) : pwallet(_pwallet) {} + bool operator()(const CNoDestination &dest) const { return false; } bool operator()(const CKeyID &keyID) { CPubKey pubkey; - if (pwalletMain) { + if (pwallet) { CScript basescript = GetScriptForDestination(keyID); isminetype typ; - typ = IsMine(*pwalletMain, basescript, SIGVERSION_WITNESS_V0); + typ = IsMine(*pwallet, basescript, SIGVERSION_WITNESS_V0); if (typ != ISMINE_SPENDABLE && typ != ISMINE_WATCH_SOLVABLE) return false; CScript witscript = GetScriptForWitness(basescript); - pwalletMain->AddCScript(witscript); + pwallet->AddCScript(witscript); result = CScriptID(witscript); return true; } @@ -1067,7 +1070,7 @@ public: bool operator()(const CScriptID &scriptID) { CScript subscript; - if (pwalletMain && pwalletMain->GetCScript(scriptID, subscript)) { + if (pwallet && pwallet->GetCScript(scriptID, subscript)) { int witnessversion; std::vector witprog; if (subscript.IsWitnessProgram(witnessversion, witprog)) { @@ -1075,11 +1078,11 @@ public: return true; } isminetype typ; - typ = IsMine(*pwalletMain, subscript, SIGVERSION_WITNESS_V0); + typ = IsMine(*pwallet, subscript, SIGVERSION_WITNESS_V0); if (typ != ISMINE_SPENDABLE && typ != ISMINE_WATCH_SOLVABLE) return false; CScript witscript = GetScriptForWitness(subscript); - pwalletMain->AddCScript(witscript); + pwallet->AddCScript(witscript); result = CScriptID(witscript); return true; } @@ -1089,7 +1092,7 @@ public: UniValue addwitnessaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 1) @@ -1119,7 +1122,7 @@ UniValue addwitnessaddress(const JSONRPCRequest& request) if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); - Witnessifier w; + Witnessifier w(pwalletMain); CTxDestination dest = address.Get(); bool ret = boost::apply_visitor(w, dest); if (!ret) { @@ -1145,7 +1148,7 @@ struct tallyitem } }; -UniValue ListReceived(const UniValue& params, bool fByAccounts) +UniValue ListReceived(CWallet * const pwallet, const UniValue& params, bool fByAccounts) { // Minimum confirmations int nMinDepth = 1; @@ -1164,7 +1167,7 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts) // Tally map mapTally; - for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + for (map::iterator it = pwallet->mapWallet.begin(); it != pwallet->mapWallet.end(); ++it) { const CWalletTx& wtx = (*it).second; @@ -1181,7 +1184,7 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts) if (!ExtractDestination(txout.scriptPubKey, address)) continue; - isminefilter mine = IsMine(*pwalletMain, address); + isminefilter mine = IsMine(*pwallet, address); if(!(mine & filter)) continue; @@ -1197,7 +1200,7 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts) // Reply UniValue ret(UniValue::VARR); map mapAccountTally; - BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, CAddressBookData)& item, pwalletMain->mapAddressBook) + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, CAddressBookData)& item, pwallet->mapAddressBook) { const CBitcoinAddress& address = item.first; const string& strAccount = item.second.name; @@ -1267,7 +1270,7 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts) UniValue listreceivedbyaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 3) @@ -1304,12 +1307,12 @@ UniValue listreceivedbyaddress(const JSONRPCRequest& request) LOCK2(cs_main, pwalletMain->cs_wallet); - return ListReceived(request.params, false); + return ListReceived(pwalletMain, request.params, false); } UniValue listreceivedbyaccount(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 3) @@ -1341,7 +1344,7 @@ UniValue listreceivedbyaccount(const JSONRPCRequest& request) LOCK2(cs_main, pwalletMain->cs_wallet); - return ListReceived(request.params, true); + return ListReceived(pwalletMain, request.params, true); } static void MaybePushAddress(UniValue & entry, const CTxDestination &dest) @@ -1351,7 +1354,7 @@ static void MaybePushAddress(UniValue & entry, const CTxDestination &dest) entry.push_back(Pair("address", addr.ToString())); } -void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter) +void ListTransactions(CWallet * const pwallet, const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter) { CAmount nFee; string strSentAccount; @@ -1369,14 +1372,14 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe BOOST_FOREACH(const COutputEntry& s, listSent) { UniValue entry(UniValue::VOBJ); - if(involvesWatchonly || (::IsMine(*pwalletMain, s.destination) & ISMINE_WATCH_ONLY)) + if(involvesWatchonly || (::IsMine(*pwallet, s.destination) & ISMINE_WATCH_ONLY)) entry.push_back(Pair("involvesWatchonly", true)); entry.push_back(Pair("account", strSentAccount)); MaybePushAddress(entry, s.destination); entry.push_back(Pair("category", "send")); entry.push_back(Pair("amount", ValueFromAmount(-s.amount))); - if (pwalletMain->mapAddressBook.count(s.destination)) - entry.push_back(Pair("label", pwalletMain->mapAddressBook[s.destination].name)); + if (pwallet->mapAddressBook.count(s.destination)) + entry.push_back(Pair("label", pwallet->mapAddressBook[s.destination].name)); entry.push_back(Pair("vout", s.vout)); entry.push_back(Pair("fee", ValueFromAmount(-nFee))); if (fLong) @@ -1392,12 +1395,12 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe BOOST_FOREACH(const COutputEntry& r, listReceived) { string account; - if (pwalletMain->mapAddressBook.count(r.destination)) - account = pwalletMain->mapAddressBook[r.destination].name; + if (pwallet->mapAddressBook.count(r.destination)) + account = pwallet->mapAddressBook[r.destination].name; if (fAllAccounts || (account == strAccount)) { UniValue entry(UniValue::VOBJ); - if(involvesWatchonly || (::IsMine(*pwalletMain, r.destination) & ISMINE_WATCH_ONLY)) + if(involvesWatchonly || (::IsMine(*pwallet, r.destination) & ISMINE_WATCH_ONLY)) entry.push_back(Pair("involvesWatchonly", true)); entry.push_back(Pair("account", account)); MaybePushAddress(entry, r.destination); @@ -1415,7 +1418,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe entry.push_back(Pair("category", "receive")); } entry.push_back(Pair("amount", ValueFromAmount(r.amount))); - if (pwalletMain->mapAddressBook.count(r.destination)) + if (pwallet->mapAddressBook.count(r.destination)) entry.push_back(Pair("label", account)); entry.push_back(Pair("vout", r.vout)); if (fLong) @@ -1445,7 +1448,7 @@ void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Un UniValue listtransactions(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 4) @@ -1538,7 +1541,7 @@ UniValue listtransactions(const JSONRPCRequest& request) { CWalletTx *const pwtx = (*it).second.first; if (pwtx != 0) - ListTransactions(*pwtx, strAccount, 0, true, ret, filter); + ListTransactions(pwalletMain, *pwtx, strAccount, 0, true, ret, filter); CAccountingEntry *const pacentry = (*it).second.second; if (pacentry != 0) AcentryToJSON(*pacentry, strAccount, ret); @@ -1573,7 +1576,7 @@ UniValue listtransactions(const JSONRPCRequest& request) UniValue listaccounts(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 2) @@ -1652,7 +1655,7 @@ UniValue listaccounts(const JSONRPCRequest& request) UniValue listsinceblock(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp) @@ -1743,7 +1746,7 @@ UniValue listsinceblock(const JSONRPCRequest& request) CWalletTx tx = (*it).second; if (depth == -1 || tx.GetDepthInMainChain() < depth) - ListTransactions(tx, "*", 0, true, transactions, filter); + ListTransactions(pwalletMain, tx, "*", 0, true, transactions, filter); } CBlockIndex *pblockLast = chainActive[chainActive.Height() + 1 - target_confirms]; @@ -1758,7 +1761,7 @@ UniValue listsinceblock(const JSONRPCRequest& request) UniValue gettransaction(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) @@ -1833,7 +1836,7 @@ UniValue gettransaction(const JSONRPCRequest& request) WalletTxToJSON(wtx, entry); UniValue details(UniValue::VARR); - ListTransactions(wtx, "*", 0, false, details, filter); + ListTransactions(pwalletMain, wtx, "*", 0, false, details, filter); entry.push_back(Pair("details", details)); string strHex = EncodeHexTx(static_cast(wtx), RPCSerializationFlags()); @@ -1844,7 +1847,7 @@ UniValue gettransaction(const JSONRPCRequest& request) UniValue abandontransaction(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 1) @@ -1879,7 +1882,7 @@ UniValue abandontransaction(const JSONRPCRequest& request) UniValue backupwallet(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 1) @@ -1905,14 +1908,14 @@ UniValue backupwallet(const JSONRPCRequest& request) UniValue keypoolrefill(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 1) throw runtime_error( "keypoolrefill ( newsize )\n" "\nFills the keypool." - + HelpRequiringPassphrase() + "\n" + + HelpRequiringPassphrase(pwalletMain) + "\n" "\nArguments\n" "1. newsize (numeric, optional, default=100) The new keypool size\n" "\nExamples:\n" @@ -1930,7 +1933,7 @@ UniValue keypoolrefill(const JSONRPCRequest& request) kpSize = (unsigned int)request.params[0].get_int(); } - EnsureWalletIsUnlocked(); + EnsureWalletIsUnlocked(pwalletMain); pwalletMain->TopUpKeyPool(kpSize); if (pwalletMain->GetKeyPoolSize() < kpSize) @@ -1949,7 +1952,7 @@ static void LockWallet(CWallet* pWallet) UniValue walletpassphrase(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (pwalletMain->IsCrypted() && (request.fHelp || request.params.size() != 2)) @@ -2009,7 +2012,7 @@ UniValue walletpassphrase(const JSONRPCRequest& request) UniValue walletpassphrasechange(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (pwalletMain->IsCrypted() && (request.fHelp || request.params.size() != 2)) @@ -2055,7 +2058,7 @@ UniValue walletpassphrasechange(const JSONRPCRequest& request) UniValue walletlock(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (pwalletMain->IsCrypted() && (request.fHelp || request.params.size() != 0)) @@ -2094,7 +2097,7 @@ UniValue walletlock(const JSONRPCRequest& request) UniValue encryptwallet(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (!pwalletMain->IsCrypted() && (request.fHelp || request.params.size() != 1)) @@ -2151,7 +2154,7 @@ UniValue encryptwallet(const JSONRPCRequest& request) UniValue lockunspent(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) @@ -2240,7 +2243,7 @@ UniValue lockunspent(const JSONRPCRequest& request) UniValue listlockunspent(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 0) @@ -2289,7 +2292,7 @@ UniValue listlockunspent(const JSONRPCRequest& request) UniValue settxfee(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 1) @@ -2316,7 +2319,7 @@ UniValue settxfee(const JSONRPCRequest& request) UniValue getwalletinfo(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 0) @@ -2362,7 +2365,7 @@ UniValue getwalletinfo(const JSONRPCRequest& request) UniValue resendwallettransactions(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 0) @@ -2390,7 +2393,7 @@ UniValue resendwallettransactions(const JSONRPCRequest& request) UniValue listunspent(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 4) @@ -2514,7 +2517,7 @@ UniValue listunspent(const JSONRPCRequest& request) UniValue fundrawtransaction(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) + if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) @@ -2674,7 +2677,7 @@ UniValue fundrawtransaction(const JSONRPCRequest& request) // calculation, but we should be able to refactor after priority is removed). // NOTE: this requires that all inputs must be in mapWallet (eg the tx should // be IsAllFromMe). -int64_t CalculateMaximumSignedTxSize(const CTransaction &tx) +int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, CWallet &wallet) { CMutableTransaction txNew(tx); std::vector> vCoins; @@ -2682,11 +2685,11 @@ int64_t CalculateMaximumSignedTxSize(const CTransaction &tx) // IsAllFromMe(ISMINE_SPENDABLE), so every input should already be in our // wallet, with a valid index into the vout array. for (auto& input : tx.vin) { - const auto mi = pwalletMain->mapWallet.find(input.prevout.hash); - assert(mi != pwalletMain->mapWallet.end() && input.prevout.n < mi->second.tx->vout.size()); + const auto mi = wallet.mapWallet.find(input.prevout.hash); + assert(mi != wallet.mapWallet.end() && input.prevout.n < mi->second.tx->vout.size()); vCoins.emplace_back(make_pair(&(mi->second), input.prevout.n)); } - if (!pwalletMain->DummySignTx(txNew, vCoins)) { + if (!wallet.DummySignTx(txNew, vCoins)) { // This should never happen, because IsAllFromMe(ISMINE_SPENDABLE) // implies that we can sign for every input. throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction contains inputs that cannot be signed"); @@ -2802,7 +2805,7 @@ UniValue bumpfee(const JSONRPCRequest& request) // Calculate the expected size of the new transaction. int64_t txSize = GetVirtualTransactionSize(*(wtx.tx)); - const int64_t maxNewTxSize = CalculateMaximumSignedTxSize(*wtx.tx); + const int64_t maxNewTxSize = CalculateMaximumSignedTxSize(*wtx.tx, *pwallet); // optional parameters bool specifiedConfirmTarget = false; -- cgit v1.2.3 From d77ad6d41666b4c41abe1ba3b63300df1903643e Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 25 Oct 2016 07:45:57 +0000 Subject: RPC: Do all wallet access through new GetWalletForJSONRPCRequest --- src/rpc/misc.cpp | 42 ++-- src/rpc/rawtransaction.cpp | 14 +- src/rpc/server.h | 1 + src/wallet/rpcdump.cpp | 148 ++++++++------ src/wallet/rpcwallet.cpp | 480 ++++++++++++++++++++++++++------------------- 5 files changed, 400 insertions(+), 285 deletions(-) (limited to 'src') diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index f8e9acb08c..c9bbce856d 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -70,7 +70,9 @@ UniValue getinfo(const JSONRPCRequest& request) ); #ifdef ENABLE_WALLET - LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + LOCK2(cs_main, pwallet ? &pwallet->cs_wallet : NULL); #else LOCK(cs_main); #endif @@ -82,9 +84,9 @@ UniValue getinfo(const JSONRPCRequest& request) obj.push_back(Pair("version", CLIENT_VERSION)); obj.push_back(Pair("protocolversion", PROTOCOL_VERSION)); #ifdef ENABLE_WALLET - if (pwalletMain) { - obj.push_back(Pair("walletversion", pwalletMain->GetVersion())); - obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance()))); + if (pwallet) { + obj.push_back(Pair("walletversion", pwallet->GetVersion())); + obj.push_back(Pair("balance", ValueFromAmount(pwallet->GetBalance()))); } #endif obj.push_back(Pair("blocks", (int)chainActive.Height())); @@ -95,11 +97,11 @@ UniValue getinfo(const JSONRPCRequest& request) obj.push_back(Pair("difficulty", (double)GetDifficulty())); obj.push_back(Pair("testnet", Params().NetworkIDString() == CBaseChainParams::TESTNET)); #ifdef ENABLE_WALLET - if (pwalletMain) { - obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime())); - obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize())); + if (pwallet) { + obj.push_back(Pair("keypoololdest", pwallet->GetOldestKeyPoolTime())); + obj.push_back(Pair("keypoolsize", (int)pwallet->GetKeyPoolSize())); } - if (pwalletMain && pwalletMain->IsCrypted()) + if (pwallet && pwallet->IsCrypted()) obj.push_back(Pair("unlocked_until", nWalletUnlockTime)); obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK()))); #endif @@ -181,7 +183,9 @@ UniValue validateaddress(const JSONRPCRequest& request) ); #ifdef ENABLE_WALLET - LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL); + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + LOCK2(cs_main, pwallet ? &pwallet->cs_wallet : NULL); #else LOCK(cs_main); #endif @@ -201,16 +205,16 @@ UniValue validateaddress(const JSONRPCRequest& request) ret.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end()))); #ifdef ENABLE_WALLET - isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : ISMINE_NO; + isminetype mine = pwallet ? IsMine(*pwallet, dest) : ISMINE_NO; ret.push_back(Pair("ismine", (mine & ISMINE_SPENDABLE) ? true : false)); ret.push_back(Pair("iswatchonly", (mine & ISMINE_WATCH_ONLY) ? true: false)); - UniValue detail = boost::apply_visitor(DescribeAddressVisitor(pwalletMain), dest); + UniValue detail = boost::apply_visitor(DescribeAddressVisitor(pwallet), dest); ret.pushKVs(detail); - if (pwalletMain && pwalletMain->mapAddressBook.count(dest)) - ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name)); + if (pwallet && pwallet->mapAddressBook.count(dest)) + ret.push_back(Pair("account", pwallet->mapAddressBook[dest].name)); CKeyID keyID; - if (pwalletMain) { - const auto& meta = pwalletMain->mapKeyMetadata; + if (pwallet) { + const auto& meta = pwallet->mapKeyMetadata; auto it = address.GetKeyID(keyID) ? meta.find(keyID) : meta.end(); if (it == meta.end()) { it = meta.find(CScriptID(scriptPubKey)); @@ -294,6 +298,12 @@ CScript _createmultisig_redeemScript(CWallet * const pwallet, const UniValue& pa UniValue createmultisig(const JSONRPCRequest& request) { +#ifdef ENABLE_WALLET + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); +#else + CWallet * const pwallet = NULL; +#endif + if (request.fHelp || request.params.size() < 2 || request.params.size() > 2) { string msg = "createmultisig nrequired [\"key\",...]\n" @@ -324,7 +334,7 @@ UniValue createmultisig(const JSONRPCRequest& request) } // Construct using pay-to-script-hash: - CScript inner = _createmultisig_redeemScript(pwalletMain, request.params); + CScript inner = _createmultisig_redeemScript(pwallet, request.params); CScriptID innerID(inner); CBitcoinAddress address(innerID); diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index faafe9829b..5c75fecac8 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -594,6 +594,10 @@ static void TxInErrorToJSON(const CTxIn& txin, UniValue& vErrorsRet, const std:: UniValue signrawtransaction(const JSONRPCRequest& request) { +#ifdef ENABLE_WALLET + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); +#endif + if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) throw runtime_error( "signrawtransaction \"hexstring\" ( [{\"txid\":\"id\",\"vout\":n,\"scriptPubKey\":\"hex\",\"redeemScript\":\"hex\"},...] [\"privatekey1\",...] sighashtype )\n" @@ -603,7 +607,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request) "The third optional argument (may be null) is an array of base58-encoded private\n" "keys that, if given, will be the only keys used to sign the transaction.\n" #ifdef ENABLE_WALLET - + HelpRequiringPassphrase(pwalletMain) + "\n" + + HelpRequiringPassphrase(pwallet) + "\n" #endif "\nArguments:\n" @@ -654,7 +658,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request) ); #ifdef ENABLE_WALLET - LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL); + LOCK2(cs_main, pwallet ? &pwallet->cs_wallet : NULL); #else LOCK(cs_main); #endif @@ -717,8 +721,8 @@ UniValue signrawtransaction(const JSONRPCRequest& request) } } #ifdef ENABLE_WALLET - else if (pwalletMain) - EnsureWalletIsUnlocked(pwalletMain); + else if (pwallet) + EnsureWalletIsUnlocked(pwallet); #endif // Add previous txouts given in the RPC call: @@ -785,7 +789,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request) } #ifdef ENABLE_WALLET - const CKeyStore& keystore = ((fGivenKeys || !pwalletMain) ? tempKeystore : *pwalletMain); + const CKeyStore& keystore = ((fGivenKeys || !pwallet) ? tempKeystore : *pwallet); #else const CKeyStore& keystore = tempKeystore; #endif diff --git a/src/rpc/server.h b/src/rpc/server.h index b32eaaa133..b8f0373acc 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -202,6 +202,7 @@ class CWallet; #ifdef ENABLE_WALLET // New code should accessing the wallet should be under the ../wallet/ directory +CWallet *GetWalletForJSONRPCRequest(const JSONRPCRequest&); std::string HelpRequiringPassphrase(CWallet *); void EnsureWalletIsUnlocked(CWallet *); bool EnsureWalletIsAvailable(CWallet *, bool avoidException); diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 9f71d74e32..f0df76c92a 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -74,7 +74,9 @@ std::string DecodeDumpString(const std::string &str) { UniValue importprivkey(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 3) @@ -98,9 +100,9 @@ UniValue importprivkey(const JSONRPCRequest& request) ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); - EnsureWalletIsUnlocked(pwalletMain); + EnsureWalletIsUnlocked(pwallet); string strSecret = request.params[0].get_str(); string strLabel = ""; @@ -127,23 +129,23 @@ UniValue importprivkey(const JSONRPCRequest& request) assert(key.VerifyPubKey(pubkey)); CKeyID vchAddress = pubkey.GetID(); { - pwalletMain->MarkDirty(); - pwalletMain->SetAddressBook(vchAddress, strLabel, "receive"); + pwallet->MarkDirty(); + pwallet->SetAddressBook(vchAddress, strLabel, "receive"); // Don't throw error in case a key is already there - if (pwalletMain->HaveKey(vchAddress)) + if (pwallet->HaveKey(vchAddress)) return NullUniValue; - pwalletMain->mapKeyMetadata[vchAddress].nCreateTime = 1; + pwallet->mapKeyMetadata[vchAddress].nCreateTime = 1; - if (!pwalletMain->AddKeyPubKey(key, pubkey)) + if (!pwallet->AddKeyPubKey(key, pubkey)) throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet"); // whenever a key is imported, we need to scan the whole chain - pwalletMain->UpdateTimeFirstKey(1); + pwallet->UpdateTimeFirstKey(1); if (fRescan) { - pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true); + pwallet->ScanForWalletTransactions(chainActive.Genesis(), true); } } @@ -184,7 +186,9 @@ void ImportAddress(CWallet * const pwallet, const CBitcoinAddress& address, cons UniValue importaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) @@ -227,24 +231,24 @@ UniValue importaddress(const JSONRPCRequest& request) if (request.params.size() > 3) fP2SH = request.params[3].get_bool(); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); CBitcoinAddress address(request.params[0].get_str()); if (address.IsValid()) { if (fP2SH) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Cannot use the p2sh flag with an address - use a script instead"); - ImportAddress(pwalletMain, address, strLabel); + ImportAddress(pwallet, address, strLabel); } else if (IsHex(request.params[0].get_str())) { std::vector data(ParseHex(request.params[0].get_str())); - ImportScript(pwalletMain, CScript(data.begin(), data.end()), strLabel, fP2SH); + ImportScript(pwallet, CScript(data.begin(), data.end()), strLabel, fP2SH); } else { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address or script"); } if (fRescan) { - pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true); - pwalletMain->ReacceptWalletTransactions(); + pwallet->ScanForWalletTransactions(chainActive.Genesis(), true); + pwallet->ReacceptWalletTransactions(); } return NullUniValue; @@ -252,7 +256,9 @@ UniValue importaddress(const JSONRPCRequest& request) UniValue importprunedfunds(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 2) @@ -268,7 +274,7 @@ UniValue importprunedfunds(const JSONRPCRequest& request) if (!DecodeHexTx(tx, request.params[0].get_str())) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); uint256 hashTx = tx.GetHash(); - CWalletTx wtx(pwalletMain, MakeTransactionRef(std::move(tx))); + CWalletTx wtx(pwallet, MakeTransactionRef(std::move(tx))); CDataStream ssMB(ParseHexV(request.params[1], "proof"), SER_NETWORK, PROTOCOL_VERSION); CMerkleBlock merkleBlock; @@ -299,10 +305,10 @@ UniValue importprunedfunds(const JSONRPCRequest& request) wtx.nIndex = txnIndex; wtx.hashBlock = merkleBlock.header.GetHash(); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); - if (pwalletMain->IsMine(wtx)) { - pwalletMain->AddToWallet(wtx, false); + if (pwallet->IsMine(wtx)) { + pwallet->AddToWallet(wtx, false); return NullUniValue; } @@ -311,7 +317,9 @@ UniValue importprunedfunds(const JSONRPCRequest& request) UniValue removeprunedfunds(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 1) @@ -326,7 +334,7 @@ UniValue removeprunedfunds(const JSONRPCRequest& request) + HelpExampleRpc("removprunedfunds", "\"a8d0c0184dde994a09ec054286f1ce581bebf46446a512166eae7628734ea0a5\"") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); uint256 hash; hash.SetHex(request.params[0].get_str()); @@ -334,7 +342,7 @@ UniValue removeprunedfunds(const JSONRPCRequest& request) vHash.push_back(hash); vector vHashOut; - if(pwalletMain->ZapSelectTx(vHash, vHashOut) != DB_LOAD_OK) { + if(pwallet->ZapSelectTx(vHash, vHashOut) != DB_LOAD_OK) { throw JSONRPCError(RPC_INTERNAL_ERROR, "Could not properly delete the transaction."); } @@ -347,7 +355,9 @@ UniValue removeprunedfunds(const JSONRPCRequest& request) UniValue importpubkey(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) @@ -388,15 +398,15 @@ UniValue importpubkey(const JSONRPCRequest& request) if (!pubKey.IsFullyValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey is not a valid public key"); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); - ImportAddress(pwalletMain, CBitcoinAddress(pubKey.GetID()), strLabel); - ImportScript(pwalletMain, GetScriptForRawPubKey(pubKey), strLabel, false); + ImportAddress(pwallet, CBitcoinAddress(pubKey.GetID()), strLabel); + ImportScript(pwallet, GetScriptForRawPubKey(pubKey), strLabel, false); if (fRescan) { - pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true); - pwalletMain->ReacceptWalletTransactions(); + pwallet->ScanForWalletTransactions(chainActive.Genesis(), true); + pwallet->ReacceptWalletTransactions(); } return NullUniValue; @@ -405,7 +415,9 @@ UniValue importpubkey(const JSONRPCRequest& request) UniValue importwallet(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 1) @@ -426,9 +438,9 @@ UniValue importwallet(const JSONRPCRequest& request) if (fPruneMode) throw JSONRPCError(RPC_WALLET_ERROR, "Importing wallets is disabled in pruned mode"); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); - EnsureWalletIsUnlocked(pwalletMain); + EnsureWalletIsUnlocked(pwallet); ifstream file; file.open(request.params[0].get_str().c_str(), std::ios::in | std::ios::ate); @@ -442,9 +454,9 @@ UniValue importwallet(const JSONRPCRequest& request) int64_t nFilesize = std::max((int64_t)1, (int64_t)file.tellg()); file.seekg(0, file.beg); - pwalletMain->ShowProgress(_("Importing..."), 0); // show progress dialog in GUI + pwallet->ShowProgress(_("Importing..."), 0); // show progress dialog in GUI while (file.good()) { - pwalletMain->ShowProgress("", std::max(1, std::min(99, (int)(((double)file.tellg() / (double)nFilesize) * 100)))); + pwallet->ShowProgress("", std::max(1, std::min(99, (int)(((double)file.tellg() / (double)nFilesize) * 100)))); std::string line; std::getline(file, line); if (line.empty() || line[0] == '#') @@ -461,7 +473,7 @@ UniValue importwallet(const JSONRPCRequest& request) CPubKey pubkey = key.GetPubKey(); assert(key.VerifyPubKey(pubkey)); CKeyID keyid = pubkey.GetID(); - if (pwalletMain->HaveKey(keyid)) { + if (pwallet->HaveKey(keyid)) { LogPrintf("Skipping import of %s (key already present)\n", CBitcoinAddress(keyid).ToString()); continue; } @@ -481,27 +493,27 @@ UniValue importwallet(const JSONRPCRequest& request) } } LogPrintf("Importing %s...\n", CBitcoinAddress(keyid).ToString()); - if (!pwalletMain->AddKeyPubKey(key, pubkey)) { + if (!pwallet->AddKeyPubKey(key, pubkey)) { fGood = false; continue; } - pwalletMain->mapKeyMetadata[keyid].nCreateTime = nTime; + pwallet->mapKeyMetadata[keyid].nCreateTime = nTime; if (fLabel) - pwalletMain->SetAddressBook(keyid, strLabel, "receive"); + pwallet->SetAddressBook(keyid, strLabel, "receive"); nTimeBegin = std::min(nTimeBegin, nTime); } file.close(); - pwalletMain->ShowProgress("", 100); // hide progress dialog in GUI + pwallet->ShowProgress("", 100); // hide progress dialog in GUI CBlockIndex *pindex = chainActive.Tip(); while (pindex && pindex->pprev && pindex->GetBlockTime() > nTimeBegin - 7200) pindex = pindex->pprev; - pwalletMain->UpdateTimeFirstKey(nTimeBegin); + pwallet->UpdateTimeFirstKey(nTimeBegin); LogPrintf("Rescanning last %i blocks\n", chainActive.Height() - pindex->nHeight + 1); - pwalletMain->ScanForWalletTransactions(pindex); - pwalletMain->MarkDirty(); + pwallet->ScanForWalletTransactions(pindex); + pwallet->MarkDirty(); if (!fGood) throw JSONRPCError(RPC_WALLET_ERROR, "Error adding some keys to wallet"); @@ -511,7 +523,9 @@ UniValue importwallet(const JSONRPCRequest& request) UniValue dumpprivkey(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 1) @@ -529,9 +543,9 @@ UniValue dumpprivkey(const JSONRPCRequest& request) + HelpExampleRpc("dumpprivkey", "\"myaddress\"") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); - EnsureWalletIsUnlocked(pwalletMain); + EnsureWalletIsUnlocked(pwallet); string strAddress = request.params[0].get_str(); CBitcoinAddress address; @@ -541,7 +555,7 @@ UniValue dumpprivkey(const JSONRPCRequest& request) if (!address.GetKeyID(keyID)) throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to a key"); CKey vchSecret; - if (!pwalletMain->GetKey(keyID, vchSecret)) + if (!pwallet->GetKey(keyID, vchSecret)) throw JSONRPCError(RPC_WALLET_ERROR, "Private key for address " + strAddress + " is not known"); return CBitcoinSecret(vchSecret).ToString(); } @@ -549,7 +563,9 @@ UniValue dumpprivkey(const JSONRPCRequest& request) UniValue dumpwallet(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 1) @@ -563,9 +579,9 @@ UniValue dumpwallet(const JSONRPCRequest& request) + HelpExampleRpc("dumpwallet", "\"test\"") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); - EnsureWalletIsUnlocked(pwalletMain); + EnsureWalletIsUnlocked(pwallet); ofstream file; file.open(request.params[0].get_str().c_str()); @@ -574,8 +590,8 @@ UniValue dumpwallet(const JSONRPCRequest& request) std::map mapKeyBirth; std::set setKeyPool; - pwalletMain->GetKeyBirthTimes(mapKeyBirth); - pwalletMain->GetAllReserveKeys(setKeyPool); + pwallet->GetKeyBirthTimes(mapKeyBirth); + pwallet->GetAllReserveKeys(setKeyPool); // sort time/key pairs std::vector > vKeyBirth; @@ -595,11 +611,11 @@ UniValue dumpwallet(const JSONRPCRequest& request) file << "\n"; // add the base58check encoded extended master if the wallet uses HD - CKeyID masterKeyID = pwalletMain->GetHDChain().masterKeyID; + CKeyID masterKeyID = pwallet->GetHDChain().masterKeyID; if (!masterKeyID.IsNull()) { CKey key; - if (pwalletMain->GetKey(masterKeyID, key)) + if (pwallet->GetKey(masterKeyID, key)) { CExtKey masterKey; masterKey.SetMaster(key.begin(), key.size()); @@ -615,20 +631,20 @@ UniValue dumpwallet(const JSONRPCRequest& request) std::string strTime = EncodeDumpTime(it->first); std::string strAddr = CBitcoinAddress(keyid).ToString(); CKey key; - if (pwalletMain->GetKey(keyid, key)) { + if (pwallet->GetKey(keyid, key)) { file << strprintf("%s %s ", CBitcoinSecret(key).ToString(), strTime); - if (pwalletMain->mapAddressBook.count(keyid)) { - file << strprintf("label=%s", EncodeDumpString(pwalletMain->mapAddressBook[keyid].name)); + if (pwallet->mapAddressBook.count(keyid)) { + file << strprintf("label=%s", EncodeDumpString(pwallet->mapAddressBook[keyid].name)); } else if (keyid == masterKeyID) { file << "hdmaster=1"; } else if (setKeyPool.count(keyid)) { file << "reserve=1"; - } else if (pwalletMain->mapKeyMetadata[keyid].hdKeypath == "m") { + } else if (pwallet->mapKeyMetadata[keyid].hdKeypath == "m") { file << "inactivehdmaster=1"; } else { file << "change=1"; } - file << strprintf(" # addr=%s%s\n", strAddr, (pwalletMain->mapKeyMetadata[keyid].hdKeypath.size() > 0 ? " hdkeypath="+pwalletMain->mapKeyMetadata[keyid].hdKeypath : "")); + file << strprintf(" # addr=%s%s\n", strAddr, (pwallet->mapKeyMetadata[keyid].hdKeypath.size() > 0 ? " hdkeypath="+pwallet->mapKeyMetadata[keyid].hdKeypath : "")); } } file << "\n"; @@ -971,6 +987,8 @@ int64_t GetImportTimestamp(const UniValue& data, int64_t now) UniValue importmulti(const JSONRPCRequest& mainRequest) { + CWallet * const pwallet = GetWalletForJSONRPCRequest(mainRequest); + // clang-format off if (mainRequest.fHelp || mainRequest.params.size() < 1 || mainRequest.params.size() > 2) throw runtime_error( @@ -1009,7 +1027,7 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) " [{ \"success\": true } , { \"success\": false, \"error\": { \"code\": -1, \"message\": \"Internal Server Error\"} }, ... ]\n"); // clang-format on - if (!EnsureWalletIsAvailable(pwalletMain, mainRequest.fHelp)) { + if (!EnsureWalletIsAvailable(pwallet, mainRequest.fHelp)) { return NullUniValue; } @@ -1028,8 +1046,8 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) } } - LOCK2(cs_main, pwalletMain->cs_wallet); - EnsureWalletIsUnlocked(pwalletMain); + LOCK2(cs_main, pwallet->cs_wallet); + EnsureWalletIsUnlocked(pwallet); // Verify all timestamps are present before importing any keys. const int64_t now = chainActive.Tip() ? chainActive.Tip()->GetMedianTimePast() : 0; @@ -1051,7 +1069,7 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) BOOST_FOREACH (const UniValue& data, requests.getValues()) { const int64_t timestamp = std::max(GetImportTimestamp(data, now), minimumTimestamp); - const UniValue result = ProcessImport(pwalletMain, data, timestamp); + const UniValue result = ProcessImport(pwallet, data, timestamp); response.push_back(result); if (!fRescan) { @@ -1073,8 +1091,8 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) CBlockIndex* pindex = nLowestTimestamp > minimumTimestamp ? chainActive.FindEarliestAtLeast(std::max(nLowestTimestamp - 7200, 0)) : chainActive.Genesis(); CBlockIndex* scannedRange = nullptr; if (pindex) { - scannedRange = pwalletMain->ScanForWalletTransactions(pindex, true); - pwalletMain->ReacceptWalletTransactions(); + scannedRange = pwallet->ScanForWalletTransactions(pindex, true); + pwallet->ReacceptWalletTransactions(); } if (!scannedRange || scannedRange->nHeight > pindex->nHeight) { diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 179d42fca9..478d92cda3 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -32,6 +32,11 @@ using namespace std; int64_t nWalletUnlockTime; static CCriticalSection cs_nWalletUnlockTime; +CWallet *GetWalletForJSONRPCRequest(const JSONRPCRequest& request) +{ + return pwalletMain; +} + std::string HelpRequiringPassphrase(CWallet * const pwallet) { return pwallet && pwallet->IsCrypted() @@ -106,7 +111,9 @@ string AccountFromValue(const UniValue& value) UniValue getnewaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 1) @@ -124,23 +131,23 @@ UniValue getnewaddress(const JSONRPCRequest& request) + HelpExampleRpc("getnewaddress", "") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); // Parse the account first so we don't generate a key if there's an error string strAccount; if (request.params.size() > 0) strAccount = AccountFromValue(request.params[0]); - if (!pwalletMain->IsLocked()) - pwalletMain->TopUpKeyPool(); + if (!pwallet->IsLocked()) + pwallet->TopUpKeyPool(); // Generate a new key that is added to wallet CPubKey newKey; - if (!pwalletMain->GetKeyFromPool(newKey)) + if (!pwallet->GetKeyFromPool(newKey)) throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); CKeyID keyID = newKey.GetID(); - pwalletMain->SetAddressBook(keyID, strAccount, "receive"); + pwallet->SetAddressBook(keyID, strAccount, "receive"); return CBitcoinAddress(keyID).ToString(); } @@ -158,7 +165,9 @@ CBitcoinAddress GetAccountAddress(CWallet * const pwallet, string strAccount, bo UniValue getaccountaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 1) @@ -176,21 +185,23 @@ UniValue getaccountaddress(const JSONRPCRequest& request) + HelpExampleRpc("getaccountaddress", "\"myaccount\"") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); // Parse the account first so we don't generate a key if there's an error string strAccount = AccountFromValue(request.params[0]); UniValue ret(UniValue::VSTR); - ret = GetAccountAddress(pwalletMain, strAccount).ToString(); + ret = GetAccountAddress(pwallet, strAccount).ToString(); return ret; } UniValue getrawchangeaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 1) @@ -205,12 +216,12 @@ UniValue getrawchangeaddress(const JSONRPCRequest& request) + HelpExampleRpc("getrawchangeaddress", "") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); - if (!pwalletMain->IsLocked()) - pwalletMain->TopUpKeyPool(); + if (!pwallet->IsLocked()) + pwallet->TopUpKeyPool(); - CReserveKey reservekey(pwalletMain); + CReserveKey reservekey(pwallet); CPubKey vchPubKey; if (!reservekey.GetReservedKey(vchPubKey)) throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); @@ -225,7 +236,9 @@ UniValue getrawchangeaddress(const JSONRPCRequest& request) UniValue setaccount(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) @@ -240,7 +253,7 @@ UniValue setaccount(const JSONRPCRequest& request) + HelpExampleRpc("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"tabby\"") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); CBitcoinAddress address(request.params[0].get_str()); if (!address.IsValid()) @@ -251,16 +264,16 @@ UniValue setaccount(const JSONRPCRequest& request) strAccount = AccountFromValue(request.params[1]); // Only add the account if the address is yours. - if (IsMine(*pwalletMain, address.Get())) + if (IsMine(*pwallet, address.Get())) { // Detect when changing the account of an address that is the 'unused current key' of another account: - if (pwalletMain->mapAddressBook.count(address.Get())) + if (pwallet->mapAddressBook.count(address.Get())) { - string strOldAccount = pwalletMain->mapAddressBook[address.Get()].name; - if (address == GetAccountAddress(pwalletMain, strOldAccount)) - GetAccountAddress(pwalletMain, strOldAccount, true); + string strOldAccount = pwallet->mapAddressBook[address.Get()].name; + if (address == GetAccountAddress(pwallet, strOldAccount)) + GetAccountAddress(pwallet, strOldAccount, true); } - pwalletMain->SetAddressBook(address.Get(), strAccount, "receive"); + pwallet->SetAddressBook(address.Get(), strAccount, "receive"); } else throw JSONRPCError(RPC_MISC_ERROR, "setaccount can only be used with own address"); @@ -271,7 +284,9 @@ UniValue setaccount(const JSONRPCRequest& request) UniValue getaccount(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 1) @@ -287,15 +302,15 @@ UniValue getaccount(const JSONRPCRequest& request) + HelpExampleRpc("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\"") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); CBitcoinAddress address(request.params[0].get_str()); if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); string strAccount; - map::iterator mi = pwalletMain->mapAddressBook.find(address.Get()); - if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.name.empty()) + map::iterator mi = pwallet->mapAddressBook.find(address.Get()); + if (mi != pwallet->mapAddressBook.end() && !(*mi).second.name.empty()) strAccount = (*mi).second.name; return strAccount; } @@ -303,7 +318,9 @@ UniValue getaccount(const JSONRPCRequest& request) UniValue getaddressesbyaccount(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 1) @@ -322,13 +339,13 @@ UniValue getaddressesbyaccount(const JSONRPCRequest& request) + HelpExampleRpc("getaddressesbyaccount", "\"tabby\"") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); string strAccount = AccountFromValue(request.params[0]); // Find all addresses that have the given account UniValue ret(UniValue::VARR); - BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, CAddressBookData)& item, pwalletMain->mapAddressBook) + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, CAddressBookData)& item, pwallet->mapAddressBook) { const CBitcoinAddress& address = item.first; const string& strName = item.second.name; @@ -377,14 +394,16 @@ static void SendMoney(CWallet * const pwallet, const CTxDestination &address, CA UniValue sendtoaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 2 || request.params.size() > 5) throw runtime_error( "sendtoaddress \"address\" amount ( \"comment\" \"comment_to\" subtractfeefromamount )\n" "\nSend an amount to a given address.\n" - + HelpRequiringPassphrase(pwalletMain) + + + HelpRequiringPassphrase(pwallet) + "\nArguments:\n" "1. \"address\" (string, required) The bitcoin address to send to.\n" "2. \"amount\" (numeric or string, required) The amount in " + CURRENCY_UNIT + " to send. eg 0.1\n" @@ -404,7 +423,7 @@ UniValue sendtoaddress(const JSONRPCRequest& request) + HelpExampleRpc("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.1, \"donation\", \"seans outpost\"") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); CBitcoinAddress address(request.params[0].get_str()); if (!address.IsValid()) @@ -426,16 +445,18 @@ UniValue sendtoaddress(const JSONRPCRequest& request) if (request.params.size() > 4) fSubtractFeeFromAmount = request.params[4].get_bool(); - EnsureWalletIsUnlocked(pwalletMain); + EnsureWalletIsUnlocked(pwallet); - SendMoney(pwalletMain, address.Get(), nAmount, fSubtractFeeFromAmount, wtx); + SendMoney(pwallet, address.Get(), nAmount, fSubtractFeeFromAmount, wtx); return wtx.GetHash().GetHex(); } UniValue listaddressgroupings(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp) @@ -461,11 +482,11 @@ UniValue listaddressgroupings(const JSONRPCRequest& request) + HelpExampleRpc("listaddressgroupings", "") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); UniValue jsonGroupings(UniValue::VARR); - map balances = pwalletMain->GetAddressBalances(); - BOOST_FOREACH(set grouping, pwalletMain->GetAddressGroupings()) + map balances = pwallet->GetAddressBalances(); + BOOST_FOREACH(set grouping, pwallet->GetAddressGroupings()) { UniValue jsonGrouping(UniValue::VARR); BOOST_FOREACH(CTxDestination address, grouping) @@ -474,8 +495,8 @@ UniValue listaddressgroupings(const JSONRPCRequest& request) addressInfo.push_back(CBitcoinAddress(address).ToString()); addressInfo.push_back(ValueFromAmount(balances[address])); { - if (pwalletMain->mapAddressBook.find(CBitcoinAddress(address).Get()) != pwalletMain->mapAddressBook.end()) - addressInfo.push_back(pwalletMain->mapAddressBook.find(CBitcoinAddress(address).Get())->second.name); + if (pwallet->mapAddressBook.find(CBitcoinAddress(address).Get()) != pwallet->mapAddressBook.end()) + addressInfo.push_back(pwallet->mapAddressBook.find(CBitcoinAddress(address).Get())->second.name); } jsonGrouping.push_back(addressInfo); } @@ -486,14 +507,16 @@ UniValue listaddressgroupings(const JSONRPCRequest& request) UniValue signmessage(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 2) throw runtime_error( "signmessage \"address\" \"message\"\n" "\nSign a message with the private key of an address" - + HelpRequiringPassphrase(pwalletMain) + "\n" + + HelpRequiringPassphrase(pwallet) + "\n" "\nArguments:\n" "1. \"address\" (string, required) The bitcoin address to use for the private key.\n" "2. \"message\" (string, required) The message to create a signature of.\n" @@ -510,9 +533,9 @@ UniValue signmessage(const JSONRPCRequest& request) + HelpExampleRpc("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"my message\"") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); - EnsureWalletIsUnlocked(pwalletMain); + EnsureWalletIsUnlocked(pwallet); string strAddress = request.params[0].get_str(); string strMessage = request.params[1].get_str(); @@ -526,7 +549,7 @@ UniValue signmessage(const JSONRPCRequest& request) throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key"); CKey key; - if (!pwalletMain->GetKey(keyID, key)) + if (!pwallet->GetKey(keyID, key)) throw JSONRPCError(RPC_WALLET_ERROR, "Private key not available"); CHashWriter ss(SER_GETHASH, 0); @@ -542,7 +565,9 @@ UniValue signmessage(const JSONRPCRequest& request) UniValue getreceivedbyaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) @@ -565,14 +590,14 @@ UniValue getreceivedbyaddress(const JSONRPCRequest& request) + HelpExampleRpc("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", 6") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); // Bitcoin address CBitcoinAddress address = CBitcoinAddress(request.params[0].get_str()); if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); CScript scriptPubKey = GetScriptForDestination(address.Get()); - if (!IsMine(*pwalletMain, scriptPubKey)) + if (!IsMine(*pwallet, scriptPubKey)) return ValueFromAmount(0); // Minimum confirmations @@ -582,7 +607,7 @@ UniValue getreceivedbyaddress(const JSONRPCRequest& request) // Tally CAmount nAmount = 0; - for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + for (map::iterator it = pwallet->mapWallet.begin(); it != pwallet->mapWallet.end(); ++it) { const CWalletTx& wtx = (*it).second; if (wtx.IsCoinBase() || !CheckFinalTx(*wtx.tx)) @@ -600,7 +625,9 @@ UniValue getreceivedbyaddress(const JSONRPCRequest& request) UniValue getreceivedbyaccount(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) @@ -623,7 +650,7 @@ UniValue getreceivedbyaccount(const JSONRPCRequest& request) + HelpExampleRpc("getreceivedbyaccount", "\"tabby\", 6") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); // Minimum confirmations int nMinDepth = 1; @@ -632,11 +659,11 @@ UniValue getreceivedbyaccount(const JSONRPCRequest& request) // Get the set of pub keys assigned to account string strAccount = AccountFromValue(request.params[0]); - set setAddress = pwalletMain->GetAccountAddresses(strAccount); + set setAddress = pwallet->GetAccountAddresses(strAccount); // Tally CAmount nAmount = 0; - for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + for (map::iterator it = pwallet->mapWallet.begin(); it != pwallet->mapWallet.end(); ++it) { const CWalletTx& wtx = (*it).second; if (wtx.IsCoinBase() || !CheckFinalTx(*wtx.tx)) @@ -645,7 +672,7 @@ UniValue getreceivedbyaccount(const JSONRPCRequest& request) BOOST_FOREACH(const CTxOut& txout, wtx.tx->vout) { CTxDestination address; - if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*pwalletMain, address) && setAddress.count(address)) + if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*pwallet, address) && setAddress.count(address)) if (wtx.GetDepthInMainChain() >= nMinDepth) nAmount += txout.nValue; } @@ -657,7 +684,9 @@ UniValue getreceivedbyaccount(const JSONRPCRequest& request) UniValue getbalance(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 3) @@ -693,10 +722,10 @@ UniValue getbalance(const JSONRPCRequest& request) + HelpExampleRpc("getbalance", "\"*\", 6") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); if (request.params.size() == 0) - return ValueFromAmount(pwalletMain->GetBalance()); + return ValueFromAmount(pwallet->GetBalance()); int nMinDepth = 1; if (request.params.size() > 1) @@ -714,7 +743,7 @@ UniValue getbalance(const JSONRPCRequest& request) // TxIns spending from the wallet. This also has fewer restrictions on // which unconfirmed transactions are considered trusted. CAmount nBalance = 0; - for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + for (map::iterator it = pwallet->mapWallet.begin(); it != pwallet->mapWallet.end(); ++it) { const CWalletTx& wtx = (*it).second; if (!CheckFinalTx(wtx) || wtx.GetBlocksToMaturity() > 0 || wtx.GetDepthInMainChain() < 0) @@ -739,14 +768,16 @@ UniValue getbalance(const JSONRPCRequest& request) string strAccount = AccountFromValue(request.params[0]); - CAmount nBalance = pwalletMain->GetAccountBalance(strAccount, nMinDepth, filter); + CAmount nBalance = pwallet->GetAccountBalance(strAccount, nMinDepth, filter); return ValueFromAmount(nBalance); } UniValue getunconfirmedbalance(const JSONRPCRequest &request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 0) @@ -754,15 +785,17 @@ UniValue getunconfirmedbalance(const JSONRPCRequest &request) "getunconfirmedbalance\n" "Returns the server's total unconfirmed balance\n"); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); - return ValueFromAmount(pwalletMain->GetUnconfirmedBalance()); + return ValueFromAmount(pwallet->GetUnconfirmedBalance()); } UniValue movecmd(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 3 || request.params.size() > 5) @@ -786,7 +819,7 @@ UniValue movecmd(const JSONRPCRequest& request) + HelpExampleRpc("move", "\"timotei\", \"akiko\", 0.01, 6, \"happy birthday!\"") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); string strFrom = AccountFromValue(request.params[0]); string strTo = AccountFromValue(request.params[1]); @@ -800,7 +833,7 @@ UniValue movecmd(const JSONRPCRequest& request) if (request.params.size() > 4) strComment = request.params[4].get_str(); - if (!pwalletMain->AccountMove(strFrom, strTo, nAmount, strComment)) + if (!pwallet->AccountMove(strFrom, strTo, nAmount, strComment)) throw JSONRPCError(RPC_DATABASE_ERROR, "database error"); return true; @@ -809,14 +842,16 @@ UniValue movecmd(const JSONRPCRequest& request) UniValue sendfrom(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 3 || request.params.size() > 6) throw runtime_error( "sendfrom \"fromaccount\" \"toaddress\" amount ( minconf \"comment\" \"comment_to\" )\n" "\nDEPRECATED (use sendtoaddress). Sent an amount from an account to a bitcoin address." - + HelpRequiringPassphrase(pwalletMain) + "\n" + + HelpRequiringPassphrase(pwallet) + "\n" "\nArguments:\n" "1. \"fromaccount\" (string, required) The name of the account to send funds from. May be the default account using \"\".\n" " Specifying an account does not influence coin selection, but it does associate the newly created\n" @@ -841,7 +876,7 @@ UniValue sendfrom(const JSONRPCRequest& request) + HelpExampleRpc("sendfrom", "\"tabby\", \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.01, 6, \"donation\", \"seans outpost\"") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); string strAccount = AccountFromValue(request.params[0]); CBitcoinAddress address(request.params[1].get_str()); @@ -861,14 +896,14 @@ UniValue sendfrom(const JSONRPCRequest& request) if (request.params.size() > 5 && !request.params[5].isNull() && !request.params[5].get_str().empty()) wtx.mapValue["to"] = request.params[5].get_str(); - EnsureWalletIsUnlocked(pwalletMain); + EnsureWalletIsUnlocked(pwallet); // Check funds - CAmount nBalance = pwalletMain->GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE); + CAmount nBalance = pwallet->GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE); if (nAmount > nBalance) throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds"); - SendMoney(pwalletMain, address.Get(), nAmount, false, wtx); + SendMoney(pwallet, address.Get(), nAmount, false, wtx); return wtx.GetHash().GetHex(); } @@ -876,14 +911,16 @@ UniValue sendfrom(const JSONRPCRequest& request) UniValue sendmany(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 2 || request.params.size() > 5) throw runtime_error( "sendmany \"fromaccount\" {\"address\":amount,...} ( minconf \"comment\" [\"address\",...] )\n" "\nSend multiple times. Amounts are double-precision floating point numbers." - + HelpRequiringPassphrase(pwalletMain) + "\n" + + HelpRequiringPassphrase(pwallet) + "\n" "\nArguments:\n" "1. \"fromaccount\" (string, required) DEPRECATED. The account to send the funds from. Should be \"\" for the default account\n" "2. \"amounts\" (string, required) A json object with addresses and amounts\n" @@ -915,9 +952,9 @@ UniValue sendmany(const JSONRPCRequest& request) + HelpExampleRpc("sendmany", "\"\", \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\", 6, \"testing\"") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); - if (pwalletMain->GetBroadcastTransactions() && !g_connman) + if (pwallet->GetBroadcastTransactions() && !g_connman) throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); string strAccount = AccountFromValue(request.params[0]); @@ -967,23 +1004,23 @@ UniValue sendmany(const JSONRPCRequest& request) vecSend.push_back(recipient); } - EnsureWalletIsUnlocked(pwalletMain); + EnsureWalletIsUnlocked(pwallet); // Check funds - CAmount nBalance = pwalletMain->GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE); + CAmount nBalance = pwallet->GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE); if (totalAmount > nBalance) throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds"); // Send - CReserveKey keyChange(pwalletMain); + CReserveKey keyChange(pwallet); CAmount nFeeRequired = 0; int nChangePosRet = -1; string strFailReason; - bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, nChangePosRet, strFailReason); + bool fCreated = pwallet->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, nChangePosRet, strFailReason); if (!fCreated) throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason); CValidationState state; - if (!pwalletMain->CommitTransaction(wtx, keyChange, g_connman.get(), state)) { + if (!pwallet->CommitTransaction(wtx, keyChange, g_connman.get(), state)) { strFailReason = strprintf("Transaction commit failed:: %s", state.GetRejectReason()); throw JSONRPCError(RPC_WALLET_ERROR, strFailReason); } @@ -996,7 +1033,9 @@ extern CScript _createmultisig_redeemScript(CWallet * const pwallet, const UniVa UniValue addmultisigaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 2 || request.params.size() > 3) @@ -1027,18 +1066,18 @@ UniValue addmultisigaddress(const JSONRPCRequest& request) throw runtime_error(msg); } - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); string strAccount; if (request.params.size() > 2) strAccount = AccountFromValue(request.params[2]); // Construct using pay-to-script-hash: - CScript inner = _createmultisig_redeemScript(pwalletMain, request.params); + CScript inner = _createmultisig_redeemScript(pwallet, request.params); CScriptID innerID(inner); - pwalletMain->AddCScript(inner); + pwallet->AddCScript(inner); - pwalletMain->SetAddressBook(innerID, strAccount, "send"); + pwallet->SetAddressBook(innerID, strAccount, "send"); return CBitcoinAddress(innerID).ToString(); } @@ -1092,7 +1131,9 @@ public: UniValue addwitnessaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 1) @@ -1122,14 +1163,14 @@ UniValue addwitnessaddress(const JSONRPCRequest& request) if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); - Witnessifier w(pwalletMain); + Witnessifier w(pwallet); CTxDestination dest = address.Get(); 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"); } - pwalletMain->SetAddressBook(w.result, "", "receive"); + pwallet->SetAddressBook(w.result, "", "receive"); return CBitcoinAddress(w.result).ToString(); } @@ -1270,7 +1311,9 @@ UniValue ListReceived(CWallet * const pwallet, const UniValue& params, bool fByA UniValue listreceivedbyaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 3) @@ -1305,14 +1348,16 @@ UniValue listreceivedbyaddress(const JSONRPCRequest& request) + HelpExampleRpc("listreceivedbyaddress", "6, true, true") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); - return ListReceived(pwalletMain, request.params, false); + return ListReceived(pwallet, request.params, false); } UniValue listreceivedbyaccount(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 3) @@ -1342,9 +1387,9 @@ UniValue listreceivedbyaccount(const JSONRPCRequest& request) + HelpExampleRpc("listreceivedbyaccount", "6, true, true") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); - return ListReceived(pwalletMain, request.params, true); + return ListReceived(pwallet, request.params, true); } static void MaybePushAddress(UniValue & entry, const CTxDestination &dest) @@ -1448,7 +1493,9 @@ void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Un UniValue listtransactions(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 4) @@ -1511,7 +1558,7 @@ UniValue listtransactions(const JSONRPCRequest& request) + HelpExampleRpc("listtransactions", "\"*\", 20, 100") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); string strAccount = "*"; if (request.params.size() > 0) @@ -1534,14 +1581,14 @@ UniValue listtransactions(const JSONRPCRequest& request) UniValue ret(UniValue::VARR); - const CWallet::TxItems & txOrdered = pwalletMain->wtxOrdered; + const CWallet::TxItems & txOrdered = pwallet->wtxOrdered; // iterate backwards until we have nCount items to return: for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) { CWalletTx *const pwtx = (*it).second.first; if (pwtx != 0) - ListTransactions(pwalletMain, *pwtx, strAccount, 0, true, ret, filter); + ListTransactions(pwallet, *pwtx, strAccount, 0, true, ret, filter); CAccountingEntry *const pacentry = (*it).second.second; if (pacentry != 0) AcentryToJSON(*pacentry, strAccount, ret); @@ -1576,7 +1623,9 @@ UniValue listtransactions(const JSONRPCRequest& request) UniValue listaccounts(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 2) @@ -1602,7 +1651,7 @@ UniValue listaccounts(const JSONRPCRequest& request) + HelpExampleRpc("listaccounts", "6") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); int nMinDepth = 1; if (request.params.size() > 0) @@ -1613,12 +1662,12 @@ UniValue listaccounts(const JSONRPCRequest& request) includeWatchonly = includeWatchonly | ISMINE_WATCH_ONLY; map mapAccountBalances; - BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& entry, pwalletMain->mapAddressBook) { - if (IsMine(*pwalletMain, entry.first) & includeWatchonly) // This address belongs to me + BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& entry, pwallet->mapAddressBook) { + if (IsMine(*pwallet, entry.first) & includeWatchonly) // This address belongs to me mapAccountBalances[entry.second.name] = 0; } - for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + for (map::iterator it = pwallet->mapWallet.begin(); it != pwallet->mapWallet.end(); ++it) { const CWalletTx& wtx = (*it).second; CAmount nFee; @@ -1635,14 +1684,14 @@ UniValue listaccounts(const JSONRPCRequest& request) if (nDepth >= nMinDepth) { BOOST_FOREACH(const COutputEntry& r, listReceived) - if (pwalletMain->mapAddressBook.count(r.destination)) - mapAccountBalances[pwalletMain->mapAddressBook[r.destination].name] += r.amount; + if (pwallet->mapAddressBook.count(r.destination)) + mapAccountBalances[pwallet->mapAddressBook[r.destination].name] += r.amount; else mapAccountBalances[""] += r.amount; } } - const list & acentries = pwalletMain->laccentries; + const list & acentries = pwallet->laccentries; BOOST_FOREACH(const CAccountingEntry& entry, acentries) mapAccountBalances[entry.strAccount] += entry.nCreditDebit; @@ -1655,7 +1704,9 @@ UniValue listaccounts(const JSONRPCRequest& request) UniValue listsinceblock(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp) @@ -1699,7 +1750,7 @@ UniValue listsinceblock(const JSONRPCRequest& request) + HelpExampleRpc("listsinceblock", "\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\", 6") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); const CBlockIndex *pindex = NULL; int target_confirms = 1; @@ -1741,12 +1792,12 @@ UniValue listsinceblock(const JSONRPCRequest& request) UniValue transactions(UniValue::VARR); - for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); it++) + for (map::iterator it = pwallet->mapWallet.begin(); it != pwallet->mapWallet.end(); it++) { CWalletTx tx = (*it).second; if (depth == -1 || tx.GetDepthInMainChain() < depth) - ListTransactions(pwalletMain, tx, "*", 0, true, transactions, filter); + ListTransactions(pwallet, tx, "*", 0, true, transactions, filter); } CBlockIndex *pblockLast = chainActive[chainActive.Height() + 1 - target_confirms]; @@ -1761,7 +1812,9 @@ UniValue listsinceblock(const JSONRPCRequest& request) UniValue gettransaction(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) @@ -1809,7 +1862,7 @@ UniValue gettransaction(const JSONRPCRequest& request) + HelpExampleRpc("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); uint256 hash; hash.SetHex(request.params[0].get_str()); @@ -1820,9 +1873,9 @@ UniValue gettransaction(const JSONRPCRequest& request) filter = filter | ISMINE_WATCH_ONLY; UniValue entry(UniValue::VOBJ); - if (!pwalletMain->mapWallet.count(hash)) + if (!pwallet->mapWallet.count(hash)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id"); - const CWalletTx& wtx = pwalletMain->mapWallet[hash]; + const CWalletTx& wtx = pwallet->mapWallet[hash]; CAmount nCredit = wtx.GetCredit(filter); CAmount nDebit = wtx.GetDebit(filter); @@ -1836,7 +1889,7 @@ UniValue gettransaction(const JSONRPCRequest& request) WalletTxToJSON(wtx, entry); UniValue details(UniValue::VARR); - ListTransactions(pwalletMain, wtx, "*", 0, false, details, filter); + ListTransactions(pwallet, wtx, "*", 0, false, details, filter); entry.push_back(Pair("details", details)); string strHex = EncodeHexTx(static_cast(wtx), RPCSerializationFlags()); @@ -1847,7 +1900,9 @@ UniValue gettransaction(const JSONRPCRequest& request) UniValue abandontransaction(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 1) @@ -1866,14 +1921,14 @@ UniValue abandontransaction(const JSONRPCRequest& request) + HelpExampleRpc("abandontransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); uint256 hash; hash.SetHex(request.params[0].get_str()); - if (!pwalletMain->mapWallet.count(hash)) + if (!pwallet->mapWallet.count(hash)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id"); - if (!pwalletMain->AbandonTransaction(hash)) + if (!pwallet->AbandonTransaction(hash)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not eligible for abandonment"); return NullUniValue; @@ -1882,7 +1937,9 @@ UniValue abandontransaction(const JSONRPCRequest& request) UniValue backupwallet(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 1) @@ -1896,10 +1953,10 @@ UniValue backupwallet(const JSONRPCRequest& request) + HelpExampleRpc("backupwallet", "\"backup.dat\"") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); string strDest = request.params[0].get_str(); - if (!pwalletMain->BackupWallet(strDest)) + if (!pwallet->BackupWallet(strDest)) throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!"); return NullUniValue; @@ -1908,14 +1965,16 @@ UniValue backupwallet(const JSONRPCRequest& request) UniValue keypoolrefill(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 1) throw runtime_error( "keypoolrefill ( newsize )\n" "\nFills the keypool." - + HelpRequiringPassphrase(pwalletMain) + "\n" + + HelpRequiringPassphrase(pwallet) + "\n" "\nArguments\n" "1. newsize (numeric, optional, default=100) The new keypool size\n" "\nExamples:\n" @@ -1923,7 +1982,7 @@ UniValue keypoolrefill(const JSONRPCRequest& request) + HelpExampleRpc("keypoolrefill", "") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); // 0 is interpreted by TopUpKeyPool() as the default keypool size given by -keypool unsigned int kpSize = 0; @@ -1933,10 +1992,10 @@ UniValue keypoolrefill(const JSONRPCRequest& request) kpSize = (unsigned int)request.params[0].get_int(); } - EnsureWalletIsUnlocked(pwalletMain); - pwalletMain->TopUpKeyPool(kpSize); + EnsureWalletIsUnlocked(pwallet); + pwallet->TopUpKeyPool(kpSize); - if (pwalletMain->GetKeyPoolSize() < kpSize) + if (pwallet->GetKeyPoolSize() < kpSize) throw JSONRPCError(RPC_WALLET_ERROR, "Error refreshing keypool."); return NullUniValue; @@ -1952,10 +2011,12 @@ static void LockWallet(CWallet* pWallet) UniValue walletpassphrase(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; - if (pwalletMain->IsCrypted() && (request.fHelp || request.params.size() != 2)) + if (pwallet->IsCrypted() && (request.fHelp || request.params.size() != 2)) throw runtime_error( "walletpassphrase \"passphrase\" timeout\n" "\nStores the wallet decryption key in memory for 'timeout' seconds.\n" @@ -1975,11 +2036,11 @@ UniValue walletpassphrase(const JSONRPCRequest& request) + HelpExampleRpc("walletpassphrase", "\"my pass phrase\", 60") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); if (request.fHelp) return true; - if (!pwalletMain->IsCrypted()) + if (!pwallet->IsCrypted()) throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrase was called."); // Note that the walletpassphrase is stored in request.params[0] which is not mlock()ed @@ -1991,7 +2052,7 @@ UniValue walletpassphrase(const JSONRPCRequest& request) if (strWalletPass.length() > 0) { - if (!pwalletMain->Unlock(strWalletPass)) + if (!pwallet->Unlock(strWalletPass)) throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect."); } else @@ -1999,12 +2060,12 @@ UniValue walletpassphrase(const JSONRPCRequest& request) "walletpassphrase \n" "Stores the wallet decryption key in memory for seconds."); - pwalletMain->TopUpKeyPool(); + pwallet->TopUpKeyPool(); int64_t nSleepTime = request.params[1].get_int64(); LOCK(cs_nWalletUnlockTime); nWalletUnlockTime = GetTime() + nSleepTime; - RPCRunLater("lockwallet", boost::bind(LockWallet, pwalletMain), nSleepTime); + RPCRunLater("lockwallet", boost::bind(LockWallet, pwallet), nSleepTime); return NullUniValue; } @@ -2012,10 +2073,12 @@ UniValue walletpassphrase(const JSONRPCRequest& request) UniValue walletpassphrasechange(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; - if (pwalletMain->IsCrypted() && (request.fHelp || request.params.size() != 2)) + if (pwallet->IsCrypted() && (request.fHelp || request.params.size() != 2)) throw runtime_error( "walletpassphrasechange \"oldpassphrase\" \"newpassphrase\"\n" "\nChanges the wallet passphrase from 'oldpassphrase' to 'newpassphrase'.\n" @@ -2027,11 +2090,11 @@ UniValue walletpassphrasechange(const JSONRPCRequest& request) + HelpExampleRpc("walletpassphrasechange", "\"old one\", \"new one\"") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); if (request.fHelp) return true; - if (!pwalletMain->IsCrypted()) + if (!pwallet->IsCrypted()) throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrasechange was called."); // TODO: get rid of these .c_str() calls by implementing SecureString::operator=(std::string) @@ -2049,7 +2112,7 @@ UniValue walletpassphrasechange(const JSONRPCRequest& request) "walletpassphrasechange \n" "Changes the wallet passphrase from to ."); - if (!pwalletMain->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass)) + if (!pwallet->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass)) throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect."); return NullUniValue; @@ -2058,10 +2121,12 @@ UniValue walletpassphrasechange(const JSONRPCRequest& request) UniValue walletlock(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; - if (pwalletMain->IsCrypted() && (request.fHelp || request.params.size() != 0)) + if (pwallet->IsCrypted() && (request.fHelp || request.params.size() != 0)) throw runtime_error( "walletlock\n" "\nRemoves the wallet encryption key from memory, locking the wallet.\n" @@ -2078,16 +2143,16 @@ UniValue walletlock(const JSONRPCRequest& request) + HelpExampleRpc("walletlock", "") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); if (request.fHelp) return true; - if (!pwalletMain->IsCrypted()) + if (!pwallet->IsCrypted()) throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletlock was called."); { LOCK(cs_nWalletUnlockTime); - pwalletMain->Lock(); + pwallet->Lock(); nWalletUnlockTime = 0; } @@ -2097,10 +2162,12 @@ UniValue walletlock(const JSONRPCRequest& request) UniValue encryptwallet(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; - if (!pwalletMain->IsCrypted() && (request.fHelp || request.params.size() != 1)) + if (!pwallet->IsCrypted() && (request.fHelp || request.params.size() != 1)) throw runtime_error( "encryptwallet \"passphrase\"\n" "\nEncrypts the wallet with 'passphrase'. This is for first time encryption.\n" @@ -2124,11 +2191,11 @@ UniValue encryptwallet(const JSONRPCRequest& request) + HelpExampleRpc("encryptwallet", "\"my pass phrase\"") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); if (request.fHelp) return true; - if (pwalletMain->IsCrypted()) + if (pwallet->IsCrypted()) throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an encrypted wallet, but encryptwallet was called."); // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string) @@ -2142,7 +2209,7 @@ UniValue encryptwallet(const JSONRPCRequest& request) "encryptwallet \n" "Encrypts the wallet with ."); - if (!pwalletMain->EncryptWallet(strWalletPass)) + if (!pwallet->EncryptWallet(strWalletPass)) throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Error: Failed to encrypt the wallet."); // BDB seems to have a bad habit of writing old data into @@ -2154,7 +2221,9 @@ UniValue encryptwallet(const JSONRPCRequest& request) UniValue lockunspent(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) @@ -2194,7 +2263,7 @@ UniValue lockunspent(const JSONRPCRequest& request) + HelpExampleRpc("lockunspent", "false, \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); if (request.params.size() == 1) RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VBOOL)); @@ -2205,7 +2274,7 @@ UniValue lockunspent(const JSONRPCRequest& request) if (request.params.size() == 1) { if (fUnlock) - pwalletMain->UnlockAllCoins(); + pwallet->UnlockAllCoins(); return true; } @@ -2233,9 +2302,9 @@ UniValue lockunspent(const JSONRPCRequest& request) COutPoint outpt(uint256S(txid), nOutput); if (fUnlock) - pwalletMain->UnlockCoin(outpt); + pwallet->UnlockCoin(outpt); else - pwalletMain->LockCoin(outpt); + pwallet->LockCoin(outpt); } return true; @@ -2243,7 +2312,9 @@ UniValue lockunspent(const JSONRPCRequest& request) UniValue listlockunspent(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 0) @@ -2272,10 +2343,10 @@ UniValue listlockunspent(const JSONRPCRequest& request) + HelpExampleRpc("listlockunspent", "") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); vector vOutpts; - pwalletMain->ListLockedCoins(vOutpts); + pwallet->ListLockedCoins(vOutpts); UniValue ret(UniValue::VARR); @@ -2292,7 +2363,9 @@ UniValue listlockunspent(const JSONRPCRequest& request) UniValue settxfee(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 1) @@ -2308,7 +2381,7 @@ UniValue settxfee(const JSONRPCRequest& request) + HelpExampleRpc("settxfee", "0.00001") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); // Amount CAmount nAmount = AmountFromValue(request.params[0]); @@ -2319,7 +2392,9 @@ UniValue settxfee(const JSONRPCRequest& request) UniValue getwalletinfo(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 0) @@ -2344,20 +2419,20 @@ UniValue getwalletinfo(const JSONRPCRequest& request) + HelpExampleRpc("getwalletinfo", "") ); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("walletversion", pwalletMain->GetVersion())); - obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance()))); - obj.push_back(Pair("unconfirmed_balance", ValueFromAmount(pwalletMain->GetUnconfirmedBalance()))); - obj.push_back(Pair("immature_balance", ValueFromAmount(pwalletMain->GetImmatureBalance()))); - obj.push_back(Pair("txcount", (int)pwalletMain->mapWallet.size())); - obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime())); - obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize())); - if (pwalletMain->IsCrypted()) + obj.push_back(Pair("walletversion", pwallet->GetVersion())); + obj.push_back(Pair("balance", ValueFromAmount(pwallet->GetBalance()))); + obj.push_back(Pair("unconfirmed_balance", ValueFromAmount(pwallet->GetUnconfirmedBalance()))); + obj.push_back(Pair("immature_balance", ValueFromAmount(pwallet->GetImmatureBalance()))); + obj.push_back(Pair("txcount", (int)pwallet->mapWallet.size())); + obj.push_back(Pair("keypoololdest", pwallet->GetOldestKeyPoolTime())); + obj.push_back(Pair("keypoolsize", (int)pwallet->GetKeyPoolSize())); + if (pwallet->IsCrypted()) obj.push_back(Pair("unlocked_until", nWalletUnlockTime)); obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK()))); - CKeyID masterKeyID = pwalletMain->GetHDChain().masterKeyID; + CKeyID masterKeyID = pwallet->GetHDChain().masterKeyID; if (!masterKeyID.IsNull()) obj.push_back(Pair("hdmasterkeyid", masterKeyID.GetHex())); return obj; @@ -2365,7 +2440,9 @@ UniValue getwalletinfo(const JSONRPCRequest& request) UniValue resendwallettransactions(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() != 0) @@ -2380,9 +2457,9 @@ UniValue resendwallettransactions(const JSONRPCRequest& request) if (!g_connman) throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK2(cs_main, pwallet->cs_wallet); - std::vector txids = pwalletMain->ResendWalletTransactionsBefore(GetTime(), g_connman.get()); + std::vector txids = pwallet->ResendWalletTransactionsBefore(GetTime(), g_connman.get()); UniValue result(UniValue::VARR); BOOST_FOREACH(const uint256& txid, txids) { @@ -2393,7 +2470,9 @@ UniValue resendwallettransactions(const JSONRPCRequest& request) UniValue listunspent(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() > 4) @@ -2472,9 +2551,9 @@ UniValue listunspent(const JSONRPCRequest& request) UniValue results(UniValue::VARR); vector vecOutputs; - assert(pwalletMain != NULL); - LOCK2(cs_main, pwalletMain->cs_wallet); - pwalletMain->AvailableCoins(vecOutputs, !include_unsafe, NULL, true); + 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; @@ -2493,13 +2572,13 @@ UniValue listunspent(const JSONRPCRequest& request) if (fValidAddress) { entry.push_back(Pair("address", CBitcoinAddress(address).ToString())); - if (pwalletMain->mapAddressBook.count(address)) - entry.push_back(Pair("account", pwalletMain->mapAddressBook[address].name)); + if (pwallet->mapAddressBook.count(address)) + entry.push_back(Pair("account", pwallet->mapAddressBook[address].name)); if (scriptPubKey.IsPayToScriptHash()) { const CScriptID& hash = boost::get(address); CScript redeemScript; - if (pwalletMain->GetCScript(hash, redeemScript)) + if (pwallet->GetCScript(hash, redeemScript)) entry.push_back(Pair("redeemScript", HexStr(redeemScript.begin(), redeemScript.end()))); } } @@ -2517,7 +2596,9 @@ UniValue listunspent(const JSONRPCRequest& request) UniValue fundrawtransaction(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(pwalletMain, request.fHelp)) + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) @@ -2659,7 +2740,7 @@ UniValue fundrawtransaction(const JSONRPCRequest& request) CAmount nFeeOut; string strFailReason; - if(!pwalletMain->FundTransaction(tx, nFeeOut, overrideEstimatedFeerate, feeRate, changePosition, strFailReason, includeWatching, lockUnspents, setSubtractFeeFromOutputs, reserveChangeKey, changeAddress)) + if(!pwallet->FundTransaction(tx, nFeeOut, overrideEstimatedFeerate, feeRate, changePosition, strFailReason, includeWatching, lockUnspents, setSubtractFeeFromOutputs, reserveChangeKey, changeAddress)) throw JSONRPCError(RPC_INTERNAL_ERROR, strFailReason); UniValue result(UniValue::VOBJ); @@ -2699,9 +2780,10 @@ int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, CWallet &wallet) UniValue bumpfee(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(request.fHelp)) { + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) return NullUniValue; - } if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) { throw runtime_error( @@ -2751,14 +2833,14 @@ UniValue bumpfee(const JSONRPCRequest& request) hash.SetHex(request.params[0].get_str()); // retrieve the original tx from the wallet - LOCK2(cs_main, pwalletMain->cs_wallet); - EnsureWalletIsUnlocked(); - if (!pwalletMain->mapWallet.count(hash)) { + LOCK2(cs_main, pwallet->cs_wallet); + EnsureWalletIsUnlocked(pwallet); + if (!pwallet->mapWallet.count(hash)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id"); } - CWalletTx& wtx = pwalletMain->mapWallet[hash]; + CWalletTx& wtx = pwallet->mapWallet[hash]; - if (pwalletMain->HasWalletSpend(hash)) { + if (pwallet->HasWalletSpend(hash)) { throw JSONRPCError(RPC_MISC_ERROR, "Transaction has descendants in the wallet"); } @@ -2784,7 +2866,7 @@ UniValue bumpfee(const JSONRPCRequest& request) // check that original tx consists entirely of our inputs // if not, we can't bump the fee, because the wallet has no way of knowing the value of the other inputs (thus the fee) - if (!pwalletMain->IsAllFromMe(wtx, ISMINE_SPENDABLE)) { + if (!pwallet->IsAllFromMe(wtx, ISMINE_SPENDABLE)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction contains inputs that don't belong to this wallet"); } @@ -2792,7 +2874,7 @@ UniValue bumpfee(const JSONRPCRequest& request) // if there was no change output or multiple change outputs, fail int nOutput = -1; for (size_t i = 0; i < wtx.tx->vout.size(); ++i) { - if (pwalletMain->IsChange(wtx.tx->vout[i])) { + if (pwallet->IsChange(wtx.tx->vout[i])) { if (nOutput != -1) { throw JSONRPCError(RPC_MISC_ERROR, "Transaction has multiple change outputs"); } @@ -2935,12 +3017,12 @@ UniValue bumpfee(const JSONRPCRequest& request) CTransaction txNewConst(tx); int nIn = 0; for (auto& input : tx.vin) { - std::map::const_iterator mi = pwalletMain->mapWallet.find(input.prevout.hash); - assert(mi != pwalletMain->mapWallet.end() && input.prevout.n < mi->second.tx->vout.size()); + std::map::const_iterator mi = pwallet->mapWallet.find(input.prevout.hash); + assert(mi != pwallet->mapWallet.end() && input.prevout.n < mi->second.tx->vout.size()); const CScript& scriptPubKey = mi->second.tx->vout[input.prevout.n].scriptPubKey; const CAmount& amount = mi->second.tx->vout[input.prevout.n].nValue; SignatureData sigdata; - if (!ProduceSignature(TransactionSignatureCreator(pwalletMain, &txNewConst, nIn, amount, SIGHASH_ALL), scriptPubKey, sigdata)) { + if (!ProduceSignature(TransactionSignatureCreator(pwallet, &txNewConst, nIn, amount, SIGHASH_ALL), scriptPubKey, sigdata)) { throw JSONRPCError(RPC_WALLET_ERROR, "Can't sign transaction."); } UpdateTransaction(tx, nIn, sigdata); @@ -2948,8 +3030,8 @@ UniValue bumpfee(const JSONRPCRequest& request) } // commit/broadcast the tx - CReserveKey reservekey(pwalletMain); - CWalletTx wtxBumped(pwalletMain, MakeTransactionRef(std::move(tx))); + CReserveKey reservekey(pwallet); + CWalletTx wtxBumped(pwallet, MakeTransactionRef(std::move(tx))); wtxBumped.mapValue = wtx.mapValue; wtxBumped.mapValue["replaces_txid"] = hash.ToString(); wtxBumped.vOrderForm = wtx.vOrderForm; @@ -2957,7 +3039,7 @@ UniValue bumpfee(const JSONRPCRequest& request) wtxBumped.fTimeReceivedIsTxTime = true; wtxBumped.fFromMe = true; CValidationState state; - if (!pwalletMain->CommitTransaction(wtxBumped, reservekey, g_connman.get(), state)) { + if (!pwallet->CommitTransaction(wtxBumped, reservekey, g_connman.get(), state)) { // NOTE: CommitTransaction never returns false, so this should never happen. throw JSONRPCError(RPC_WALLET_ERROR, strprintf("Error: The transaction was rejected! Reason given: %s", state.GetRejectReason())); } @@ -2970,7 +3052,7 @@ UniValue bumpfee(const JSONRPCRequest& request) } // mark the original tx as bumped - if (!pwalletMain->MarkReplaced(wtx.GetHash(), wtxBumped.GetHash())) { + if (!pwallet->MarkReplaced(wtx.GetHash(), wtxBumped.GetHash())) { // TODO: see if JSON-RPC has a standard way of returning a response // along with an exception. It would be good to return information about // wtxBumped to the caller even if marking the original transaction -- cgit v1.2.3 From 2e518e313b5d5320c16bdb33ebd008b6d30a90f2 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Fri, 9 Sep 2016 07:48:10 +0000 Subject: Move nWalletUnlockTime to CWallet::nRelockTime, and name timed task unique per CWallet --- src/rpc/misc.cpp | 2 +- src/rpc/server.h | 1 - src/wallet/rpcwallet.cpp | 21 +++++++-------------- src/wallet/wallet.h | 3 +++ 4 files changed, 11 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index c9bbce856d..746189a2ae 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -102,7 +102,7 @@ UniValue getinfo(const JSONRPCRequest& request) obj.push_back(Pair("keypoolsize", (int)pwallet->GetKeyPoolSize())); } if (pwallet && pwallet->IsCrypted()) - obj.push_back(Pair("unlocked_until", nWalletUnlockTime)); + obj.push_back(Pair("unlocked_until", pwallet->nRelockTime)); obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK()))); #endif obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK()))); diff --git a/src/rpc/server.h b/src/rpc/server.h index b8f0373acc..72ffc76520 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -190,7 +190,6 @@ extern uint256 ParseHashO(const UniValue& o, std::string strKey); extern std::vector ParseHexV(const UniValue& v, std::string strName); extern std::vector ParseHexO(const UniValue& o, std::string strKey); -extern int64_t nWalletUnlockTime; extern CAmount AmountFromValue(const UniValue& value); extern UniValue ValueFromAmount(const CAmount& amount); extern double GetDifficulty(const CBlockIndex* blockindex = NULL); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 478d92cda3..b36a99013e 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -29,9 +29,6 @@ using namespace std; -int64_t nWalletUnlockTime; -static CCriticalSection cs_nWalletUnlockTime; - CWallet *GetWalletForJSONRPCRequest(const JSONRPCRequest& request) { return pwalletMain; @@ -2004,8 +2001,8 @@ UniValue keypoolrefill(const JSONRPCRequest& request) static void LockWallet(CWallet* pWallet) { - LOCK(cs_nWalletUnlockTime); - nWalletUnlockTime = 0; + LOCK(pWallet->cs_wallet); + pWallet->nRelockTime = 0; pWallet->Lock(); } @@ -2063,9 +2060,8 @@ UniValue walletpassphrase(const JSONRPCRequest& request) pwallet->TopUpKeyPool(); int64_t nSleepTime = request.params[1].get_int64(); - LOCK(cs_nWalletUnlockTime); - nWalletUnlockTime = GetTime() + nSleepTime; - RPCRunLater("lockwallet", boost::bind(LockWallet, pwallet), nSleepTime); + pwallet->nRelockTime = GetTime() + nSleepTime; + RPCRunLater(strprintf("lockwallet_%u", uintptr_t(pwallet)), boost::bind(LockWallet, pwallet), nSleepTime); return NullUniValue; } @@ -2150,11 +2146,8 @@ UniValue walletlock(const JSONRPCRequest& request) if (!pwallet->IsCrypted()) throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletlock was called."); - { - LOCK(cs_nWalletUnlockTime); - pwallet->Lock(); - nWalletUnlockTime = 0; - } + pwallet->Lock(); + pwallet->nRelockTime = 0; return NullUniValue; } @@ -2430,7 +2423,7 @@ UniValue getwalletinfo(const JSONRPCRequest& request) obj.push_back(Pair("keypoololdest", pwallet->GetOldestKeyPoolTime())); obj.push_back(Pair("keypoolsize", (int)pwallet->GetKeyPoolSize())); if (pwallet->IsCrypted()) - obj.push_back(Pair("unlocked_until", nWalletUnlockTime)); + obj.push_back(Pair("unlocked_until", pwallet->nRelockTime)); obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK()))); CKeyID masterKeyID = pwallet->GetHDChain().masterKeyID; if (!masterKeyID.IsNull()) diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 98e4fb87b9..176063c27f 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -768,6 +768,9 @@ public: //! Adds a watch-only address to the store, without saving it to disk (used by LoadWallet) bool LoadWatchOnly(const CScript &dest); + //! Holds a timestamp at which point the wallet is scheduled (externally) to be relocked. Caller must arrange for actual relocking to occur via Lock(). + int64_t nRelockTime; + bool Unlock(const SecureString& strWalletPassphrase); bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase); bool EncryptWallet(const SecureString& strWalletPassphrase); -- cgit v1.2.3 From bf8a04a165e1c19dffce70a7e5c3fb10b0035d96 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 25 Oct 2016 08:04:23 +0000 Subject: Reformat touched lines with C++11 --- src/rpc/misc.cpp | 12 +- src/rpc/rawtransaction.cpp | 3 +- src/wallet/rpcdump.cpp | 47 +++++--- src/wallet/rpcwallet.cpp | 284 ++++++++++++++++++++++++++++----------------- 4 files changed, 214 insertions(+), 132 deletions(-) (limited to 'src') diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 746189a2ae..fe46f61d81 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -101,8 +101,9 @@ UniValue getinfo(const JSONRPCRequest& request) obj.push_back(Pair("keypoololdest", pwallet->GetOldestKeyPoolTime())); obj.push_back(Pair("keypoolsize", (int)pwallet->GetKeyPoolSize())); } - if (pwallet && pwallet->IsCrypted()) + if (pwallet && pwallet->IsCrypted()) { obj.push_back(Pair("unlocked_until", pwallet->nRelockTime)); + } obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK()))); #endif obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK()))); @@ -210,8 +211,9 @@ UniValue validateaddress(const JSONRPCRequest& request) ret.push_back(Pair("iswatchonly", (mine & ISMINE_WATCH_ONLY) ? true: false)); UniValue detail = boost::apply_visitor(DescribeAddressVisitor(pwallet), dest); ret.pushKVs(detail); - if (pwallet && pwallet->mapAddressBook.count(dest)) + if (pwallet && pwallet->mapAddressBook.count(dest)) { ret.push_back(Pair("account", pwallet->mapAddressBook[dest].name)); + } CKeyID keyID; if (pwallet) { const auto& meta = pwallet->mapKeyMetadata; @@ -257,16 +259,16 @@ CScript _createmultisig_redeemScript(CWallet * const pwallet, const UniValue& pa #ifdef ENABLE_WALLET // Case 1: Bitcoin address and we have full public key: CBitcoinAddress address(ks); - if (pwallet && address.IsValid()) - { + if (pwallet && address.IsValid()) { CKeyID keyID; if (!address.GetKeyID(keyID)) throw runtime_error( strprintf("%s does not refer to a key",ks)); CPubKey vchPubKey; - if (!pwallet->GetPubKey(keyID, vchPubKey)) + if (!pwallet->GetPubKey(keyID, vchPubKey)) { throw runtime_error( strprintf("no full public key for address %s",ks)); + } if (!vchPubKey.IsFullyValid()) throw runtime_error(" Invalid public key: "+ks); pubkeys[i] = vchPubKey; diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 5c75fecac8..ce7afcbe54 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -721,8 +721,9 @@ UniValue signrawtransaction(const JSONRPCRequest& request) } } #ifdef ENABLE_WALLET - else if (pwallet) + else if (pwallet) { EnsureWalletIsUnlocked(pwallet); + } #endif // Add previous txouts given in the RPC call: diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index f0df76c92a..8f73932452 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -76,8 +76,9 @@ UniValue importprivkey(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() < 1 || request.params.size() > 3) throw runtime_error( @@ -133,13 +134,15 @@ UniValue importprivkey(const JSONRPCRequest& request) pwallet->SetAddressBook(vchAddress, strLabel, "receive"); // Don't throw error in case a key is already there - if (pwallet->HaveKey(vchAddress)) + if (pwallet->HaveKey(vchAddress)) { return NullUniValue; + } pwallet->mapKeyMetadata[vchAddress].nCreateTime = 1; - if (!pwallet->AddKeyPubKey(key, pubkey)) + if (!pwallet->AddKeyPubKey(key, pubkey)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet"); + } // whenever a key is imported, we need to scan the whole chain pwallet->UpdateTimeFirstKey(1); @@ -155,17 +158,20 @@ UniValue importprivkey(const JSONRPCRequest& request) void ImportAddress(CWallet*, const CBitcoinAddress& address, const string& strLabel); void ImportScript(CWallet * const pwallet, const CScript& script, const string& strLabel, bool isRedeemScript) { - if (!isRedeemScript && ::IsMine(*pwallet, script) == ISMINE_SPENDABLE) + if (!isRedeemScript && ::IsMine(*pwallet, script) == ISMINE_SPENDABLE) { throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script"); + } pwallet->MarkDirty(); - if (!pwallet->HaveWatchOnly(script) && !pwallet->AddWatchOnly(script, 0 /* nCreateTime */)) + if (!pwallet->HaveWatchOnly(script) && !pwallet->AddWatchOnly(script, 0 /* nCreateTime */)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); + } if (isRedeemScript) { - if (!pwallet->HaveCScript(script) && !pwallet->AddCScript(script)) + if (!pwallet->HaveCScript(script) && !pwallet->AddCScript(script)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding p2sh redeemScript to wallet"); + } ImportAddress(pwallet, CBitcoinAddress(CScriptID(script)), strLabel); } else { CTxDestination destination; @@ -188,8 +194,9 @@ UniValue importaddress(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) throw runtime_error( @@ -258,8 +265,9 @@ UniValue importprunedfunds(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() != 2) throw runtime_error( @@ -319,8 +327,9 @@ UniValue removeprunedfunds(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() != 1) throw runtime_error( @@ -342,7 +351,7 @@ UniValue removeprunedfunds(const JSONRPCRequest& request) vHash.push_back(hash); vector vHashOut; - if(pwallet->ZapSelectTx(vHash, vHashOut) != DB_LOAD_OK) { + if (pwallet->ZapSelectTx(vHash, vHashOut) != DB_LOAD_OK) { throw JSONRPCError(RPC_INTERNAL_ERROR, "Could not properly delete the transaction."); } @@ -357,8 +366,9 @@ UniValue importpubkey(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) throw runtime_error( @@ -417,8 +427,9 @@ UniValue importwallet(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() != 1) throw runtime_error( @@ -525,8 +536,9 @@ UniValue dumpprivkey(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() != 1) throw runtime_error( @@ -555,8 +567,9 @@ UniValue dumpprivkey(const JSONRPCRequest& request) if (!address.GetKeyID(keyID)) throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to a key"); CKey vchSecret; - if (!pwallet->GetKey(keyID, vchSecret)) + if (!pwallet->GetKey(keyID, vchSecret)) { throw JSONRPCError(RPC_WALLET_ERROR, "Private key for address " + strAddress + " is not known"); + } return CBitcoinSecret(vchSecret).ToString(); } @@ -565,8 +578,9 @@ UniValue dumpwallet(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() != 1) throw runtime_error( @@ -615,8 +629,7 @@ UniValue dumpwallet(const JSONRPCRequest& request) if (!masterKeyID.IsNull()) { CKey key; - if (pwallet->GetKey(masterKeyID, key)) - { + if (pwallet->GetKey(masterKeyID, key)) { CExtKey masterKey; masterKey.SetMaster(key.begin(), key.size()); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index b36a99013e..f9c16ad4ca 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -43,8 +43,7 @@ std::string HelpRequiringPassphrase(CWallet * const pwallet) bool EnsureWalletIsAvailable(CWallet * const pwallet, bool avoidException) { - if (!pwallet) - { + if (!pwallet) { if (!avoidException) throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)"); else @@ -55,8 +54,9 @@ bool EnsureWalletIsAvailable(CWallet * const pwallet, bool avoidException) void EnsureWalletIsUnlocked(CWallet * const pwallet) { - if (pwallet->IsLocked()) + if (pwallet->IsLocked()) { throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first."); + } } void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry) @@ -110,8 +110,9 @@ UniValue getnewaddress(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() > 1) throw runtime_error( @@ -135,13 +136,15 @@ UniValue getnewaddress(const JSONRPCRequest& request) if (request.params.size() > 0) strAccount = AccountFromValue(request.params[0]); - if (!pwallet->IsLocked()) + if (!pwallet->IsLocked()) { pwallet->TopUpKeyPool(); + } // Generate a new key that is added to wallet CPubKey newKey; - if (!pwallet->GetKeyFromPool(newKey)) + if (!pwallet->GetKeyFromPool(newKey)) { throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); + } CKeyID keyID = newKey.GetID(); pwallet->SetAddressBook(keyID, strAccount, "receive"); @@ -164,8 +167,9 @@ UniValue getaccountaddress(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() != 1) throw runtime_error( @@ -198,8 +202,9 @@ UniValue getrawchangeaddress(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() > 1) throw runtime_error( @@ -215,8 +220,9 @@ UniValue getrawchangeaddress(const JSONRPCRequest& request) LOCK2(cs_main, pwallet->cs_wallet); - if (!pwallet->IsLocked()) + if (!pwallet->IsLocked()) { pwallet->TopUpKeyPool(); + } CReserveKey reservekey(pwallet); CPubKey vchPubKey; @@ -235,8 +241,9 @@ UniValue setaccount(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( @@ -261,14 +268,13 @@ UniValue setaccount(const JSONRPCRequest& request) strAccount = AccountFromValue(request.params[1]); // Only add the account if the address is yours. - if (IsMine(*pwallet, address.Get())) - { + if (IsMine(*pwallet, address.Get())) { // Detect when changing the account of an address that is the 'unused current key' of another account: - if (pwallet->mapAddressBook.count(address.Get())) - { + if (pwallet->mapAddressBook.count(address.Get())) { string strOldAccount = pwallet->mapAddressBook[address.Get()].name; - if (address == GetAccountAddress(pwallet, strOldAccount)) + if (address == GetAccountAddress(pwallet, strOldAccount)) { GetAccountAddress(pwallet, strOldAccount, true); + } } pwallet->SetAddressBook(address.Get(), strAccount, "receive"); } @@ -283,8 +289,9 @@ UniValue getaccount(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() != 1) throw runtime_error( @@ -307,8 +314,9 @@ UniValue getaccount(const JSONRPCRequest& request) string strAccount; map::iterator mi = pwallet->mapAddressBook.find(address.Get()); - if (mi != pwallet->mapAddressBook.end() && !(*mi).second.name.empty()) + if (mi != pwallet->mapAddressBook.end() && !(*mi).second.name.empty()) { strAccount = (*mi).second.name; + } return strAccount; } @@ -317,8 +325,9 @@ UniValue getaddressesbyaccount(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() != 1) throw runtime_error( @@ -342,8 +351,7 @@ UniValue getaddressesbyaccount(const JSONRPCRequest& request) // Find all addresses that have the given account UniValue ret(UniValue::VARR); - BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, CAddressBookData)& item, pwallet->mapAddressBook) - { + for (const std::pair& item : pwallet->mapAddressBook) { const CBitcoinAddress& address = item.first; const string& strName = item.second.name; if (strName == strAccount) @@ -363,8 +371,9 @@ static void SendMoney(CWallet * const pwallet, const CTxDestination &address, CA if (nValue > curBalance) throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds"); - if (pwallet->GetBroadcastTransactions() && !g_connman) + if (pwallet->GetBroadcastTransactions() && !g_connman) { throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); + } // Parse Bitcoin address CScript scriptPubKey = GetScriptForDestination(address); @@ -393,8 +402,9 @@ UniValue sendtoaddress(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() < 2 || request.params.size() > 5) throw runtime_error( @@ -453,8 +463,9 @@ UniValue listaddressgroupings(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp) throw runtime_error( @@ -483,8 +494,7 @@ UniValue listaddressgroupings(const JSONRPCRequest& request) UniValue jsonGroupings(UniValue::VARR); map balances = pwallet->GetAddressBalances(); - BOOST_FOREACH(set grouping, pwallet->GetAddressGroupings()) - { + for (set grouping : pwallet->GetAddressGroupings()) { UniValue jsonGrouping(UniValue::VARR); BOOST_FOREACH(CTxDestination address, grouping) { @@ -492,8 +502,9 @@ UniValue listaddressgroupings(const JSONRPCRequest& request) addressInfo.push_back(CBitcoinAddress(address).ToString()); addressInfo.push_back(ValueFromAmount(balances[address])); { - if (pwallet->mapAddressBook.find(CBitcoinAddress(address).Get()) != pwallet->mapAddressBook.end()) + if (pwallet->mapAddressBook.find(CBitcoinAddress(address).Get()) != pwallet->mapAddressBook.end()) { addressInfo.push_back(pwallet->mapAddressBook.find(CBitcoinAddress(address).Get())->second.name); + } } jsonGrouping.push_back(addressInfo); } @@ -506,8 +517,9 @@ UniValue signmessage(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() != 2) throw runtime_error( @@ -546,8 +558,9 @@ UniValue signmessage(const JSONRPCRequest& request) throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key"); CKey key; - if (!pwallet->GetKey(keyID, key)) + if (!pwallet->GetKey(keyID, key)) { throw JSONRPCError(RPC_WALLET_ERROR, "Private key not available"); + } CHashWriter ss(SER_GETHASH, 0); ss << strMessageMagic; @@ -564,8 +577,9 @@ UniValue getreceivedbyaddress(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( @@ -594,8 +608,9 @@ UniValue getreceivedbyaddress(const JSONRPCRequest& request) if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); CScript scriptPubKey = GetScriptForDestination(address.Get()); - if (!IsMine(*pwallet, scriptPubKey)) + if (!IsMine(*pwallet, scriptPubKey)) { return ValueFromAmount(0); + } // Minimum confirmations int nMinDepth = 1; @@ -604,9 +619,8 @@ UniValue getreceivedbyaddress(const JSONRPCRequest& request) // Tally CAmount nAmount = 0; - for (map::iterator it = pwallet->mapWallet.begin(); it != pwallet->mapWallet.end(); ++it) - { - const CWalletTx& wtx = (*it).second; + for (const std::pair& pairWtx : pwallet->mapWallet) { + const CWalletTx& wtx = pairWtx.second; if (wtx.IsCoinBase() || !CheckFinalTx(*wtx.tx)) continue; @@ -624,8 +638,9 @@ UniValue getreceivedbyaccount(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( @@ -660,18 +675,18 @@ UniValue getreceivedbyaccount(const JSONRPCRequest& request) // Tally CAmount nAmount = 0; - for (map::iterator it = pwallet->mapWallet.begin(); it != pwallet->mapWallet.end(); ++it) - { - const CWalletTx& wtx = (*it).second; + for (const std::pair& pairWtx : pwallet->mapWallet) { + const CWalletTx& wtx = pairWtx.second; if (wtx.IsCoinBase() || !CheckFinalTx(*wtx.tx)) continue; BOOST_FOREACH(const CTxOut& txout, wtx.tx->vout) { CTxDestination address; - if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*pwallet, address) && setAddress.count(address)) + if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*pwallet, address) && setAddress.count(address)) { if (wtx.GetDepthInMainChain() >= nMinDepth) nAmount += txout.nValue; + } } } @@ -683,8 +698,9 @@ UniValue getbalance(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() > 3) throw runtime_error( @@ -740,9 +756,8 @@ UniValue getbalance(const JSONRPCRequest& request) // TxIns spending from the wallet. This also has fewer restrictions on // which unconfirmed transactions are considered trusted. CAmount nBalance = 0; - for (map::iterator it = pwallet->mapWallet.begin(); it != pwallet->mapWallet.end(); ++it) - { - const CWalletTx& wtx = (*it).second; + for (const std::pair& pairWtx : pwallet->mapWallet) { + const CWalletTx& wtx = pairWtx.second; if (!CheckFinalTx(wtx) || wtx.GetBlocksToMaturity() > 0 || wtx.GetDepthInMainChain() < 0) continue; @@ -774,8 +789,9 @@ UniValue getunconfirmedbalance(const JSONRPCRequest &request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() > 0) throw runtime_error( @@ -792,8 +808,9 @@ UniValue movecmd(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() < 3 || request.params.size() > 5) throw runtime_error( @@ -830,8 +847,9 @@ UniValue movecmd(const JSONRPCRequest& request) if (request.params.size() > 4) 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"); + } return true; } @@ -841,8 +859,9 @@ UniValue sendfrom(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() < 3 || request.params.size() > 6) throw runtime_error( @@ -910,8 +929,9 @@ UniValue sendmany(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() < 2 || request.params.size() > 5) throw runtime_error( @@ -951,8 +971,9 @@ UniValue sendmany(const JSONRPCRequest& request) LOCK2(cs_main, pwallet->cs_wallet); - if (pwallet->GetBroadcastTransactions() && !g_connman) + if (pwallet->GetBroadcastTransactions() && !g_connman) { throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); + } string strAccount = AccountFromValue(request.params[0]); UniValue sendTo = request.params[1].get_obj(); @@ -1032,8 +1053,9 @@ UniValue addmultisigaddress(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() < 2 || request.params.size() > 3) { @@ -1130,8 +1152,9 @@ UniValue addwitnessaddress(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() < 1 || request.params.size() > 1) { @@ -1205,9 +1228,8 @@ UniValue ListReceived(CWallet * const pwallet, const UniValue& params, bool fByA // Tally map mapTally; - for (map::iterator it = pwallet->mapWallet.begin(); it != pwallet->mapWallet.end(); ++it) - { - const CWalletTx& wtx = (*it).second; + for (const std::pair& pairWtx : pwallet->mapWallet) { + const CWalletTx& wtx = pairWtx.second; if (wtx.IsCoinBase() || !CheckFinalTx(*wtx.tx)) continue; @@ -1238,8 +1260,7 @@ UniValue ListReceived(CWallet * const pwallet, const UniValue& params, bool fByA // Reply UniValue ret(UniValue::VARR); map mapAccountTally; - BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, CAddressBookData)& item, pwallet->mapAddressBook) - { + for (const std::pair& item : pwallet->mapAddressBook) { const CBitcoinAddress& address = item.first; const string& strAccount = item.second.name; map::iterator it = mapTally.find(address); @@ -1310,8 +1331,9 @@ UniValue listreceivedbyaddress(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() > 3) throw runtime_error( @@ -1354,8 +1376,9 @@ UniValue listreceivedbyaccount(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() > 3) throw runtime_error( @@ -1414,14 +1437,16 @@ void ListTransactions(CWallet * const pwallet, const CWalletTx& wtx, const strin BOOST_FOREACH(const COutputEntry& s, listSent) { UniValue entry(UniValue::VOBJ); - if(involvesWatchonly || (::IsMine(*pwallet, s.destination) & ISMINE_WATCH_ONLY)) + if (involvesWatchonly || (::IsMine(*pwallet, s.destination) & ISMINE_WATCH_ONLY)) { entry.push_back(Pair("involvesWatchonly", true)); + } entry.push_back(Pair("account", strSentAccount)); MaybePushAddress(entry, s.destination); entry.push_back(Pair("category", "send")); entry.push_back(Pair("amount", ValueFromAmount(-s.amount))); - if (pwallet->mapAddressBook.count(s.destination)) + if (pwallet->mapAddressBook.count(s.destination)) { entry.push_back(Pair("label", pwallet->mapAddressBook[s.destination].name)); + } entry.push_back(Pair("vout", s.vout)); entry.push_back(Pair("fee", ValueFromAmount(-nFee))); if (fLong) @@ -1437,13 +1462,15 @@ void ListTransactions(CWallet * const pwallet, const CWalletTx& wtx, const strin BOOST_FOREACH(const COutputEntry& r, listReceived) { string account; - if (pwallet->mapAddressBook.count(r.destination)) + if (pwallet->mapAddressBook.count(r.destination)) { account = pwallet->mapAddressBook[r.destination].name; + } if (fAllAccounts || (account == strAccount)) { UniValue entry(UniValue::VOBJ); - if(involvesWatchonly || (::IsMine(*pwallet, r.destination) & ISMINE_WATCH_ONLY)) + if (involvesWatchonly || (::IsMine(*pwallet, r.destination) & ISMINE_WATCH_ONLY)) { entry.push_back(Pair("involvesWatchonly", true)); + } entry.push_back(Pair("account", account)); MaybePushAddress(entry, r.destination); if (wtx.IsCoinBase()) @@ -1460,8 +1487,9 @@ void ListTransactions(CWallet * const pwallet, const CWalletTx& wtx, const strin entry.push_back(Pair("category", "receive")); } entry.push_back(Pair("amount", ValueFromAmount(r.amount))); - if (pwallet->mapAddressBook.count(r.destination)) + if (pwallet->mapAddressBook.count(r.destination)) { entry.push_back(Pair("label", account)); + } entry.push_back(Pair("vout", r.vout)); if (fLong) WalletTxToJSON(wtx, entry); @@ -1492,8 +1520,9 @@ UniValue listtransactions(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() > 4) throw runtime_error( @@ -1622,8 +1651,9 @@ UniValue listaccounts(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() > 2) throw runtime_error( @@ -1659,14 +1689,14 @@ UniValue listaccounts(const JSONRPCRequest& request) includeWatchonly = includeWatchonly | ISMINE_WATCH_ONLY; map mapAccountBalances; - BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& entry, pwallet->mapAddressBook) { - if (IsMine(*pwallet, entry.first) & includeWatchonly) // This address belongs to me + for (const std::pair& entry : pwallet->mapAddressBook) { + if (IsMine(*pwallet, entry.first) & includeWatchonly) { // This address belongs to me mapAccountBalances[entry.second.name] = 0; + } } - for (map::iterator it = pwallet->mapWallet.begin(); it != pwallet->mapWallet.end(); ++it) - { - const CWalletTx& wtx = (*it).second; + for (const std::pair& pairWtx : pwallet->mapWallet) { + const CWalletTx& wtx = pairWtx.second; CAmount nFee; string strSentAccount; list listReceived; @@ -1681,8 +1711,9 @@ UniValue listaccounts(const JSONRPCRequest& request) if (nDepth >= nMinDepth) { BOOST_FOREACH(const COutputEntry& r, listReceived) - if (pwallet->mapAddressBook.count(r.destination)) + if (pwallet->mapAddressBook.count(r.destination)) { mapAccountBalances[pwallet->mapAddressBook[r.destination].name] += r.amount; + } else mapAccountBalances[""] += r.amount; } @@ -1703,8 +1734,9 @@ UniValue listsinceblock(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp) throw runtime_error( @@ -1789,9 +1821,8 @@ UniValue listsinceblock(const JSONRPCRequest& request) UniValue transactions(UniValue::VARR); - for (map::iterator it = pwallet->mapWallet.begin(); it != pwallet->mapWallet.end(); it++) - { - CWalletTx tx = (*it).second; + for (const std::pair& pairWtx : pwallet->mapWallet) { + CWalletTx tx = pairWtx.second; if (depth == -1 || tx.GetDepthInMainChain() < depth) ListTransactions(pwallet, tx, "*", 0, true, transactions, filter); @@ -1811,8 +1842,9 @@ UniValue gettransaction(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( @@ -1870,8 +1902,9 @@ UniValue gettransaction(const JSONRPCRequest& request) filter = filter | ISMINE_WATCH_ONLY; UniValue entry(UniValue::VOBJ); - if (!pwallet->mapWallet.count(hash)) + if (!pwallet->mapWallet.count(hash)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id"); + } const CWalletTx& wtx = pwallet->mapWallet[hash]; CAmount nCredit = wtx.GetCredit(filter); @@ -1899,8 +1932,9 @@ UniValue abandontransaction(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() != 1) throw runtime_error( @@ -1923,10 +1957,12 @@ UniValue abandontransaction(const JSONRPCRequest& request) uint256 hash; hash.SetHex(request.params[0].get_str()); - if (!pwallet->mapWallet.count(hash)) + if (!pwallet->mapWallet.count(hash)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id"); - if (!pwallet->AbandonTransaction(hash)) + } + if (!pwallet->AbandonTransaction(hash)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not eligible for abandonment"); + } return NullUniValue; } @@ -1936,8 +1972,9 @@ UniValue backupwallet(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() != 1) throw runtime_error( @@ -1953,8 +1990,9 @@ UniValue backupwallet(const JSONRPCRequest& request) LOCK2(cs_main, pwallet->cs_wallet); string strDest = request.params[0].get_str(); - if (!pwallet->BackupWallet(strDest)) + if (!pwallet->BackupWallet(strDest)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!"); + } return NullUniValue; } @@ -1964,8 +2002,9 @@ UniValue keypoolrefill(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() > 1) throw runtime_error( @@ -1992,8 +2031,9 @@ UniValue keypoolrefill(const JSONRPCRequest& request) EnsureWalletIsUnlocked(pwallet); pwallet->TopUpKeyPool(kpSize); - if (pwallet->GetKeyPoolSize() < kpSize) + if (pwallet->GetKeyPoolSize() < kpSize) { throw JSONRPCError(RPC_WALLET_ERROR, "Error refreshing keypool."); + } return NullUniValue; } @@ -2010,10 +2050,11 @@ UniValue walletpassphrase(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } - if (pwallet->IsCrypted() && (request.fHelp || request.params.size() != 2)) + if (pwallet->IsCrypted() && (request.fHelp || request.params.size() != 2)) { throw runtime_error( "walletpassphrase \"passphrase\" timeout\n" "\nStores the wallet decryption key in memory for 'timeout' seconds.\n" @@ -2032,13 +2073,15 @@ UniValue walletpassphrase(const JSONRPCRequest& request) "\nAs json rpc call\n" + HelpExampleRpc("walletpassphrase", "\"my pass phrase\", 60") ); + } LOCK2(cs_main, pwallet->cs_wallet); if (request.fHelp) return true; - if (!pwallet->IsCrypted()) + if (!pwallet->IsCrypted()) { throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrase was called."); + } // Note that the walletpassphrase is stored in request.params[0] which is not mlock()ed SecureString strWalletPass; @@ -2049,8 +2092,9 @@ UniValue walletpassphrase(const JSONRPCRequest& request) if (strWalletPass.length() > 0) { - if (!pwallet->Unlock(strWalletPass)) + if (!pwallet->Unlock(strWalletPass)) { throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect."); + } } else throw runtime_error( @@ -2071,10 +2115,11 @@ UniValue walletpassphrasechange(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } - if (pwallet->IsCrypted() && (request.fHelp || request.params.size() != 2)) + if (pwallet->IsCrypted() && (request.fHelp || request.params.size() != 2)) { throw runtime_error( "walletpassphrasechange \"oldpassphrase\" \"newpassphrase\"\n" "\nChanges the wallet passphrase from 'oldpassphrase' to 'newpassphrase'.\n" @@ -2085,13 +2130,15 @@ UniValue walletpassphrasechange(const JSONRPCRequest& request) + HelpExampleCli("walletpassphrasechange", "\"old one\" \"new one\"") + HelpExampleRpc("walletpassphrasechange", "\"old one\", \"new one\"") ); + } LOCK2(cs_main, pwallet->cs_wallet); if (request.fHelp) return true; - if (!pwallet->IsCrypted()) + if (!pwallet->IsCrypted()) { throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrasechange was called."); + } // TODO: get rid of these .c_str() calls by implementing SecureString::operator=(std::string) // Alternately, find a way to make request.params[0] mlock()'d to begin with. @@ -2108,8 +2155,9 @@ UniValue walletpassphrasechange(const JSONRPCRequest& request) "walletpassphrasechange \n" "Changes the wallet passphrase from to ."); - if (!pwallet->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass)) + if (!pwallet->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass)) { throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect."); + } return NullUniValue; } @@ -2119,10 +2167,11 @@ UniValue walletlock(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } - if (pwallet->IsCrypted() && (request.fHelp || request.params.size() != 0)) + if (pwallet->IsCrypted() && (request.fHelp || request.params.size() != 0)) { throw runtime_error( "walletlock\n" "\nRemoves the wallet encryption key from memory, locking the wallet.\n" @@ -2138,13 +2187,15 @@ UniValue walletlock(const JSONRPCRequest& request) "\nAs json rpc call\n" + HelpExampleRpc("walletlock", "") ); + } LOCK2(cs_main, pwallet->cs_wallet); if (request.fHelp) return true; - if (!pwallet->IsCrypted()) + if (!pwallet->IsCrypted()) { throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletlock was called."); + } pwallet->Lock(); pwallet->nRelockTime = 0; @@ -2157,10 +2208,11 @@ UniValue encryptwallet(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } - if (!pwallet->IsCrypted() && (request.fHelp || request.params.size() != 1)) + if (!pwallet->IsCrypted() && (request.fHelp || request.params.size() != 1)) { throw runtime_error( "encryptwallet \"passphrase\"\n" "\nEncrypts the wallet with 'passphrase'. This is for first time encryption.\n" @@ -2183,13 +2235,15 @@ UniValue encryptwallet(const JSONRPCRequest& request) "\nAs a json rpc call\n" + HelpExampleRpc("encryptwallet", "\"my pass phrase\"") ); + } LOCK2(cs_main, pwallet->cs_wallet); if (request.fHelp) return true; - if (pwallet->IsCrypted()) + if (pwallet->IsCrypted()) { throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an encrypted wallet, but encryptwallet was called."); + } // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string) // Alternately, find a way to make request.params[0] mlock()'d to begin with. @@ -2202,8 +2256,9 @@ UniValue encryptwallet(const JSONRPCRequest& request) "encryptwallet \n" "Encrypts the wallet with ."); - if (!pwallet->EncryptWallet(strWalletPass)) + if (!pwallet->EncryptWallet(strWalletPass)) { throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Error: Failed to encrypt the wallet."); + } // BDB seems to have a bad habit of writing old data into // slack space in .dat files; that is bad if the old data is @@ -2216,8 +2271,9 @@ UniValue lockunspent(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( @@ -2307,8 +2363,9 @@ UniValue listlockunspent(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() > 0) throw runtime_error( @@ -2358,8 +2415,9 @@ UniValue settxfee(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() < 1 || request.params.size() > 1) throw runtime_error( @@ -2387,8 +2445,9 @@ UniValue getwalletinfo(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() != 0) throw runtime_error( @@ -2422,8 +2481,9 @@ UniValue getwalletinfo(const JSONRPCRequest& request) obj.push_back(Pair("txcount", (int)pwallet->mapWallet.size())); obj.push_back(Pair("keypoololdest", pwallet->GetOldestKeyPoolTime())); obj.push_back(Pair("keypoolsize", (int)pwallet->GetKeyPoolSize())); - if (pwallet->IsCrypted()) + if (pwallet->IsCrypted()) { obj.push_back(Pair("unlocked_until", pwallet->nRelockTime)); + } obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK()))); CKeyID masterKeyID = pwallet->GetHDChain().masterKeyID; if (!masterKeyID.IsNull()) @@ -2435,8 +2495,9 @@ UniValue resendwallettransactions(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() != 0) throw runtime_error( @@ -2465,8 +2526,9 @@ UniValue listunspent(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() > 4) throw runtime_error( @@ -2565,14 +2627,16 @@ UniValue listunspent(const JSONRPCRequest& request) if (fValidAddress) { entry.push_back(Pair("address", CBitcoinAddress(address).ToString())); - if (pwallet->mapAddressBook.count(address)) + if (pwallet->mapAddressBook.count(address)) { entry.push_back(Pair("account", pwallet->mapAddressBook[address].name)); + } if (scriptPubKey.IsPayToScriptHash()) { const CScriptID& hash = boost::get(address); CScript redeemScript; - if (pwallet->GetCScript(hash, redeemScript)) + if (pwallet->GetCScript(hash, redeemScript)) { entry.push_back(Pair("redeemScript", HexStr(redeemScript.begin(), redeemScript.end()))); + } } } @@ -2591,8 +2655,9 @@ UniValue fundrawtransaction(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; + } if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( @@ -2733,8 +2798,9 @@ UniValue fundrawtransaction(const JSONRPCRequest& request) CAmount nFeeOut; string strFailReason; - if(!pwallet->FundTransaction(tx, nFeeOut, overrideEstimatedFeerate, feeRate, changePosition, strFailReason, includeWatching, lockUnspents, setSubtractFeeFromOutputs, reserveChangeKey, changeAddress)) + if (!pwallet->FundTransaction(tx, nFeeOut, overrideEstimatedFeerate, feeRate, changePosition, strFailReason, includeWatching, lockUnspents, setSubtractFeeFromOutputs, reserveChangeKey, changeAddress)) { throw JSONRPCError(RPC_INTERNAL_ERROR, strFailReason); + } UniValue result(UniValue::VOBJ); result.push_back(Pair("hex", EncodeHexTx(tx))); -- cgit v1.2.3 From ad1573472e3eff7378f9e28e0d267f919c368907 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 29 Dec 2016 13:05:51 +0000 Subject: RPC: Pass on JSONRPCRequest metadata (URI/user/etc) for "help" method --- src/rpc/server.cpp | 11 +++++++---- src/rpc/server.h | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 0b763acd45..46f7d35907 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -178,7 +178,7 @@ vector ParseHexO(const UniValue& o, string strKey) * Note: This interface may still be subject to change. */ -std::string CRPCTable::help(const std::string& strCommand) const +std::string CRPCTable::help(const std::string& strCommand, const JSONRPCRequest& helpreq) const { string strRet; string category; @@ -189,6 +189,10 @@ std::string CRPCTable::help(const std::string& strCommand) const vCommands.push_back(make_pair(mi->second->category + mi->first, mi->second)); sort(vCommands.begin(), vCommands.end()); + JSONRPCRequest jreq(helpreq); + jreq.fHelp = true; + jreq.params = UniValue(); + BOOST_FOREACH(const PAIRTYPE(string, const CRPCCommand*)& command, vCommands) { const CRPCCommand *pcmd = command.second; @@ -198,10 +202,9 @@ std::string CRPCTable::help(const std::string& strCommand) const continue; if ((strCommand != "" || pcmd->category == "hidden") && strMethod != strCommand) continue; + jreq.strMethod = strMethod; try { - JSONRPCRequest jreq; - jreq.fHelp = true; rpcfn_type pfn = pcmd->actor; if (setDone.insert(pfn).second) (*pfn)(jreq); @@ -250,7 +253,7 @@ UniValue help(const JSONRPCRequest& jsonRequest) if (jsonRequest.params.size() > 0) strCommand = jsonRequest.params[0].get_str(); - return tableRPC.help(strCommand); + return tableRPC.help(strCommand, jsonRequest); } diff --git a/src/rpc/server.h b/src/rpc/server.h index 72ffc76520..0850f68f10 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -154,7 +154,7 @@ private: public: CRPCTable(); const CRPCCommand* operator[](const std::string& name) const; - std::string help(const std::string& name) const; + std::string help(const std::string& name, const JSONRPCRequest& helpreq) const; /** * Execute a method. -- cgit v1.2.3 From a4356328e00155796cd7aa188e96c51c09562423 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Fri, 6 Jan 2017 17:53:06 +0000 Subject: Move wallet RPC declarations to rpcwallet.h --- src/rpc/misc.cpp | 4 ++++ src/rpc/rawtransaction.cpp | 1 + src/rpc/server.h | 11 ----------- src/wallet/rpcdump.cpp | 2 ++ src/wallet/rpcwallet.h | 13 +++++++++++++ 5 files changed, 20 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index fe46f61d81..e543781e73 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -14,6 +14,7 @@ #include "util.h" #include "utilstrencodings.h" #ifdef ENABLE_WALLET +#include "wallet/rpcwallet.h" #include "wallet/wallet.h" #include "wallet/walletdb.h" #endif @@ -234,6 +235,9 @@ UniValue validateaddress(const JSONRPCRequest& request) return ret; } +// Needed even with !ENABLE_WALLET, to pass (ignored) pointers around +class CWallet; + /** * Used by addmultisigaddress / createmultisig: */ diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index ce7afcbe54..79b27d0475 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -24,6 +24,7 @@ #include "uint256.h" #include "utilstrencodings.h" #ifdef ENABLE_WALLET +#include "wallet/rpcwallet.h" #include "wallet/wallet.h" #endif diff --git a/src/rpc/server.h b/src/rpc/server.h index 0850f68f10..68d8a6ec96 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -196,17 +196,6 @@ extern double GetDifficulty(const CBlockIndex* blockindex = NULL); extern std::string HelpExampleCli(const std::string& methodname, const std::string& args); extern std::string HelpExampleRpc(const std::string& methodname, const std::string& args); -// Needed even with !ENABLE_WALLET, to pass (ignored) pointers around -class CWallet; - -#ifdef ENABLE_WALLET -// New code should accessing the wallet should be under the ../wallet/ directory -CWallet *GetWalletForJSONRPCRequest(const JSONRPCRequest&); -std::string HelpRequiringPassphrase(CWallet *); -void EnsureWalletIsUnlocked(CWallet *); -bool EnsureWalletIsAvailable(CWallet *, bool avoidException); -#endif - bool StartRPC(); void InterruptRPC(); void StopRPC(); diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 8f73932452..e4d4d6b36d 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -16,6 +16,8 @@ #include "merkleblock.h" #include "core_io.h" +#include "rpcwallet.h" + #include #include diff --git a/src/wallet/rpcwallet.h b/src/wallet/rpcwallet.h index 3a68ccf1b2..bd5dad18ca 100644 --- a/src/wallet/rpcwallet.h +++ b/src/wallet/rpcwallet.h @@ -6,7 +6,20 @@ #define BITCOIN_WALLET_RPCWALLET_H class CRPCTable; +class JSONRPCRequest; void RegisterWalletRPCCommands(CRPCTable &t); +/** + * Figures out what wallet, if any, to use for a JSONRPCRequest. + * + * @param[in] request JSONRPCRequest that wishes to access a wallet + * @return NULL if no wallet should be used, or a pointer to the CWallet + */ +CWallet *GetWalletForJSONRPCRequest(const JSONRPCRequest&); + +std::string HelpRequiringPassphrase(CWallet *); +void EnsureWalletIsUnlocked(CWallet *); +bool EnsureWalletIsAvailable(CWallet *, bool avoidException); + #endif //BITCOIN_WALLET_RPCWALLET_H -- cgit v1.2.3 From 86be48a77c584cb80b237c31dee9a06ee2aaf2f9 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sat, 7 Jan 2017 19:15:22 +0000 Subject: More tightly couple EnsureWalletIsAvailable with GetWalletForJSONRPCRequest where appropriate --- src/wallet/rpcdump.cpp | 24 ++++++++---------------- src/wallet/rpcwallet.cpp | 38 -------------------------------------- 2 files changed, 8 insertions(+), 54 deletions(-) (limited to 'src') diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index e4d4d6b36d..4629311095 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -77,11 +77,10 @@ std::string DecodeDumpString(const std::string &str) { UniValue importprivkey(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } - + if (request.fHelp || request.params.size() < 1 || request.params.size() > 3) throw runtime_error( "importprivkey \"bitcoinprivkey\" ( \"label\" ) ( rescan )\n" @@ -195,11 +194,10 @@ void ImportAddress(CWallet * const pwallet, const CBitcoinAddress& address, cons UniValue importaddress(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } - + if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) throw runtime_error( "importaddress \"address\" ( \"label\" rescan p2sh )\n" @@ -266,7 +264,6 @@ UniValue importaddress(const JSONRPCRequest& request) UniValue importprunedfunds(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -328,7 +325,6 @@ UniValue importprunedfunds(const JSONRPCRequest& request) UniValue removeprunedfunds(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -367,7 +363,6 @@ UniValue removeprunedfunds(const JSONRPCRequest& request) UniValue importpubkey(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -428,11 +423,10 @@ UniValue importpubkey(const JSONRPCRequest& request) UniValue importwallet(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } - + if (request.fHelp || request.params.size() != 1) throw runtime_error( "importwallet \"filename\"\n" @@ -537,11 +531,10 @@ UniValue importwallet(const JSONRPCRequest& request) UniValue dumpprivkey(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } - + if (request.fHelp || request.params.size() != 1) throw runtime_error( "dumpprivkey \"address\"\n" @@ -579,11 +572,10 @@ UniValue dumpprivkey(const JSONRPCRequest& request) UniValue dumpwallet(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } - + if (request.fHelp || request.params.size() != 1) throw runtime_error( "dumpwallet \"filename\"\n" @@ -1003,6 +995,9 @@ int64_t GetImportTimestamp(const UniValue& data, int64_t now) UniValue importmulti(const JSONRPCRequest& mainRequest) { CWallet * const pwallet = GetWalletForJSONRPCRequest(mainRequest); + if (!EnsureWalletIsAvailable(pwallet, mainRequest.fHelp)) { + return NullUniValue; + } // clang-format off if (mainRequest.fHelp || mainRequest.params.size() < 1 || mainRequest.params.size() > 2) @@ -1042,9 +1037,6 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) " [{ \"success\": true } , { \"success\": false, \"error\": { \"code\": -1, \"message\": \"Internal Server Error\"} }, ... ]\n"); // clang-format on - if (!EnsureWalletIsAvailable(pwallet, mainRequest.fHelp)) { - return NullUniValue; - } RPCTypeCheck(mainRequest.params, boost::assign::list_of(UniValue::VARR)(UniValue::VOBJ)); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index f9c16ad4ca..60f08b91c1 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -109,7 +109,6 @@ string AccountFromValue(const UniValue& value) UniValue getnewaddress(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -166,7 +165,6 @@ CBitcoinAddress GetAccountAddress(CWallet * const pwallet, string strAccount, bo UniValue getaccountaddress(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -201,7 +199,6 @@ UniValue getaccountaddress(const JSONRPCRequest& request) UniValue getrawchangeaddress(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -240,7 +237,6 @@ UniValue getrawchangeaddress(const JSONRPCRequest& request) UniValue setaccount(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -288,7 +284,6 @@ UniValue setaccount(const JSONRPCRequest& request) UniValue getaccount(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -324,7 +319,6 @@ UniValue getaccount(const JSONRPCRequest& request) UniValue getaddressesbyaccount(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -401,7 +395,6 @@ static void SendMoney(CWallet * const pwallet, const CTxDestination &address, CA UniValue sendtoaddress(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -462,7 +455,6 @@ UniValue sendtoaddress(const JSONRPCRequest& request) UniValue listaddressgroupings(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -516,7 +508,6 @@ UniValue listaddressgroupings(const JSONRPCRequest& request) UniValue signmessage(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -576,7 +567,6 @@ UniValue signmessage(const JSONRPCRequest& request) UniValue getreceivedbyaddress(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -637,7 +627,6 @@ UniValue getreceivedbyaddress(const JSONRPCRequest& request) UniValue getreceivedbyaccount(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -697,7 +686,6 @@ UniValue getreceivedbyaccount(const JSONRPCRequest& request) UniValue getbalance(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -788,7 +776,6 @@ UniValue getbalance(const JSONRPCRequest& request) UniValue getunconfirmedbalance(const JSONRPCRequest &request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -807,7 +794,6 @@ UniValue getunconfirmedbalance(const JSONRPCRequest &request) UniValue movecmd(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -858,7 +844,6 @@ UniValue movecmd(const JSONRPCRequest& request) UniValue sendfrom(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -928,7 +913,6 @@ UniValue sendfrom(const JSONRPCRequest& request) UniValue sendmany(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -1052,7 +1036,6 @@ extern CScript _createmultisig_redeemScript(CWallet * const pwallet, const UniVa UniValue addmultisigaddress(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -1151,7 +1134,6 @@ public: UniValue addwitnessaddress(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -1330,7 +1312,6 @@ UniValue ListReceived(CWallet * const pwallet, const UniValue& params, bool fByA UniValue listreceivedbyaddress(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -1375,7 +1356,6 @@ UniValue listreceivedbyaddress(const JSONRPCRequest& request) UniValue listreceivedbyaccount(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -1519,7 +1499,6 @@ void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Un UniValue listtransactions(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -1650,7 +1629,6 @@ UniValue listtransactions(const JSONRPCRequest& request) UniValue listaccounts(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -1733,7 +1711,6 @@ UniValue listaccounts(const JSONRPCRequest& request) UniValue listsinceblock(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -1841,7 +1818,6 @@ UniValue listsinceblock(const JSONRPCRequest& request) UniValue gettransaction(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -1931,7 +1907,6 @@ UniValue gettransaction(const JSONRPCRequest& request) UniValue abandontransaction(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -1971,7 +1946,6 @@ UniValue abandontransaction(const JSONRPCRequest& request) UniValue backupwallet(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -2001,7 +1975,6 @@ UniValue backupwallet(const JSONRPCRequest& request) UniValue keypoolrefill(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -2049,7 +2022,6 @@ static void LockWallet(CWallet* pWallet) UniValue walletpassphrase(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -2114,7 +2086,6 @@ UniValue walletpassphrase(const JSONRPCRequest& request) UniValue walletpassphrasechange(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -2166,7 +2137,6 @@ UniValue walletpassphrasechange(const JSONRPCRequest& request) UniValue walletlock(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -2207,7 +2177,6 @@ UniValue walletlock(const JSONRPCRequest& request) UniValue encryptwallet(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -2270,7 +2239,6 @@ UniValue encryptwallet(const JSONRPCRequest& request) UniValue lockunspent(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -2362,7 +2330,6 @@ UniValue lockunspent(const JSONRPCRequest& request) UniValue listlockunspent(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -2414,7 +2381,6 @@ UniValue listlockunspent(const JSONRPCRequest& request) UniValue settxfee(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -2444,7 +2410,6 @@ UniValue settxfee(const JSONRPCRequest& request) UniValue getwalletinfo(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -2494,7 +2459,6 @@ UniValue getwalletinfo(const JSONRPCRequest& request) UniValue resendwallettransactions(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -2525,7 +2489,6 @@ UniValue resendwallettransactions(const JSONRPCRequest& request) UniValue listunspent(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } @@ -2654,7 +2617,6 @@ UniValue listunspent(const JSONRPCRequest& request) UniValue fundrawtransaction(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } -- cgit v1.2.3 From 9756be382e64ab060e8d8fd3cefe5bbccc44bb45 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sun, 8 Jan 2017 20:33:33 +0000 Subject: Wallet/RPC: Use filename rather than CWallet pointer, for lockwallet RPCRunLater job name The job name is logged, and could pose as an information leak to someone attacking the process, helping them counteract ASLR protections --- src/wallet/rpcwallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 60f08b91c1..148f0abe86 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2077,7 +2077,7 @@ UniValue walletpassphrase(const JSONRPCRequest& request) int64_t nSleepTime = request.params[1].get_int64(); pwallet->nRelockTime = GetTime() + nSleepTime; - RPCRunLater(strprintf("lockwallet_%u", uintptr_t(pwallet)), boost::bind(LockWallet, pwallet), nSleepTime); + RPCRunLater(strprintf("lockwallet(%s)", pwallet->strWalletFile), boost::bind(LockWallet, pwallet), nSleepTime); return NullUniValue; } -- cgit v1.2.3 From d678771c660c936a6222dd43a204cb2699100f3e Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sun, 8 Jan 2017 20:41:30 +0000 Subject: Wallet: Sanitise -wallet parameter --- src/utilstrencodings.cpp | 3 ++- src/utilstrencodings.h | 3 ++- src/wallet/wallet.cpp | 6 ++++++ 3 files changed, 10 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp index 025040c43a..29ae57940f 100644 --- a/src/utilstrencodings.cpp +++ b/src/utilstrencodings.cpp @@ -19,7 +19,8 @@ static const string CHARS_ALPHA_NUM = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO static const string SAFE_CHARS[] = { CHARS_ALPHA_NUM + " .,;-_/:?@()", // SAFE_CHARS_DEFAULT - CHARS_ALPHA_NUM + " .,;-_?@" // SAFE_CHARS_UA_COMMENT + CHARS_ALPHA_NUM + " .,;-_?@", // SAFE_CHARS_UA_COMMENT + CHARS_ALPHA_NUM + ".-_", // SAFE_CHARS_FILENAME }; string SanitizeString(const string& str, int rule) diff --git a/src/utilstrencodings.h b/src/utilstrencodings.h index cb6f014fc2..e2a1b9bef9 100644 --- a/src/utilstrencodings.h +++ b/src/utilstrencodings.h @@ -26,7 +26,8 @@ enum SafeChars { SAFE_CHARS_DEFAULT, //!< The full set of allowed chars - SAFE_CHARS_UA_COMMENT //!< BIP-0014 subset + SAFE_CHARS_UA_COMMENT, //!< BIP-0014 subset + SAFE_CHARS_FILENAME, //!< Chars allowed in filenames }; /** diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 63501b04be..446454e9e3 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3765,6 +3765,12 @@ bool CWallet::InitLoadWallet() std::string walletFile = GetArg("-wallet", DEFAULT_WALLET_DAT); + if (walletFile.find_first_of("/\\") != std::string::npos) { + return InitError(_("-wallet parameter must only specify a filename (not a path)")); + } else if (SanitizeString(walletFile, SAFE_CHARS_FILENAME) != walletFile) { + return InitError(_("Invalid characters in -wallet filename")); + } + CWallet * const pwallet = CreateWalletFromFile(walletFile); if (!pwallet) { return false; -- cgit v1.2.3