diff options
Diffstat (limited to 'src/wallet')
-rw-r--r-- | src/wallet/rpcdump.cpp | 100 | ||||
-rw-r--r-- | src/wallet/rpcwallet.cpp | 503 | ||||
-rw-r--r-- | src/wallet/test/crypto_tests.cpp | 2 | ||||
-rw-r--r-- | src/wallet/wallet.cpp | 13 | ||||
-rw-r--r-- | src/wallet/wallet.h | 2 |
5 files changed, 313 insertions, 307 deletions
diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index e80fa7dff8..8a1bbd5684 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -74,12 +74,12 @@ std::string DecodeDumpString(const std::string &str) { return ret.str(); } -UniValue importprivkey(const UniValue& params, bool fHelp) +UniValue importprivkey(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() < 1 || params.size() > 3) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 3) throw runtime_error( "importprivkey \"bitcoinprivkey\" ( \"label\" rescan )\n" "\nAdds a private key (as returned by dumpprivkey) to your wallet.\n" @@ -104,15 +104,15 @@ UniValue importprivkey(const UniValue& params, bool fHelp) EnsureWalletIsUnlocked(); - string strSecret = params[0].get_str(); + string strSecret = request.params[0].get_str(); string strLabel = ""; - if (params.size() > 1) - strLabel = params[1].get_str(); + if (request.params.size() > 1) + strLabel = request.params[1].get_str(); // Whether to perform rescan after import bool fRescan = true; - if (params.size() > 2) - fRescan = params[2].get_bool(); + if (request.params.size() > 2) + fRescan = request.params[2].get_bool(); if (fRescan && fPruneMode) throw JSONRPCError(RPC_WALLET_ERROR, "Rescan is disabled in pruned mode"); @@ -184,12 +184,12 @@ void ImportAddress(const CBitcoinAddress& address, const string& strLabel) pwalletMain->SetAddressBook(address.Get(), strLabel, "receive"); } -UniValue importaddress(const UniValue& params, bool fHelp) +UniValue importaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() < 1 || params.size() > 4) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) throw runtime_error( "importaddress \"address\" ( \"label\" rescan p2sh )\n" "\nAdds a script (in hex) or address that can be watched as if it were in your wallet but cannot be used to spend.\n" @@ -213,31 +213,31 @@ UniValue importaddress(const UniValue& params, bool fHelp) string strLabel = ""; - if (params.size() > 1) - strLabel = params[1].get_str(); + if (request.params.size() > 1) + strLabel = request.params[1].get_str(); // Whether to perform rescan after import bool fRescan = true; - if (params.size() > 2) - fRescan = params[2].get_bool(); + if (request.params.size() > 2) + fRescan = request.params[2].get_bool(); if (fRescan && fPruneMode) throw JSONRPCError(RPC_WALLET_ERROR, "Rescan is disabled in pruned mode"); // Whether to import a p2sh version, too bool fP2SH = false; - if (params.size() > 3) - fP2SH = params[3].get_bool(); + if (request.params.size() > 3) + fP2SH = request.params[3].get_bool(); LOCK2(cs_main, pwalletMain->cs_wallet); - CBitcoinAddress address(params[0].get_str()); + 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(address, strLabel); - } else if (IsHex(params[0].get_str())) { - std::vector<unsigned char> data(ParseHex(params[0].get_str())); + } else if (IsHex(request.params[0].get_str())) { + std::vector<unsigned char> data(ParseHex(request.params[0].get_str())); ImportScript(CScript(data.begin(), data.end()), strLabel, fP2SH); } else { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address or script"); @@ -252,12 +252,12 @@ UniValue importaddress(const UniValue& params, bool fHelp) return NullUniValue; } -UniValue importprunedfunds(const UniValue& params, bool fHelp) +UniValue importprunedfunds(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() != 2) + if (request.fHelp || request.params.size() != 2) throw runtime_error( "importprunedfunds\n" "\nImports funds without rescan. Corresponding address or script must previously be included in wallet. Aimed towards pruned wallets. The end-user is responsible to import additional transactions that subsequently spend the imported outputs or rescan after the point in the blockchain the transaction is included.\n" @@ -267,12 +267,12 @@ UniValue importprunedfunds(const UniValue& params, bool fHelp) ); CTransaction tx; - if (!DecodeHexTx(tx, params[0].get_str())) + if (!DecodeHexTx(tx, request.params[0].get_str())) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); uint256 hashTx = tx.GetHash(); CWalletTx wtx(pwalletMain,tx); - CDataStream ssMB(ParseHexV(params[1], "proof"), SER_NETWORK, PROTOCOL_VERSION); + CDataStream ssMB(ParseHexV(request.params[1], "proof"), SER_NETWORK, PROTOCOL_VERSION); CMerkleBlock merkleBlock; ssMB >> merkleBlock; @@ -311,12 +311,12 @@ UniValue importprunedfunds(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No addresses in wallet correspond to included transaction"); } -UniValue removeprunedfunds(const UniValue& params, bool fHelp) +UniValue removeprunedfunds(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "removeprunedfunds \"txid\"\n" "\nDeletes the specified transaction from the wallet. Meant for use with pruned wallets and as a companion to importprunedfunds. This will effect wallet balances.\n" @@ -331,7 +331,7 @@ UniValue removeprunedfunds(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); uint256 hash; - hash.SetHex(params[0].get_str()); + hash.SetHex(request.params[0].get_str()); vector<uint256> vHash; vHash.push_back(hash); vector<uint256> vHashOut; @@ -347,12 +347,12 @@ UniValue removeprunedfunds(const UniValue& params, bool fHelp) return NullUniValue; } -UniValue importpubkey(const UniValue& params, bool fHelp) +UniValue importpubkey(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() < 1 || params.size() > 4) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) throw runtime_error( "importpubkey \"pubkey\" ( \"label\" rescan )\n" "\nAdds a public key (in hex) that can be watched as if it were in your wallet but cannot be used to spend.\n" @@ -372,20 +372,20 @@ UniValue importpubkey(const UniValue& params, bool fHelp) string strLabel = ""; - if (params.size() > 1) - strLabel = params[1].get_str(); + if (request.params.size() > 1) + strLabel = request.params[1].get_str(); // Whether to perform rescan after import bool fRescan = true; - if (params.size() > 2) - fRescan = params[2].get_bool(); + if (request.params.size() > 2) + fRescan = request.params[2].get_bool(); if (fRescan && fPruneMode) throw JSONRPCError(RPC_WALLET_ERROR, "Rescan is disabled in pruned mode"); - if (!IsHex(params[0].get_str())) + if (!IsHex(request.params[0].get_str())) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey must be a hex string"); - std::vector<unsigned char> data(ParseHex(params[0].get_str())); + std::vector<unsigned char> data(ParseHex(request.params[0].get_str())); CPubKey pubKey(data.begin(), data.end()); if (!pubKey.IsFullyValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey is not a valid public key"); @@ -405,12 +405,12 @@ UniValue importpubkey(const UniValue& params, bool fHelp) } -UniValue importwallet(const UniValue& params, bool fHelp) +UniValue importwallet(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "importwallet \"filename\"\n" "\nImports keys from a wallet dump file (see dumpwallet).\n" @@ -433,7 +433,7 @@ UniValue importwallet(const UniValue& params, bool fHelp) EnsureWalletIsUnlocked(); ifstream file; - file.open(params[0].get_str().c_str(), std::ios::in | std::ios::ate); + file.open(request.params[0].get_str().c_str(), std::ios::in | std::ios::ate); if (!file.is_open()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file"); @@ -512,12 +512,12 @@ UniValue importwallet(const UniValue& params, bool fHelp) return NullUniValue; } -UniValue dumpprivkey(const UniValue& params, bool fHelp) +UniValue dumpprivkey(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "dumpprivkey \"bitcoinaddress\"\n" "\nReveals the private key corresponding to 'bitcoinaddress'.\n" @@ -536,7 +536,7 @@ UniValue dumpprivkey(const UniValue& params, bool fHelp) EnsureWalletIsUnlocked(); - string strAddress = params[0].get_str(); + string strAddress = request.params[0].get_str(); CBitcoinAddress address; if (!address.SetString(strAddress)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); @@ -550,12 +550,12 @@ UniValue dumpprivkey(const UniValue& params, bool fHelp) } -UniValue dumpwallet(const UniValue& params, bool fHelp) +UniValue dumpwallet(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "dumpwallet \"filename\"\n" "\nDumps all wallet keys in a human-readable format.\n" @@ -571,7 +571,7 @@ UniValue dumpwallet(const UniValue& params, bool fHelp) EnsureWalletIsUnlocked(); ofstream file; - file.open(params[0].get_str().c_str()); + file.open(request.params[0].get_str().c_str()); if (!file.is_open()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file"); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 3eb7e5d9ba..33620aa6ff 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2015 The Bitcoin Core developers +// Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -101,12 +101,12 @@ string AccountFromValue(const UniValue& value) return strAccount; } -UniValue getnewaddress(const UniValue& params, bool fHelp) +UniValue getnewaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() > 1) + if (request.fHelp || request.params.size() > 1) throw runtime_error( "getnewaddress ( \"account\" )\n" "\nReturns a new Bitcoin address for receiving payments.\n" @@ -125,8 +125,8 @@ UniValue getnewaddress(const UniValue& params, bool fHelp) // Parse the account first so we don't generate a key if there's an error string strAccount; - if (params.size() > 0) - strAccount = AccountFromValue(params[0]); + if (request.params.size() > 0) + strAccount = AccountFromValue(request.params[0]); if (!pwalletMain->IsLocked()) pwalletMain->TopUpKeyPool(); @@ -153,12 +153,12 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false) return CBitcoinAddress(pubKey.GetID()); } -UniValue getaccountaddress(const UniValue& params, bool fHelp) +UniValue getaccountaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "getaccountaddress \"account\"\n" "\nDEPRECATED. Returns the current Bitcoin address for receiving payments to this account.\n" @@ -176,7 +176,7 @@ UniValue getaccountaddress(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); // Parse the account first so we don't generate a key if there's an error - string strAccount = AccountFromValue(params[0]); + string strAccount = AccountFromValue(request.params[0]); UniValue ret(UniValue::VSTR); @@ -185,12 +185,12 @@ UniValue getaccountaddress(const UniValue& params, bool fHelp) } -UniValue getrawchangeaddress(const UniValue& params, bool fHelp) +UniValue getrawchangeaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() > 1) + if (request.fHelp || request.params.size() > 1) throw runtime_error( "getrawchangeaddress\n" "\nReturns a new Bitcoin address, for receiving change.\n" @@ -220,12 +220,12 @@ UniValue getrawchangeaddress(const UniValue& params, bool fHelp) } -UniValue setaccount(const UniValue& params, bool fHelp) +UniValue setaccount(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() < 1 || params.size() > 2) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( "setaccount \"bitcoinaddress\" \"account\"\n" "\nDEPRECATED. Sets the account associated with the given address.\n" @@ -239,13 +239,13 @@ UniValue setaccount(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - CBitcoinAddress address(params[0].get_str()); + CBitcoinAddress address(request.params[0].get_str()); if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); string strAccount; - if (params.size() > 1) - strAccount = AccountFromValue(params[1]); + if (request.params.size() > 1) + strAccount = AccountFromValue(request.params[1]); // Only add the account if the address is yours. if (IsMine(*pwalletMain, address.Get())) @@ -266,12 +266,12 @@ UniValue setaccount(const UniValue& params, bool fHelp) } -UniValue getaccount(const UniValue& params, bool fHelp) +UniValue getaccount(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "getaccount \"bitcoinaddress\"\n" "\nDEPRECATED. Returns the account associated with the given address.\n" @@ -286,7 +286,7 @@ UniValue getaccount(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - CBitcoinAddress address(params[0].get_str()); + CBitcoinAddress address(request.params[0].get_str()); if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); @@ -298,12 +298,12 @@ UniValue getaccount(const UniValue& params, bool fHelp) } -UniValue getaddressesbyaccount(const UniValue& params, bool fHelp) +UniValue getaddressesbyaccount(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "getaddressesbyaccount \"account\"\n" "\nDEPRECATED. Returns the list of addresses for the given account.\n" @@ -321,7 +321,7 @@ UniValue getaddressesbyaccount(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - string strAccount = AccountFromValue(params[0]); + string strAccount = AccountFromValue(request.params[0]); // Find all addresses that have the given account UniValue ret(UniValue::VARR); @@ -369,12 +369,12 @@ static void SendMoney(const CTxDestination &address, CAmount nValue, bool fSubtr throw JSONRPCError(RPC_WALLET_ERROR, "Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of the wallet and coins were spent in the copy but not marked as spent here."); } -UniValue sendtoaddress(const UniValue& params, bool fHelp) +UniValue sendtoaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() < 2 || params.size() > 5) + if (request.fHelp || request.params.size() < 2 || request.params.size() > 5) throw runtime_error( "sendtoaddress \"bitcoinaddress\" amount ( \"comment\" \"comment-to\" subtractfeefromamount )\n" "\nSend an amount to a given address.\n" @@ -400,25 +400,25 @@ UniValue sendtoaddress(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - CBitcoinAddress address(params[0].get_str()); + CBitcoinAddress address(request.params[0].get_str()); if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); // Amount - CAmount nAmount = AmountFromValue(params[1]); + CAmount nAmount = AmountFromValue(request.params[1]); if (nAmount <= 0) throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send"); // Wallet comments CWalletTx wtx; - if (params.size() > 2 && !params[2].isNull() && !params[2].get_str().empty()) - wtx.mapValue["comment"] = params[2].get_str(); - if (params.size() > 3 && !params[3].isNull() && !params[3].get_str().empty()) - wtx.mapValue["to"] = params[3].get_str(); + if (request.params.size() > 2 && !request.params[2].isNull() && !request.params[2].get_str().empty()) + wtx.mapValue["comment"] = request.params[2].get_str(); + if (request.params.size() > 3 && !request.params[3].isNull() && !request.params[3].get_str().empty()) + wtx.mapValue["to"] = request.params[3].get_str(); bool fSubtractFeeFromAmount = false; - if (params.size() > 4) - fSubtractFeeFromAmount = params[4].get_bool(); + if (request.params.size() > 4) + fSubtractFeeFromAmount = request.params[4].get_bool(); EnsureWalletIsUnlocked(); @@ -427,12 +427,12 @@ UniValue sendtoaddress(const UniValue& params, bool fHelp) return wtx.GetHash().GetHex(); } -UniValue listaddressgroupings(const UniValue& params, bool fHelp) +UniValue listaddressgroupings(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp) + if (request.fHelp) throw runtime_error( "listaddressgroupings\n" "\nLists groups of addresses which have had their common ownership\n" @@ -478,12 +478,12 @@ UniValue listaddressgroupings(const UniValue& params, bool fHelp) return jsonGroupings; } -UniValue signmessage(const UniValue& params, bool fHelp) +UniValue signmessage(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() != 2) + if (request.fHelp || request.params.size() != 2) throw runtime_error( "signmessage \"bitcoinaddress\" \"message\"\n" "\nSign a message with the private key of an address" @@ -508,8 +508,8 @@ UniValue signmessage(const UniValue& params, bool fHelp) EnsureWalletIsUnlocked(); - string strAddress = params[0].get_str(); - string strMessage = params[1].get_str(); + string strAddress = request.params[0].get_str(); + string strMessage = request.params[1].get_str(); CBitcoinAddress addr(strAddress); if (!addr.IsValid()) @@ -534,12 +534,12 @@ UniValue signmessage(const UniValue& params, bool fHelp) return EncodeBase64(&vchSig[0], vchSig.size()); } -UniValue getreceivedbyaddress(const UniValue& params, bool fHelp) +UniValue getreceivedbyaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() < 1 || params.size() > 2) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( "getreceivedbyaddress \"bitcoinaddress\" ( minconf )\n" "\nReturns the total amount received by the given bitcoinaddress in transactions with at least minconf confirmations.\n" @@ -562,7 +562,7 @@ UniValue getreceivedbyaddress(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); // Bitcoin address - CBitcoinAddress address = CBitcoinAddress(params[0].get_str()); + 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()); @@ -571,8 +571,8 @@ UniValue getreceivedbyaddress(const UniValue& params, bool fHelp) // Minimum confirmations int nMinDepth = 1; - if (params.size() > 1) - nMinDepth = params[1].get_int(); + if (request.params.size() > 1) + nMinDepth = request.params[1].get_int(); // Tally CAmount nAmount = 0; @@ -592,12 +592,12 @@ UniValue getreceivedbyaddress(const UniValue& params, bool fHelp) } -UniValue getreceivedbyaccount(const UniValue& params, bool fHelp) +UniValue getreceivedbyaccount(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() < 1 || params.size() > 2) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( "getreceivedbyaccount \"account\" ( minconf )\n" "\nDEPRECATED. Returns the total amount received by addresses with <account> in transactions with at least [minconf] confirmations.\n" @@ -621,11 +621,11 @@ UniValue getreceivedbyaccount(const UniValue& params, bool fHelp) // Minimum confirmations int nMinDepth = 1; - if (params.size() > 1) - nMinDepth = params[1].get_int(); + if (request.params.size() > 1) + nMinDepth = request.params[1].get_int(); // Get the set of pub keys assigned to account - string strAccount = AccountFromValue(params[0]); + string strAccount = AccountFromValue(request.params[0]); set<CTxDestination> setAddress = pwalletMain->GetAccountAddresses(strAccount); // Tally @@ -649,12 +649,12 @@ UniValue getreceivedbyaccount(const UniValue& params, bool fHelp) } -UniValue getbalance(const UniValue& params, bool fHelp) +UniValue getbalance(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() > 3) + if (request.fHelp || request.params.size() > 3) throw runtime_error( "getbalance ( \"account\" minconf includeWatchonly )\n" "\nIf account is not specified, returns the server's total available balance.\n" @@ -678,18 +678,18 @@ UniValue getbalance(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - if (params.size() == 0) + if (request.params.size() == 0) return ValueFromAmount(pwalletMain->GetBalance()); int nMinDepth = 1; - if (params.size() > 1) - nMinDepth = params[1].get_int(); + if (request.params.size() > 1) + nMinDepth = request.params[1].get_int(); isminefilter filter = ISMINE_SPENDABLE; - if(params.size() > 2) - if(params[2].get_bool()) + if(request.params.size() > 2) + if(request.params[2].get_bool()) filter = filter | ISMINE_WATCH_ONLY; - if (params[0].get_str() == "*") { + if (request.params[0].get_str() == "*") { // Calculate total balance a different way from GetBalance() // (GetBalance() sums up all unspent TxOuts) // getbalance and "getbalance * 1 true" should return the same number @@ -717,19 +717,19 @@ UniValue getbalance(const UniValue& params, bool fHelp) return ValueFromAmount(nBalance); } - string strAccount = AccountFromValue(params[0]); + string strAccount = AccountFromValue(request.params[0]); CAmount nBalance = pwalletMain->GetAccountBalance(strAccount, nMinDepth, filter); return ValueFromAmount(nBalance); } -UniValue getunconfirmedbalance(const UniValue ¶ms, bool fHelp) +UniValue getunconfirmedbalance(const JSONRPCRequest &request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() > 0) + if (request.fHelp || request.params.size() > 0) throw runtime_error( "getunconfirmedbalance\n" "Returns the server's total unconfirmed balance\n"); @@ -740,12 +740,12 @@ UniValue getunconfirmedbalance(const UniValue ¶ms, bool fHelp) } -UniValue movecmd(const UniValue& params, bool fHelp) +UniValue movecmd(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() < 3 || params.size() > 5) + if (request.fHelp || request.params.size() < 3 || request.params.size() > 5) throw runtime_error( "move \"fromaccount\" \"toaccount\" amount ( minconf \"comment\" )\n" "\nDEPRECATED. Move a specified amount from one account in your wallet to another.\n" @@ -768,17 +768,17 @@ UniValue movecmd(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - string strFrom = AccountFromValue(params[0]); - string strTo = AccountFromValue(params[1]); - CAmount nAmount = AmountFromValue(params[2]); + string strFrom = AccountFromValue(request.params[0]); + string strTo = AccountFromValue(request.params[1]); + CAmount nAmount = AmountFromValue(request.params[2]); if (nAmount <= 0) throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send"); - if (params.size() > 3) + if (request.params.size() > 3) // unused parameter, used to be nMinDepth, keep type-checking it though - (void)params[3].get_int(); + (void)request.params[3].get_int(); string strComment; - if (params.size() > 4) - strComment = params[4].get_str(); + if (request.params.size() > 4) + strComment = request.params[4].get_str(); if (!pwalletMain->AccountMove(strFrom, strTo, nAmount, strComment)) throw JSONRPCError(RPC_DATABASE_ERROR, "database error"); @@ -787,12 +787,12 @@ UniValue movecmd(const UniValue& params, bool fHelp) } -UniValue sendfrom(const UniValue& params, bool fHelp) +UniValue sendfrom(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() < 3 || params.size() > 6) + if (request.fHelp || request.params.size() < 3 || request.params.size() > 6) throw runtime_error( "sendfrom \"fromaccount\" \"tobitcoinaddress\" amount ( minconf \"comment\" \"comment-to\" )\n" "\nDEPRECATED (use sendtoaddress). Sent an amount from an account to a bitcoin address." @@ -820,23 +820,23 @@ UniValue sendfrom(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - string strAccount = AccountFromValue(params[0]); - CBitcoinAddress address(params[1].get_str()); + string strAccount = AccountFromValue(request.params[0]); + CBitcoinAddress address(request.params[1].get_str()); if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); - CAmount nAmount = AmountFromValue(params[2]); + CAmount nAmount = AmountFromValue(request.params[2]); if (nAmount <= 0) throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send"); int nMinDepth = 1; - if (params.size() > 3) - nMinDepth = params[3].get_int(); + if (request.params.size() > 3) + nMinDepth = request.params[3].get_int(); CWalletTx wtx; wtx.strFromAccount = strAccount; - if (params.size() > 4 && !params[4].isNull() && !params[4].get_str().empty()) - wtx.mapValue["comment"] = params[4].get_str(); - if (params.size() > 5 && !params[5].isNull() && !params[5].get_str().empty()) - wtx.mapValue["to"] = params[5].get_str(); + if (request.params.size() > 4 && !request.params[4].isNull() && !request.params[4].get_str().empty()) + wtx.mapValue["comment"] = request.params[4].get_str(); + if (request.params.size() > 5 && !request.params[5].isNull() && !request.params[5].get_str().empty()) + wtx.mapValue["to"] = request.params[5].get_str(); EnsureWalletIsUnlocked(); @@ -851,12 +851,12 @@ UniValue sendfrom(const UniValue& params, bool fHelp) } -UniValue sendmany(const UniValue& params, bool fHelp) +UniValue sendmany(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() < 2 || params.size() > 5) + 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." @@ -897,20 +897,20 @@ UniValue sendmany(const UniValue& params, bool fHelp) if (pwalletMain->GetBroadcastTransactions() && !g_connman) throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); - string strAccount = AccountFromValue(params[0]); - UniValue sendTo = params[1].get_obj(); + string strAccount = AccountFromValue(request.params[0]); + UniValue sendTo = request.params[1].get_obj(); int nMinDepth = 1; - if (params.size() > 2) - nMinDepth = params[2].get_int(); + if (request.params.size() > 2) + nMinDepth = request.params[2].get_int(); CWalletTx wtx; wtx.strFromAccount = strAccount; - if (params.size() > 3 && !params[3].isNull() && !params[3].get_str().empty()) - wtx.mapValue["comment"] = params[3].get_str(); + if (request.params.size() > 3 && !request.params[3].isNull() && !request.params[3].get_str().empty()) + wtx.mapValue["comment"] = request.params[3].get_str(); UniValue subtractFeeFromAmount(UniValue::VARR); - if (params.size() > 4) - subtractFeeFromAmount = params[4].get_array(); + if (request.params.size() > 4) + subtractFeeFromAmount = request.params[4].get_array(); set<CBitcoinAddress> setAddress; vector<CRecipient> vecSend; @@ -968,12 +968,12 @@ UniValue sendmany(const UniValue& params, bool fHelp) // Defined in rpc/misc.cpp extern CScript _createmultisig_redeemScript(const UniValue& params); -UniValue addmultisigaddress(const UniValue& params, bool fHelp) +UniValue addmultisigaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() < 2 || params.size() > 3) + if (request.fHelp || request.params.size() < 2 || request.params.size() > 3) { string msg = "addmultisigaddress nrequired [\"key\",...] ( \"account\" )\n" "\nAdd a nrequired-to-sign multisignature address to the wallet.\n" @@ -1004,11 +1004,11 @@ UniValue addmultisigaddress(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); string strAccount; - if (params.size() > 2) - strAccount = AccountFromValue(params[2]); + if (request.params.size() > 2) + strAccount = AccountFromValue(request.params[2]); // Construct using pay-to-script-hash: - CScript inner = _createmultisig_redeemScript(params); + CScript inner = _createmultisig_redeemScript(request.params); CScriptID innerID(inner); pwalletMain->AddCScript(inner); @@ -1025,9 +1025,12 @@ public: bool operator()(const CKeyID &keyID) { CPubKey pubkey; - if (pwalletMain && pwalletMain->GetPubKey(keyID, pubkey)) { - CScript basescript; - basescript << ToByteVector(pubkey) << OP_CHECKSIG; + if (pwalletMain) { + CScript basescript = GetScriptForDestination(keyID); + isminetype typ; + typ = IsMine(*pwalletMain, basescript, SIGVERSION_WITNESS_V0); + if (typ != ISMINE_SPENDABLE && typ != ISMINE_WATCH_SOLVABLE) + return false; CScript witscript = GetScriptForWitness(basescript); pwalletMain->AddCScript(witscript); result = CScriptID(witscript); @@ -1045,6 +1048,10 @@ public: result = scriptID; return true; } + isminetype typ; + typ = IsMine(*pwalletMain, subscript, SIGVERSION_WITNESS_V0); + if (typ != ISMINE_SPENDABLE && typ != ISMINE_WATCH_SOLVABLE) + return false; CScript witscript = GetScriptForWitness(subscript); pwalletMain->AddCScript(witscript); result = CScriptID(witscript); @@ -1054,12 +1061,12 @@ public: } }; -UniValue addwitnessaddress(const UniValue& params, bool fHelp) +UniValue addwitnessaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() < 1 || params.size() > 1) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 1) { string msg = "addwitnessaddress \"address\"\n" "\nAdd a witness address for a script (with pubkey or redeemscript known).\n" @@ -1082,7 +1089,7 @@ UniValue addwitnessaddress(const UniValue& params, bool fHelp) } } - CBitcoinAddress address(params[0].get_str()); + CBitcoinAddress address(request.params[0].get_str()); if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); @@ -1090,7 +1097,7 @@ UniValue addwitnessaddress(const UniValue& params, bool fHelp) 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"); + throw JSONRPCError(RPC_WALLET_ERROR, "Public key or redeemscript not known to wallet, or the key is uncompressed"); } pwalletMain->SetAddressBook(w.result, "", "receive"); @@ -1232,12 +1239,12 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts) return ret; } -UniValue listreceivedbyaddress(const UniValue& params, bool fHelp) +UniValue listreceivedbyaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() > 3) + if (request.fHelp || request.params.size() > 3) throw runtime_error( "listreceivedbyaddress ( minconf includeempty includeWatchonly)\n" "\nList balances by receiving address.\n" @@ -1267,15 +1274,15 @@ UniValue listreceivedbyaddress(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - return ListReceived(params, false); + return ListReceived(request.params, false); } -UniValue listreceivedbyaccount(const UniValue& params, bool fHelp) +UniValue listreceivedbyaccount(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() > 3) + if (request.fHelp || request.params.size() > 3) throw runtime_error( "listreceivedbyaccount ( minconf includeempty includeWatchonly)\n" "\nDEPRECATED. List balances by account.\n" @@ -1304,7 +1311,7 @@ UniValue listreceivedbyaccount(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - return ListReceived(params, true); + return ListReceived(request.params, true); } static void MaybePushAddress(UniValue & entry, const CTxDestination &dest) @@ -1406,12 +1413,12 @@ void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Un } } -UniValue listtransactions(const UniValue& params, bool fHelp) +UniValue listtransactions(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() > 4) + if (request.fHelp || request.params.size() > 4) throw runtime_error( "listtransactions ( \"account\" count from includeWatchonly)\n" "\nReturns up to 'count' most recent transactions skipping the first 'from' transactions for account 'account'.\n" @@ -1473,17 +1480,17 @@ UniValue listtransactions(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); string strAccount = "*"; - if (params.size() > 0) - strAccount = params[0].get_str(); + if (request.params.size() > 0) + strAccount = request.params[0].get_str(); int nCount = 10; - if (params.size() > 1) - nCount = params[1].get_int(); + if (request.params.size() > 1) + nCount = request.params[1].get_int(); int nFrom = 0; - if (params.size() > 2) - nFrom = params[2].get_int(); + if (request.params.size() > 2) + nFrom = request.params[2].get_int(); isminefilter filter = ISMINE_SPENDABLE; - if(params.size() > 3) - if(params[3].get_bool()) + if(request.params.size() > 3) + if(request.params[3].get_bool()) filter = filter | ISMINE_WATCH_ONLY; if (nCount < 0) @@ -1533,12 +1540,12 @@ UniValue listtransactions(const UniValue& params, bool fHelp) return ret; } -UniValue listaccounts(const UniValue& params, bool fHelp) +UniValue listaccounts(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() > 2) + if (request.fHelp || request.params.size() > 2) throw runtime_error( "listaccounts ( minconf includeWatchonly)\n" "\nDEPRECATED. Returns Object that has account names as keys, account balances as values.\n" @@ -1564,11 +1571,11 @@ UniValue listaccounts(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); int nMinDepth = 1; - if (params.size() > 0) - nMinDepth = params[0].get_int(); + if (request.params.size() > 0) + nMinDepth = request.params[0].get_int(); isminefilter includeWatchonly = ISMINE_SPENDABLE; - if(params.size() > 1) - if(params[1].get_bool()) + if(request.params.size() > 1) + if(request.params[1].get_bool()) includeWatchonly = includeWatchonly | ISMINE_WATCH_ONLY; map<string, CAmount> mapAccountBalances; @@ -1612,12 +1619,12 @@ UniValue listaccounts(const UniValue& params, bool fHelp) return ret; } -UniValue listsinceblock(const UniValue& params, bool fHelp) +UniValue listsinceblock(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp) + if (request.fHelp) throw runtime_error( "listsinceblock ( \"blockhash\" target-confirmations includeWatchonly)\n" "\nGet all transactions in blocks since block [blockhash], or all transactions if omitted\n" @@ -1660,26 +1667,26 @@ UniValue listsinceblock(const UniValue& params, bool fHelp) int target_confirms = 1; isminefilter filter = ISMINE_SPENDABLE; - if (params.size() > 0) + if (request.params.size() > 0) { uint256 blockId; - blockId.SetHex(params[0].get_str()); + blockId.SetHex(request.params[0].get_str()); BlockMap::iterator it = mapBlockIndex.find(blockId); if (it != mapBlockIndex.end()) pindex = it->second; } - if (params.size() > 1) + if (request.params.size() > 1) { - target_confirms = params[1].get_int(); + target_confirms = request.params[1].get_int(); if (target_confirms < 1) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter"); } - if(params.size() > 2) - if(params[2].get_bool()) + if(request.params.size() > 2) + if(request.params[2].get_bool()) filter = filter | ISMINE_WATCH_ONLY; int depth = pindex ? (1 + chainActive.Height() - pindex->nHeight) : -1; @@ -1704,12 +1711,12 @@ UniValue listsinceblock(const UniValue& params, bool fHelp) return ret; } -UniValue gettransaction(const UniValue& params, bool fHelp) +UniValue gettransaction(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() < 1 || params.size() > 2) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( "gettransaction \"txid\" ( includeWatchonly )\n" "\nGet detailed information about in-wallet transaction <txid>\n" @@ -1751,11 +1758,11 @@ UniValue gettransaction(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); uint256 hash; - hash.SetHex(params[0].get_str()); + hash.SetHex(request.params[0].get_str()); isminefilter filter = ISMINE_SPENDABLE; - if(params.size() > 1) - if(params[1].get_bool()) + if(request.params.size() > 1) + if(request.params[1].get_bool()) filter = filter | ISMINE_WATCH_ONLY; UniValue entry(UniValue::VOBJ); @@ -1784,12 +1791,12 @@ UniValue gettransaction(const UniValue& params, bool fHelp) return entry; } -UniValue abandontransaction(const UniValue& params, bool fHelp) +UniValue abandontransaction(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "abandontransaction \"txid\"\n" "\nMark in-wallet transaction <txid> as abandoned\n" @@ -1808,7 +1815,7 @@ UniValue abandontransaction(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); uint256 hash; - hash.SetHex(params[0].get_str()); + hash.SetHex(request.params[0].get_str()); if (!pwalletMain->mapWallet.count(hash)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id"); @@ -1819,12 +1826,12 @@ UniValue abandontransaction(const UniValue& params, bool fHelp) } -UniValue backupwallet(const UniValue& params, bool fHelp) +UniValue backupwallet(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "backupwallet \"destination\"\n" "\nSafely copies current wallet file to destination, which can be a directory or a path with filename.\n" @@ -1837,7 +1844,7 @@ UniValue backupwallet(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - string strDest = params[0].get_str(); + string strDest = request.params[0].get_str(); if (!pwalletMain->BackupWallet(strDest)) throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!"); @@ -1845,12 +1852,12 @@ UniValue backupwallet(const UniValue& params, bool fHelp) } -UniValue keypoolrefill(const UniValue& params, bool fHelp) +UniValue keypoolrefill(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() > 1) + if (request.fHelp || request.params.size() > 1) throw runtime_error( "keypoolrefill ( newsize )\n" "\nFills the keypool." @@ -1866,10 +1873,10 @@ UniValue keypoolrefill(const UniValue& params, bool fHelp) // 0 is interpreted by TopUpKeyPool() as the default keypool size given by -keypool unsigned int kpSize = 0; - if (params.size() > 0) { - if (params[0].get_int() < 0) + if (request.params.size() > 0) { + if (request.params[0].get_int() < 0) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected valid size."); - kpSize = (unsigned int)params[0].get_int(); + kpSize = (unsigned int)request.params[0].get_int(); } EnsureWalletIsUnlocked(); @@ -1889,12 +1896,12 @@ static void LockWallet(CWallet* pWallet) pWallet->Lock(); } -UniValue walletpassphrase(const UniValue& params, bool fHelp) +UniValue walletpassphrase(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2)) + if (pwalletMain->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" @@ -1916,17 +1923,17 @@ UniValue walletpassphrase(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - if (fHelp) + if (request.fHelp) return true; if (!pwalletMain->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 params[0] which is not mlock()ed + // Note that the walletpassphrase is stored in request.params[0] which is not mlock()ed SecureString strWalletPass; strWalletPass.reserve(100); // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string) - // Alternately, find a way to make params[0] mlock()'d to begin with. - strWalletPass = params[0].get_str().c_str(); + // Alternately, find a way to make request.params[0] mlock()'d to begin with. + strWalletPass = request.params[0].get_str().c_str(); if (strWalletPass.length() > 0) { @@ -1940,7 +1947,7 @@ UniValue walletpassphrase(const UniValue& params, bool fHelp) pwalletMain->TopUpKeyPool(); - int64_t nSleepTime = params[1].get_int64(); + int64_t nSleepTime = request.params[1].get_int64(); LOCK(cs_nWalletUnlockTime); nWalletUnlockTime = GetTime() + nSleepTime; RPCRunLater("lockwallet", boost::bind(LockWallet, pwalletMain), nSleepTime); @@ -1949,12 +1956,12 @@ UniValue walletpassphrase(const UniValue& params, bool fHelp) } -UniValue walletpassphrasechange(const UniValue& params, bool fHelp) +UniValue walletpassphrasechange(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2)) + if (pwalletMain->IsCrypted() && (request.fHelp || request.params.size() != 2)) throw runtime_error( "walletpassphrasechange \"oldpassphrase\" \"newpassphrase\"\n" "\nChanges the wallet passphrase from 'oldpassphrase' to 'newpassphrase'.\n" @@ -1968,20 +1975,20 @@ UniValue walletpassphrasechange(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - if (fHelp) + if (request.fHelp) return true; if (!pwalletMain->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 params[0] mlock()'d to begin with. + // Alternately, find a way to make request.params[0] mlock()'d to begin with. SecureString strOldWalletPass; strOldWalletPass.reserve(100); - strOldWalletPass = params[0].get_str().c_str(); + strOldWalletPass = request.params[0].get_str().c_str(); SecureString strNewWalletPass; strNewWalletPass.reserve(100); - strNewWalletPass = params[1].get_str().c_str(); + strNewWalletPass = request.params[1].get_str().c_str(); if (strOldWalletPass.length() < 1 || strNewWalletPass.length() < 1) throw runtime_error( @@ -1995,12 +2002,12 @@ UniValue walletpassphrasechange(const UniValue& params, bool fHelp) } -UniValue walletlock(const UniValue& params, bool fHelp) +UniValue walletlock(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (pwalletMain->IsCrypted() && (fHelp || params.size() != 0)) + if (pwalletMain->IsCrypted() && (request.fHelp || request.params.size() != 0)) throw runtime_error( "walletlock\n" "\nRemoves the wallet encryption key from memory, locking the wallet.\n" @@ -2019,7 +2026,7 @@ UniValue walletlock(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - if (fHelp) + if (request.fHelp) return true; if (!pwalletMain->IsCrypted()) throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletlock was called."); @@ -2034,12 +2041,12 @@ UniValue walletlock(const UniValue& params, bool fHelp) } -UniValue encryptwallet(const UniValue& params, bool fHelp) +UniValue encryptwallet(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (!pwalletMain->IsCrypted() && (fHelp || params.size() != 1)) + if (!pwalletMain->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" @@ -2065,16 +2072,16 @@ UniValue encryptwallet(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - if (fHelp) + if (request.fHelp) return true; if (pwalletMain->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 params[0] mlock()'d to begin with. + // Alternately, find a way to make request.params[0] mlock()'d to begin with. SecureString strWalletPass; strWalletPass.reserve(100); - strWalletPass = params[0].get_str().c_str(); + strWalletPass = request.params[0].get_str().c_str(); if (strWalletPass.length() < 1) throw runtime_error( @@ -2091,12 +2098,12 @@ UniValue encryptwallet(const UniValue& params, bool fHelp) return "wallet encrypted; Bitcoin server stopping, restart to run with encrypted wallet. The keypool has been flushed and a new HD seed was generated (if you are using HD). You need to make a new backup."; } -UniValue lockunspent(const UniValue& params, bool fHelp) +UniValue lockunspent(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() < 1 || params.size() > 2) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( "lockunspent unlock ([{\"txid\":\"txid\",\"vout\":n},...])\n" "\nUpdates list of temporarily unspendable outputs.\n" @@ -2135,20 +2142,20 @@ UniValue lockunspent(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - if (params.size() == 1) - RPCTypeCheck(params, boost::assign::list_of(UniValue::VBOOL)); + if (request.params.size() == 1) + RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VBOOL)); else - RPCTypeCheck(params, boost::assign::list_of(UniValue::VBOOL)(UniValue::VARR)); + RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VBOOL)(UniValue::VARR)); - bool fUnlock = params[0].get_bool(); + bool fUnlock = request.params[0].get_bool(); - if (params.size() == 1) { + if (request.params.size() == 1) { if (fUnlock) pwalletMain->UnlockAllCoins(); return true; } - UniValue outputs = params[1].get_array(); + UniValue outputs = request.params[1].get_array(); for (unsigned int idx = 0; idx < outputs.size(); idx++) { const UniValue& output = outputs[idx]; if (!output.isObject()) @@ -2180,12 +2187,12 @@ UniValue lockunspent(const UniValue& params, bool fHelp) return true; } -UniValue listlockunspent(const UniValue& params, bool fHelp) +UniValue listlockunspent(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() > 0) + if (request.fHelp || request.params.size() > 0) throw runtime_error( "listlockunspent\n" "\nReturns list of temporarily unspendable outputs.\n" @@ -2229,12 +2236,12 @@ UniValue listlockunspent(const UniValue& params, bool fHelp) return ret; } -UniValue settxfee(const UniValue& params, bool fHelp) +UniValue settxfee(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() < 1 || params.size() > 1) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 1) throw runtime_error( "settxfee amount\n" "\nSet the transaction fee per kB. Overwrites the paytxfee parameter.\n" @@ -2250,18 +2257,18 @@ UniValue settxfee(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); // Amount - CAmount nAmount = AmountFromValue(params[0]); + CAmount nAmount = AmountFromValue(request.params[0]); payTxFee = CFeeRate(nAmount, 1000); return true; } -UniValue getwalletinfo(const UniValue& params, bool fHelp) +UniValue getwalletinfo(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() != 0) + if (request.fHelp || request.params.size() != 0) throw runtime_error( "getwalletinfo\n" "Returns an object containing various wallet state info.\n" @@ -2302,12 +2309,12 @@ UniValue getwalletinfo(const UniValue& params, bool fHelp) return obj; } -UniValue resendwallettransactions(const UniValue& params, bool fHelp) +UniValue resendwallettransactions(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() != 0) + if (request.fHelp || request.params.size() != 0) throw runtime_error( "resendwallettransactions\n" "Immediately re-broadcast unconfirmed wallet transactions to all peers.\n" @@ -2330,12 +2337,12 @@ UniValue resendwallettransactions(const UniValue& params, bool fHelp) return result; } -UniValue listunspent(const UniValue& params, bool fHelp) +UniValue listunspent(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() > 3) + if (request.fHelp || request.params.size() > 3) throw runtime_error( "listunspent ( minconf maxconf [\"address\",...] )\n" "\nReturns array of unspent transaction outputs\n" @@ -2372,19 +2379,19 @@ UniValue listunspent(const UniValue& params, bool fHelp) + HelpExampleRpc("listunspent", "6, 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"") ); - RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM)(UniValue::VNUM)(UniValue::VARR)); + RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VNUM)(UniValue::VNUM)(UniValue::VARR)); int nMinDepth = 1; - if (params.size() > 0) - nMinDepth = params[0].get_int(); + if (request.params.size() > 0) + nMinDepth = request.params[0].get_int(); int nMaxDepth = 9999999; - if (params.size() > 1) - nMaxDepth = params[1].get_int(); + if (request.params.size() > 1) + nMaxDepth = request.params[1].get_int(); set<CBitcoinAddress> setAddress; - if (params.size() > 2) { - UniValue inputs = params[2].get_array(); + if (request.params.size() > 2) { + UniValue inputs = request.params[2].get_array(); for (unsigned int idx = 0; idx < inputs.size(); idx++) { const UniValue& input = inputs[idx]; CBitcoinAddress address(input.get_str()); @@ -2441,12 +2448,12 @@ UniValue listunspent(const UniValue& params, bool fHelp) return results; } -UniValue fundrawtransaction(const UniValue& params, bool fHelp) +UniValue fundrawtransaction(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() < 1 || params.size() > 2) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( "fundrawtransaction \"hexstring\" ( options )\n" "\nAdd inputs to a transaction until it has enough in value to meet its out value.\n" @@ -2487,7 +2494,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) + HelpExampleCli("sendrawtransaction", "\"signedtransactionhex\"") ); - RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)); + RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VSTR)); CTxDestination changeAddress = CNoDestination(); int changePosition = -1; @@ -2496,15 +2503,15 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) CFeeRate feeRate = CFeeRate(0); bool overrideEstimatedFeerate = false; - if (params.size() > 1) { - if (params[1].type() == UniValue::VBOOL) { + if (request.params.size() > 1) { + if (request.params[1].type() == UniValue::VBOOL) { // backward compatibility bool only fallback - includeWatching = params[1].get_bool(); + includeWatching = request.params[1].get_bool(); } else { - RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VOBJ)); + RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VSTR)(UniValue::VOBJ)); - UniValue options = params[1]; + UniValue options = request.params[1]; RPCTypeCheckObj(options, { @@ -2544,7 +2551,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) // parse hex string from parameter CTransaction origTx; - if (!DecodeHexTx(origTx, params[0].get_str(), true)) + if (!DecodeHexTx(origTx, request.params[0].get_str(), true)) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); if (origTx.vout.size() == 0) @@ -2568,14 +2575,14 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) return result; } -extern UniValue dumpprivkey(const UniValue& params, bool fHelp); // in rpcdump.cpp -extern UniValue importprivkey(const UniValue& params, bool fHelp); -extern UniValue importaddress(const UniValue& params, bool fHelp); -extern UniValue importpubkey(const UniValue& params, bool fHelp); -extern UniValue dumpwallet(const UniValue& params, bool fHelp); -extern UniValue importwallet(const UniValue& params, bool fHelp); -extern UniValue importprunedfunds(const UniValue& params, bool fHelp); -extern UniValue removeprunedfunds(const UniValue& params, bool fHelp); +extern UniValue dumpprivkey(const JSONRPCRequest& request); // in rpcdump.cpp +extern UniValue importprivkey(const JSONRPCRequest& request); +extern UniValue importaddress(const JSONRPCRequest& request); +extern UniValue importpubkey(const JSONRPCRequest& request); +extern UniValue dumpwallet(const JSONRPCRequest& request); +extern UniValue importwallet(const JSONRPCRequest& request); +extern UniValue importprunedfunds(const JSONRPCRequest& request); +extern UniValue removeprunedfunds(const JSONRPCRequest& request); static const CRPCCommand commands[] = { // category name actor (function) okSafeMode diff --git a/src/wallet/test/crypto_tests.cpp b/src/wallet/test/crypto_tests.cpp index 05387f5f2b..c5f55ef5f0 100644 --- a/src/wallet/test/crypto_tests.cpp +++ b/src/wallet/test/crypto_tests.cpp @@ -2,7 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "random.h" +#include "test/test_random.h" #include "utilstrencodings.h" #include "test/test_bitcoin.h" #include "wallet/crypter.h" diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 6f86f3360d..c7f98b238e 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1463,7 +1463,7 @@ void CWallet::ReacceptWalletTransactions() CWalletTx& wtx = *(item.second); LOCK(mempool.cs); - wtx.AcceptToMemoryPool(false, maxTxFee); + wtx.AcceptToMemoryPool(maxTxFee); } } @@ -1907,7 +1907,7 @@ static void ApproximateBestSubset(vector<pair<CAmount, pair<const CWalletTx*,uns vfBest.assign(vValue.size(), true); nBest = nTotalLower; - seed_insecure_rand(); + FastRandomContext insecure_rand; for (int nRep = 0; nRep < iterations && nBest != nTargetValue; nRep++) { @@ -1924,7 +1924,7 @@ static void ApproximateBestSubset(vector<pair<CAmount, pair<const CWalletTx*,uns //that the rng is fast. We do not use a constant random sequence, //because there may be some privacy improvement by making //the selection random. - if (nPass == 0 ? insecure_rand()&1 : !vfIncluded[i]) + if (nPass == 0 ? insecure_rand.rand32()&1 : !vfIncluded[i]) { nTotal += vValue[i].first; vfIncluded[i] = true; @@ -2502,8 +2502,7 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CCon if (fBroadcastTransactions) { // Broadcast - if (!wtxNew.AcceptToMemoryPool(false, maxTxFee)) - { + if (!wtxNew.AcceptToMemoryPool(maxTxFee)) { // This must not fail. The transaction has already been signed and recorded. LogPrintf("CommitTransaction(): Error: Transaction not valid\n"); return false; @@ -3650,8 +3649,8 @@ int CMerkleTx::GetBlocksToMaturity() const } -bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, CAmount nAbsurdFee) +bool CMerkleTx::AcceptToMemoryPool(const CAmount& nAbsurdFee) { CValidationState state; - return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, false, nAbsurdFee); + return ::AcceptToMemoryPool(mempool, state, *this, true, NULL, false, nAbsurdFee); } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 077edcab2d..3b37f7cb1f 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -215,7 +215,7 @@ public: bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet) > 0; } int GetBlocksToMaturity() const; /** Pass this transaction to the mempool. Fails if absolute fee exceeds absurd fee. */ - bool AcceptToMemoryPool(bool fLimitFree, const CAmount nAbsurdFee); + bool AcceptToMemoryPool(const CAmount& nAbsurdFee); bool hashUnset() const { return (hashBlock.IsNull() || hashBlock == ABANDON_HASH); } bool isAbandoned() const { return (hashBlock == ABANDON_HASH); } void setAbandoned() { hashBlock = ABANDON_HASH; } |