X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Frpcwallet.cpp;h=e0839b8bb13c7b86285063869513ed608abed199;hb=HEAD;hp=ad200624a6e195fdd1ba2a26f914e8eac6e69143;hpb=91e95a40e7a818d671eac2549830dd7dfe5fa21b;p=novacoin.git diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index ad20062..a5b5dd6 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -12,7 +12,6 @@ #include "base58.h" using namespace json_spirit; -using namespace std; int64_t nWalletUnlockTime; static CCriticalSection cs_nWalletUnlockTime; @@ -50,13 +49,13 @@ void WalletTxToJSON(const CWalletTx& wtx, Object& entry) entry.push_back(Pair("txid", wtx.GetHash().GetHex())); entry.push_back(Pair("time", (int64_t)wtx.GetTxTime())); entry.push_back(Pair("timereceived", (int64_t)wtx.nTimeReceived)); - BOOST_FOREACH(const PAIRTYPE(string,string)& item, wtx.mapValue) + for (const auto& item : wtx.mapValue) entry.push_back(Pair(item.first, item.second)); } -string AccountFromValue(const Value& value) +std::string AccountFromValue(const Value& value) { - string strAccount = value.get_str(); + std::string strAccount = value.get_str(); if (strAccount == "*") throw JSONRPCError(RPC_WALLET_INVALID_ACCOUNT_NAME, "Invalid account name"); return strAccount; @@ -65,7 +64,7 @@ string AccountFromValue(const Value& value) Value getinfo(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) - throw runtime_error( + throw std::runtime_error( "getinfo\n" "Returns an object containing various state info."); @@ -95,7 +94,7 @@ Value getinfo(const Array& params, bool fHelp) obj.push_back(Pair("moneysupply", ValueFromAmount(pindexBest->nMoneySupply))); obj.push_back(Pair("connections", (int)vNodes.size())); - obj.push_back(Pair("proxy", (proxy.first.IsValid() ? proxy.first.ToStringIPPort() : string()))); + obj.push_back(Pair("proxy", (proxy.first.IsValid() ? proxy.first.ToStringIPPort() : std::string()))); obj.push_back(Pair("ip", addrSeenByPeer.ToStringIP())); diff.push_back(Pair("proof-of-work", GetDifficulty())); @@ -116,14 +115,14 @@ Value getinfo(const Array& params, bool fHelp) Value getnewaddress(const Array& params, bool fHelp) { if (fHelp || params.size() > 1) - throw runtime_error( + throw std::runtime_error( "getnewaddress [account]\n" "Returns a new NovaCoin address for receiving payments. " "If [account] is specified (recommended), it is added to the address book " "so payments received with the address will be credited to [account]."); // Parse the account first so we don't generate a key if there's an error - string strAccount; + std::string strAccount; if (params.size() > 0) strAccount = AccountFromValue(params[0]); @@ -134,15 +133,15 @@ Value getnewaddress(const Array& params, bool fHelp) CPubKey newKey; if (!pwalletMain->GetKeyFromPool(newKey, false)) throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); - CKeyID keyID = newKey.GetID(); + CBitcoinAddress address(newKey.GetID()); - pwalletMain->SetAddressBookName(keyID, strAccount); + pwalletMain->SetAddressBookName(address, strAccount); - return CBitcoinAddress(keyID).ToString(); + return address.ToString(); } -CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false) +CBitcoinAddress GetAccountAddress(std::string strAccount, bool bForceNew=false) { CWalletDB walletdb(pwalletMain->strWalletFile); @@ -156,12 +155,12 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false) { CScript scriptPubKey; scriptPubKey.SetDestination(account.vchPubKey.GetID()); - for (map::iterator it = pwalletMain->mapWallet.begin(); + for (auto it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end() && account.vchPubKey.IsValid(); ++it) { const CWalletTx& wtx = (*it).second; - BOOST_FOREACH(const CTxOut& txout, wtx.vout) + for (const CTxOut& txout : wtx.vout) if (txout.scriptPubKey == scriptPubKey) bKeyUsed = true; } @@ -183,12 +182,12 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false) Value getaccountaddress(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) - throw runtime_error( + throw std::runtime_error( "getaccountaddress \n" "Returns the current NovaCoin address for receiving payments to this account."); // Parse the account first so we don't generate a key if there's an error - string strAccount = AccountFromValue(params[0]); + std::string strAccount = AccountFromValue(params[0]); Value ret; @@ -202,7 +201,7 @@ Value getaccountaddress(const Array& params, bool fHelp) Value setaccount(const Array& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) - throw runtime_error( + throw std::runtime_error( "setaccount \n" "Sets the account associated with the given address."); @@ -211,19 +210,19 @@ Value setaccount(const Array& params, bool fHelp) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid NovaCoin address"); - string strAccount; + std::string strAccount; if (params.size() > 1) strAccount = AccountFromValue(params[1]); // Detect when changing the account of an address that is the 'unused current key' of another account: - if (pwalletMain->mapAddressBook.count(address.Get())) + if (pwalletMain->mapAddressBook.count(address)) { - string strOldAccount = pwalletMain->mapAddressBook[address.Get()]; + std::string strOldAccount = pwalletMain->mapAddressBook[address]; if (address == GetAccountAddress(strOldAccount)) GetAccountAddress(strOldAccount, true); } - pwalletMain->SetAddressBookName(address.Get(), strAccount); + pwalletMain->SetAddressBookName(address, strAccount); return Value::null; } @@ -232,7 +231,7 @@ Value setaccount(const Array& params, bool fHelp) Value getaccount(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) - throw runtime_error( + throw std::runtime_error( "getaccount \n" "Returns the account associated with the given address."); @@ -240,8 +239,8 @@ Value getaccount(const Array& params, bool fHelp) if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid NovaCoin address"); - string strAccount; - map::iterator mi = pwalletMain->mapAddressBook.find(address.Get()); + std::string strAccount; + auto mi = pwalletMain->mapAddressBook.find(address); if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.empty()) strAccount = (*mi).second; return strAccount; @@ -251,18 +250,18 @@ Value getaccount(const Array& params, bool fHelp) Value getaddressesbyaccount(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) - throw runtime_error( + throw std::runtime_error( "getaddressesbyaccount \n" "Returns the list of addresses for the given account."); - string strAccount = AccountFromValue(params[0]); + std::string strAccount = AccountFromValue(params[0]); // Find all addresses that have the given account Array ret; - BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook) + for (const auto& item : pwalletMain->mapAddressBook) { const CBitcoinAddress& address = item.first; - const string& strName = item.second; + const std::string& strName = item.second; if (strName == strAccount) ret.push_back(address.ToString()); } @@ -272,7 +271,7 @@ Value getaddressesbyaccount(const Array& params, bool fHelp) Value mergecoins(const Array& params, bool fHelp) { if (fHelp || params.size() != 3) - throw runtime_error( + throw std::runtime_error( "mergecoins \n" " is resulting inputs sum\n" " is minimum value of inputs which are used in join process\n" @@ -304,12 +303,12 @@ Value mergecoins(const Array& params, bool fHelp) if (nOutputValue < nMinValue) throw JSONRPCError(-101, "Output value is lower than min value"); - list listMerged; + std::list listMerged; if (!pwalletMain->MergeCoins(nAmount, nMinValue, nOutputValue, listMerged)) return Value::null; Array mergedHashes; - BOOST_FOREACH(const uint256 txHash, listMerged) + for (const uint256 txHash : listMerged) mergedHashes.push_back(txHash.GetHex()); return mergedHashes; @@ -318,13 +317,19 @@ Value mergecoins(const Array& params, bool fHelp) Value sendtoaddress(const Array& params, bool fHelp) { if (fHelp || params.size() < 2 || params.size() > 4) - throw runtime_error( + throw std::runtime_error( "sendtoaddress [comment] [comment-to]\n" " is a real and is rounded to the nearest " + FormatMoney(nMinimumInputValue) + HelpRequiringPassphrase()); - CBitcoinAddress address(params[0].get_str()); - if (!address.IsValid()) + // Parse address + CScript scriptPubKey; + std::string strAddress = params[0].get_str(); + + CBitcoinAddress address(strAddress); + if (address.IsValid()) + scriptPubKey.SetAddress(address); + else throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid NovaCoin address"); // Amount @@ -343,8 +348,8 @@ Value sendtoaddress(const Array& params, bool fHelp) if (pwalletMain->IsLocked()) throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first."); - string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx); - if (strError != "") + std::string strError = pwalletMain->SendMoney(scriptPubKey, nAmount, wtx); + if (!strError.empty()) throw JSONRPCError(RPC_WALLET_ERROR, strError); return wtx.GetHash().GetHex(); @@ -353,26 +358,26 @@ Value sendtoaddress(const Array& params, bool fHelp) Value listaddressgroupings(const Array& params, bool fHelp) { if (fHelp) - throw runtime_error( + throw std::runtime_error( "listaddressgroupings\n" "Lists groups of addresses which have had their common ownership\n" "made public by common use as inputs or as the resulting change\n" "in past transactions"); Array jsonGroupings; - map balances = pwalletMain->GetAddressBalances(); - BOOST_FOREACH(set grouping, pwalletMain->GetAddressGroupings()) + auto balances = pwalletMain->GetAddressBalances(); + for (auto grouping : pwalletMain->GetAddressGroupings()) { Array jsonGrouping; - BOOST_FOREACH(CTxDestination address, grouping) + for (CBitcoinAddress address : grouping) { Array addressInfo; - addressInfo.push_back(CBitcoinAddress(address).ToString()); + addressInfo.push_back(address.ToString()); addressInfo.push_back(ValueFromAmount(balances[address])); { LOCK(pwalletMain->cs_wallet); - if (pwalletMain->mapAddressBook.find(CBitcoinAddress(address).Get()) != pwalletMain->mapAddressBook.end()) - addressInfo.push_back(pwalletMain->mapAddressBook.find(CBitcoinAddress(address).Get())->second); + if (pwalletMain->mapAddressBook.find(address) != pwalletMain->mapAddressBook.end()) + addressInfo.push_back(pwalletMain->mapAddressBook.find(address)->second); } jsonGrouping.push_back(addressInfo); } @@ -384,14 +389,14 @@ Value listaddressgroupings(const Array& params, bool fHelp) Value signmessage(const Array& params, bool fHelp) { if (fHelp || params.size() != 2) - throw runtime_error( + throw std::runtime_error( "signmessage \n" "Sign a message with the private key of an address"); EnsureWalletIsUnlocked(); - string strAddress = params[0].get_str(); - string strMessage = params[1].get_str(); + std::string strAddress = params[0].get_str(); + std::string strMessage = params[1].get_str(); CBitcoinAddress addr(strAddress); if (!addr.IsValid()) @@ -409,7 +414,7 @@ Value signmessage(const Array& params, bool fHelp) ss << strMessageMagic; ss << strMessage; - vector vchSig; + std::vector vchSig; if (!key.SignCompact(Hash(ss.begin(), ss.end()), vchSig)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed"); @@ -419,13 +424,13 @@ Value signmessage(const Array& params, bool fHelp) Value verifymessage(const Array& params, bool fHelp) { if (fHelp || params.size() != 3) - throw runtime_error( + throw std::runtime_error( "verifymessage \n" "Verify a signed message"); - string strAddress = params[0].get_str(); - string strSign = params[1].get_str(); - string strMessage = params[2].get_str(); + std::string strAddress = params[0].get_str(); + std::string strSign = params[1].get_str(); + std::string strMessage = params[2].get_str(); CBitcoinAddress addr(strAddress); if (!addr.IsValid()) @@ -436,7 +441,7 @@ Value verifymessage(const Array& params, bool fHelp) throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key"); bool fInvalid = false; - vector vchSig = DecodeBase64(strSign.c_str(), &fInvalid); + std::vector vchSig = DecodeBase64(strSign.c_str(), &fInvalid); if (fInvalid) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Malformed base64 encoding"); @@ -445,28 +450,26 @@ Value verifymessage(const Array& params, bool fHelp) ss << strMessageMagic; ss << strMessage; - CKey key; + CPubKey key; if (!key.SetCompactSignature(Hash(ss.begin(), ss.end()), vchSig)) return false; - return (key.GetPubKey().GetID() == keyID); + return (key.GetID() == keyID); } Value getreceivedbyaddress(const Array& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) - throw runtime_error( - "getreceivedbyaddress [minconf=1]\n" - "Returns the total amount received by in transactions with at least [minconf] confirmations."); + throw std::runtime_error( + "getreceivedbyaddress [minconf=1]\n" + "Returns the total amount received by in transactions with at least [minconf] confirmations."); // Bitcoin address CBitcoinAddress address = CBitcoinAddress(params[0].get_str()); - CScript scriptPubKey; if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid NovaCoin address"); - scriptPubKey.SetDestination(address.Get()); - if (!IsMine(*pwalletMain,scriptPubKey)) + if (!IsMine(*pwalletMain,address)) return 0.0; // Minimum confirmations @@ -474,30 +477,32 @@ Value getreceivedbyaddress(const Array& params, bool fHelp) if (params.size() > 1) nMinDepth = params[1].get_int(); - // Tally int64_t nAmount = 0; - for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + for (auto it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { const CWalletTx& wtx = (*it).second; if (wtx.IsCoinBase() || wtx.IsCoinStake() || !wtx.IsFinal()) continue; - - BOOST_FOREACH(const CTxOut& txout, wtx.vout) - if (txout.scriptPubKey == scriptPubKey) + for (const CTxOut& txout : wtx.vout) + { + CBitcoinAddress addressRet; + if (!ExtractAddress(*pwalletMain, txout.scriptPubKey, addressRet)) + continue; + if (addressRet == address) if (wtx.GetDepthInMainChain() >= nMinDepth) nAmount += txout.nValue; + } } return ValueFromAmount(nAmount); } - -void GetAccountAddresses(string strAccount, set& setAddress) +void GetAccountAddresses(std::string strAccount, std::set& setAddress) { - BOOST_FOREACH(const PAIRTYPE(CTxDestination, string)& item, pwalletMain->mapAddressBook) + for (const auto& item : pwalletMain->mapAddressBook) { - const CTxDestination& address = item.first; - const string& strName = item.second; + const CBitcoinAddress& address = item.first; + const std::string& strName = item.second; if (strName == strAccount) setAddress.insert(address); } @@ -506,7 +511,7 @@ void GetAccountAddresses(string strAccount, set& setAddress) Value getreceivedbyaccount(const Array& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) - throw runtime_error( + throw std::runtime_error( "getreceivedbyaccount [minconf=1]\n" "Returns the total amount received by addresses with in transactions with at least [minconf] confirmations."); @@ -516,22 +521,22 @@ Value getreceivedbyaccount(const Array& params, bool fHelp) nMinDepth = params[1].get_int(); // Get the set of pub keys assigned to account - string strAccount = AccountFromValue(params[0]); - set setAddress; + std::string strAccount = AccountFromValue(params[0]); + std::set setAddress; GetAccountAddresses(strAccount, setAddress); // Tally int64_t nAmount = 0; - for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + for (auto it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { const CWalletTx& wtx = (*it).second; if (wtx.IsCoinBase() || wtx.IsCoinStake() || !wtx.IsFinal()) continue; - BOOST_FOREACH(const CTxOut& txout, wtx.vout) + for (const CTxOut& txout : wtx.vout) { - CTxDestination address; - if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*pwalletMain, address) && setAddress.count(address)) + CBitcoinAddress address; + if (ExtractAddress(*pwalletMain, txout.scriptPubKey, address) && IsMine(*pwalletMain, address) && setAddress.count(address)) if (wtx.GetDepthInMainChain() >= nMinDepth) nAmount += txout.nValue; } @@ -541,12 +546,12 @@ Value getreceivedbyaccount(const Array& params, bool fHelp) } -int64_t GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth, const isminefilter& filter) +int64_t GetAccountBalance(CWalletDB& walletdb, const std::string& strAccount, int nMinDepth, const isminefilter& filter) { int64_t nBalance = 0; // Tally wallet transactions - for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + for (auto it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { const CWalletTx& wtx = (*it).second; if (!wtx.IsFinal()) @@ -566,7 +571,7 @@ int64_t GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMi return nBalance; } -int64_t GetAccountBalance(const string& strAccount, int nMinDepth, const isminefilter& filter) +int64_t GetAccountBalance(const std::string& strAccount, int nMinDepth, const isminefilter& filter) { CWalletDB walletdb(pwalletMain->strWalletFile); return GetAccountBalance(walletdb, strAccount, nMinDepth, filter); @@ -575,8 +580,8 @@ int64_t GetAccountBalance(const string& strAccount, int nMinDepth, const isminef Value getbalance(const Array& params, bool fHelp) { - if (fHelp || params.size() > 2) - throw runtime_error( + if (fHelp || params.size() > 3) + throw std::runtime_error( "getbalance [account] [minconf=1] [watchonly=0]\n" "If [account] is not specified, returns the server's total available balance.\n" "If [account] is specified, returns the balance in the account.\n" @@ -598,7 +603,7 @@ Value getbalance(const Array& params, bool fHelp) // (GetBalance() sums up all unspent TxOuts) // getbalance and getbalance '*' 0 should return the same number. int64_t nBalance = 0; - for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + for (auto it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { const CWalletTx& wtx = (*it).second; if (!wtx.IsTrusted()) @@ -607,16 +612,16 @@ Value getbalance(const Array& params, bool fHelp) int64_t allGeneratedImmature, allGeneratedMature, allFee; allGeneratedImmature = allGeneratedMature = allFee = 0; - string strSentAccount; - list > listReceived; - list > listSent; + std::string strSentAccount; + std::list > listReceived; + std::list > listSent; wtx.GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount, filter); if (wtx.GetDepthInMainChain() >= nMinDepth) { - BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64_t)& r, listReceived) + for (const auto& r : listReceived) nBalance += r.second; } - BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64_t)& r, listSent) + for (const auto& r : listSent) nBalance -= r.second; nBalance -= allFee; nBalance += allGeneratedMature; @@ -624,7 +629,7 @@ Value getbalance(const Array& params, bool fHelp) return ValueFromAmount(nBalance); } - string strAccount = AccountFromValue(params[0]); + std::string strAccount = AccountFromValue(params[0]); int64_t nBalance = GetAccountBalance(strAccount, nMinDepth, filter); @@ -635,12 +640,12 @@ Value getbalance(const Array& params, bool fHelp) Value movecmd(const Array& params, bool fHelp) { if (fHelp || params.size() < 3 || params.size() > 5) - throw runtime_error( + throw std::runtime_error( "move [minconf=1] [comment]\n" "Move from one account in your wallet to another."); - string strFrom = AccountFromValue(params[0]); - string strTo = AccountFromValue(params[1]); + std::string strFrom = AccountFromValue(params[0]); + std::string strTo = AccountFromValue(params[1]); int64_t nAmount = AmountFromValue(params[2]); if (nAmount < nMinimumInputValue) @@ -649,7 +654,7 @@ Value movecmd(const Array& params, bool fHelp) if (params.size() > 3) // unused parameter, used to be nMinDepth, keep type-checking it though (void)params[3].get_int(); - string strComment; + std::string strComment; if (params.size() > 4) strComment = params[4].get_str(); @@ -689,15 +694,24 @@ Value movecmd(const Array& params, bool fHelp) Value sendfrom(const Array& params, bool fHelp) { if (fHelp || params.size() < 3 || params.size() > 6) - throw runtime_error( + throw std::runtime_error( "sendfrom [minconf=1] [comment] [comment-to]\n" " is a real and is rounded to the nearest " + FormatMoney(nMinimumInputValue) + HelpRequiringPassphrase()); - string strAccount = AccountFromValue(params[0]); - CBitcoinAddress address(params[1].get_str()); - if (!address.IsValid()) + std::string strAccount = AccountFromValue(params[0]); + + // Parse address + CScript scriptPubKey; + std::string strAddress = params[1].get_str(); + + CBitcoinAddress address(strAddress); + if (address.IsValid()) + scriptPubKey.SetAddress(address); + else throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid NovaCoin address"); + + int64_t nAmount = AmountFromValue(params[2]); if (nAmount < nMinimumInputValue) @@ -722,8 +736,8 @@ Value sendfrom(const Array& params, bool fHelp) throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds"); // Send - string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx); - if (strError != "") + std::string strError = pwalletMain->SendMoney(scriptPubKey, nAmount, wtx); + if (!strError.empty()) throw JSONRPCError(RPC_WALLET_ERROR, strError); return wtx.GetHash().GetHex(); @@ -733,12 +747,12 @@ Value sendfrom(const Array& params, bool fHelp) Value sendmany(const Array& params, bool fHelp) { if (fHelp || params.size() < 2 || params.size() > 4) - throw runtime_error( + throw std::runtime_error( "sendmany '{address:amount,...}' [minconf=1] [comment]\n" "amounts are double-precision floating point numbers" + HelpRequiringPassphrase()); - string strAccount = AccountFromValue(params[0]); + std::string strAccount = AccountFromValue(params[0]); Object sendTo = params[1].get_obj(); int nMinDepth = 1; if (params.size() > 2) @@ -749,22 +763,25 @@ Value sendmany(const Array& params, bool fHelp) if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty()) wtx.mapValue["comment"] = params[3].get_str(); - set setAddress; - vector > vecSend; + std::set setAddress; + std::vector > vecSend; int64_t totalAmount = 0; - BOOST_FOREACH(const Pair& s, sendTo) + for (const Pair& s : sendTo) { CBitcoinAddress address(s.name_); if (!address.IsValid()) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid NovaCoin address: ")+s.name_); + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid NovaCoin address: ")+s.name_); - if (setAddress.count(address)) - throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_); - setAddress.insert(address); + if (!address.IsPair()) + { + if (setAddress.count(address)) + throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ")+s.name_); + setAddress.insert(address); + } CScript scriptPubKey; - scriptPubKey.SetDestination(address.Get()); + scriptPubKey.SetAddress(address); int64_t nAmount = AmountFromValue(s.value_); if (nAmount < nMinimumInputValue) @@ -803,29 +820,29 @@ Value addmultisigaddress(const Array& params, bool fHelp) { if (fHelp || params.size() < 2 || params.size() > 3) { - string msg = "addmultisigaddress <'[\"key\",\"key\"]'> [account]\n" + std::string msg = "addmultisigaddress <'[\"key\",\"key\"]'> [account]\n" "Add a nrequired-to-sign multisignature address to the wallet\"\n" "each key is a NovaCoin address or hex-encoded public key\n" "If [account] is specified, assign address to [account]."; - throw runtime_error(msg); + throw std::runtime_error(msg); } int nRequired = params[0].get_int(); const Array& keys = params[1].get_array(); - string strAccount; + std::string strAccount; if (params.size() > 2) strAccount = AccountFromValue(params[2]); // Gather public keys if (nRequired < 1) - throw runtime_error("a multisignature address must require at least one key to redeem"); + throw std::runtime_error("a multisignature address must require at least one key to redeem"); if ((int)keys.size() < nRequired) - throw runtime_error( + throw std::runtime_error( strprintf("not enough keys supplied " "(got %" PRIszu " keys, but need at least %d to redeem)", keys.size(), nRequired)); if (keys.size() > 16) - throw runtime_error("Number of addresses involved in the multisignature address creation > 16\nReduce the number"); - std::vector pubkeys; + throw std::runtime_error("Number of addresses involved in the multisignature address creation > 16\nReduce the number"); + std::vector pubkeys; pubkeys.resize(keys.size()); for (unsigned int i = 0; i < keys.size(); i++) { @@ -837,26 +854,28 @@ Value addmultisigaddress(const Array& params, bool fHelp) { CKeyID keyID; if (!address.GetKeyID(keyID)) - throw runtime_error( + throw std::runtime_error( strprintf("%s does not refer to a key",ks.c_str())); CPubKey vchPubKey; if (!pwalletMain->GetPubKey(keyID, vchPubKey)) - throw runtime_error( + throw std::runtime_error( strprintf("no full public key for address %s",ks.c_str())); - if (!vchPubKey.IsValid() || !pubkeys[i].SetPubKey(vchPubKey)) - throw runtime_error(" Invalid public key: "+ks); + if (!vchPubKey.IsValid()) + throw std::runtime_error(" Invalid public key: "+ks); + pubkeys[i] = vchPubKey; } // Case 2: hex public key else if (IsHex(ks)) { CPubKey vchPubKey(ParseHex(ks)); - if (!vchPubKey.IsValid() || !pubkeys[i].SetPubKey(vchPubKey)) - throw runtime_error(" Invalid public key: "+ks); + if (!vchPubKey.IsValid()) + throw std::runtime_error(" Invalid public key: "+ks); + pubkeys[i] = vchPubKey; } else { - throw runtime_error(" Invalid public key: "+ks); + throw std::runtime_error(" Invalid public key: "+ks); } } @@ -865,38 +884,38 @@ Value addmultisigaddress(const Array& params, bool fHelp) inner.SetMultisig(nRequired, pubkeys); if (inner.size() > MAX_SCRIPT_ELEMENT_SIZE) - throw runtime_error( + throw std::runtime_error( strprintf("redeemScript exceeds size limit: %" PRIszu " > %d", inner.size(), MAX_SCRIPT_ELEMENT_SIZE)); - CScriptID innerID = inner.GetID(); pwalletMain->AddCScript(inner); + CBitcoinAddress address(inner.GetID()); - pwalletMain->SetAddressBookName(innerID, strAccount); - return CBitcoinAddress(innerID).ToString(); + pwalletMain->SetAddressBookName(address, strAccount); + return address.ToString(); } Value addredeemscript(const Array& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) { - string msg = "addredeemscript [account]\n" + std::string msg = "addredeemscript [account]\n" "Add a P2SH address with a specified redeemScript to the wallet.\n" "If [account] is specified, assign address to [account]."; - throw runtime_error(msg); + throw std::runtime_error(msg); } - string strAccount; + std::string strAccount; if (params.size() > 1) strAccount = AccountFromValue(params[1]); // Construct using pay-to-script-hash: - vector innerData = ParseHexV(params[0], "redeemScript"); + auto innerData = ParseHexV(params[0], "redeemScript"); CScript inner(innerData.begin(), innerData.end()); - CScriptID innerID = inner.GetID(); pwalletMain->AddCScript(inner); + CBitcoinAddress address(inner.GetID()); - pwalletMain->SetAddressBookName(innerID, strAccount); - return CBitcoinAddress(innerID).ToString(); + pwalletMain->SetAddressBookName(address, strAccount); + return address.ToString(); } struct tallyitem @@ -923,8 +942,8 @@ Value ListReceived(const Array& params, bool fByAccounts) fIncludeEmpty = params[1].get_bool(); // Tally - map mapTally; - for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + std::map mapTally; + for (auto it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { const CWalletTx& wtx = (*it).second; @@ -935,7 +954,7 @@ Value ListReceived(const Array& params, bool fByAccounts) if (nDepth < nMinDepth) continue; - BOOST_FOREACH(const CTxOut& txout, wtx.vout) + for (const CTxOut& txout : wtx.vout) { CTxDestination address; if (!ExtractDestination(txout.scriptPubKey, address) || !IsMine(*pwalletMain, address)) @@ -943,18 +962,18 @@ Value ListReceived(const Array& params, bool fByAccounts) tallyitem& item = mapTally[address]; item.nAmount += txout.nValue; - item.nConf = min(item.nConf, nDepth); + item.nConf = std::min(item.nConf, nDepth); } } // Reply Array ret; - map mapAccountTally; - BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook) + std::map mapAccountTally; + for (const auto& item : pwalletMain->mapAddressBook) { const CBitcoinAddress& address = item.first; - const string& strAccount = item.second; - map::iterator it = mapTally.find(address); + const std::string& strAccount = item.second; + auto it = mapTally.find(address); if (it == mapTally.end() && !fIncludeEmpty) continue; @@ -970,7 +989,7 @@ Value ListReceived(const Array& params, bool fByAccounts) { tallyitem& item = mapAccountTally[strAccount]; item.nAmount += nAmount; - item.nConf = min(item.nConf, nConf); + item.nConf = std::min(item.nConf, nConf); } else { @@ -985,7 +1004,7 @@ Value ListReceived(const Array& params, bool fByAccounts) if (fByAccounts) { - for (map::iterator it = mapAccountTally.begin(); it != mapAccountTally.end(); ++it) + for (auto it = mapAccountTally.begin(); it != mapAccountTally.end(); ++it) { int64_t nAmount = (*it).second.nAmount; int nConf = (*it).second.nConf; @@ -1003,7 +1022,7 @@ Value ListReceived(const Array& params, bool fByAccounts) Value listreceivedbyaddress(const Array& params, bool fHelp) { if (fHelp || params.size() > 2) - throw runtime_error( + throw std::runtime_error( "listreceivedbyaddress [minconf=1] [includeempty=false]\n" "[minconf] is the minimum number of confirmations before payments are included.\n" "[includeempty] whether to include addresses that haven't received any payments.\n" @@ -1019,7 +1038,7 @@ Value listreceivedbyaddress(const Array& params, bool fHelp) Value listreceivedbyaccount(const Array& params, bool fHelp) { if (fHelp || params.size() > 2) - throw runtime_error( + throw std::runtime_error( "listreceivedbyaccount [minconf=1] [includeempty=false]\n" "[minconf] is the minimum number of confirmations before payments are included.\n" "[includeempty] whether to include accounts that haven't received any payments.\n" @@ -1031,30 +1050,28 @@ Value listreceivedbyaccount(const Array& params, bool fHelp) return ListReceived(params, true); } -static void MaybePushAddress(Object & entry, const CTxDestination &dest) +static void MaybePushAddress(Object & entry, const CBitcoinAddress &dest) { - CBitcoinAddress addr; - if (addr.Set(dest)) - entry.push_back(Pair("address", addr.ToString())); + entry.push_back(Pair("address", dest.ToString())); } -void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, Array& ret, const isminefilter& filter) +void ListTransactions(const CWalletTx& wtx, const std::string& strAccount, int nMinDepth, bool fLong, Array& ret, const isminefilter& filter) { int64_t nGeneratedImmature, nGeneratedMature, nFee; - string strSentAccount; - list > listReceived; - list > listSent; + std::string strSentAccount; + std::list > listReceived; + std::list > listSent; wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount, filter); - bool fAllAccounts = (strAccount == string("*")); + bool fAllAccounts = (strAccount == std::string("*")); bool involvesWatchonly = wtx.IsFromMe(MINE_WATCH_ONLY); // Generated blocks assigned to account "" - if ((nGeneratedMature+nGeneratedImmature) != 0 && (fAllAccounts || strAccount == "")) + if ((nGeneratedMature+nGeneratedImmature) != 0 && (fAllAccounts || strAccount.empty())) { Object entry; - entry.push_back(Pair("account", string(""))); + entry.push_back(Pair("account", std::string(""))); if (nGeneratedImmature) { entry.push_back(Pair("category", wtx.GetDepthInMainChain() ? "immature" : "orphan")); @@ -1073,7 +1090,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe // Sent if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount)) { - BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64_t)& s, listSent) + for (const auto& s : listSent) { Object entry; entry.push_back(Pair("account", strSentAccount)); @@ -1098,9 +1115,9 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe // Received if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth) { - BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64_t)& r, listReceived) + for (const auto& r : listReceived) { - string account; + std::string account; if (pwalletMain->mapAddressBook.count(r.first)) account = pwalletMain->mapAddressBook[r.first]; if (fAllAccounts || (account == strAccount)) @@ -1130,9 +1147,9 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe } } -void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Array& ret) +void AcentryToJSON(const CAccountingEntry& acentry, const std::string& strAccount, Array& ret) { - bool fAllAccounts = (strAccount == string("*")); + bool fAllAccounts = (strAccount == std::string("*")); if (fAllAccounts || acentry.strAccount == strAccount) { @@ -1150,11 +1167,11 @@ void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Ar Value listtransactions(const Array& params, bool fHelp) { if (fHelp || params.size() > 3) - throw runtime_error( + throw std::runtime_error( "listtransactions [account] [count=10] [from=0]\n" "Returns up to [count] most recent transactions skipping the first [from] transactions for account [account]."); - string strAccount = "*"; + std::string strAccount = "*"; if (params.size() > 0) strAccount = params[0].get_str(); int nCount = 10; @@ -1213,7 +1230,7 @@ Value listtransactions(const Array& params, bool fHelp) Value listaccounts(const Array& params, bool fHelp) { if (fHelp || params.size() > 1) - throw runtime_error( + throw std::runtime_error( "listaccounts [minconf=1]\n" "Returns Object that has account names as keys, account balances as values."); @@ -1227,27 +1244,27 @@ Value listaccounts(const Array& params, bool fHelp) includeWatchonly = includeWatchonly | MINE_WATCH_ONLY; - map mapAccountBalances; - BOOST_FOREACH(const PAIRTYPE(CTxDestination, string)& entry, pwalletMain->mapAddressBook) { + std::map mapAccountBalances; + for (const auto& entry : pwalletMain->mapAddressBook) { if (IsMine(*pwalletMain, entry.first)) // This address belongs to me mapAccountBalances[entry.second] = 0; } - for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + for (auto it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { const CWalletTx& wtx = (*it).second; int64_t nGeneratedImmature, nGeneratedMature, nFee; - string strSentAccount; - list > listReceived; - list > listSent; + std::string strSentAccount; + std::list > listReceived; + std::list > listSent; wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount, includeWatchonly); mapAccountBalances[strSentAccount] -= nFee; - BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64_t)& s, listSent) + for (const auto& s : listSent) mapAccountBalances[strSentAccount] -= s.second; if (wtx.GetDepthInMainChain() >= nMinDepth) { mapAccountBalances[""] += nGeneratedMature; - BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64_t)& r, listReceived) + for (const auto& r : listReceived) if (pwalletMain->mapAddressBook.count(r.first)) mapAccountBalances[pwalletMain->mapAddressBook[r.first]] += r.second; else @@ -1255,13 +1272,13 @@ Value listaccounts(const Array& params, bool fHelp) } } - list acentries; + std::list acentries; CWalletDB(pwalletMain->strWalletFile).ListAccountCreditDebit("*", acentries); - BOOST_FOREACH(const CAccountingEntry& entry, acentries) + for (const CAccountingEntry& entry : acentries) mapAccountBalances[entry.strAccount] += entry.nCreditDebit; Object ret; - BOOST_FOREACH(const PAIRTYPE(string, int64_t)& accountBalance, mapAccountBalances) { + for (const auto& accountBalance : mapAccountBalances) { ret.push_back(Pair(accountBalance.first, ValueFromAmount(accountBalance.second))); } return ret; @@ -1270,7 +1287,7 @@ Value listaccounts(const Array& params, bool fHelp) Value listsinceblock(const Array& params, bool fHelp) { if (fHelp) - throw runtime_error( + throw std::runtime_error( "listsinceblock [blockhash] [target-confirmations]\n" "Get all transactions in blocks since block [blockhash], or all transactions if omitted"); @@ -1302,7 +1319,7 @@ Value listsinceblock(const Array& params, bool fHelp) Array transactions; - for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); it++) + for (auto it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); it++) { CWalletTx tx = (*it).second; @@ -1338,7 +1355,7 @@ Value listsinceblock(const Array& params, bool fHelp) Value gettransaction(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) - throw runtime_error( + throw std::runtime_error( "gettransaction \n" "Get detailed information about "); @@ -1385,7 +1402,7 @@ Value gettransaction(const Array& params, bool fHelp) else { entry.push_back(Pair("blockhash", hashBlock.GetHex())); - map::iterator mi = mapBlockIndex.find(hashBlock); + auto mi = mapBlockIndex.find(hashBlock); if (mi != mapBlockIndex.end() && (*mi).second) { CBlockIndex* pindex = (*mi).second; @@ -1407,11 +1424,11 @@ Value gettransaction(const Array& params, bool fHelp) Value backupwallet(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) - throw runtime_error( + throw std::runtime_error( "backupwallet \n" "Safely copies wallet.dat to destination, which can be a directory or a path with filename."); - string strDest = params[0].get_str(); + std::string strDest = params[0].get_str(); if (!BackupWallet(*pwalletMain, strDest)) throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!"); @@ -1422,14 +1439,14 @@ Value backupwallet(const Array& params, bool fHelp) Value keypoolrefill(const Array& params, bool fHelp) { if (fHelp || params.size() > 1) - throw runtime_error( + throw std::runtime_error( "keypoolrefill [new-size]\n" "Fills the keypool.\n" "IMPORTANT: Any previous backups you have made of your wallet file " "should be replaced with the newly generated one." + HelpRequiringPassphrase()); - unsigned int nSize = max(GetArgUInt("-keypool", 100), 0); + unsigned int nSize = std::max(GetArgUInt("-keypool", 100), 0); if (params.size() > 0) { if (params[0].get_int() < 0) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected valid size"); @@ -1449,14 +1466,14 @@ Value keypoolrefill(const Array& params, bool fHelp) Value keypoolreset(const Array& params, bool fHelp) { if (fHelp || params.size() > 1) - throw runtime_error( + throw std::runtime_error( "keypoolreset [new-size]\n" "Resets the keypool.\n" "IMPORTANT: Any previous backups you have made of your wallet file " "should be replaced with the newly generated one." + HelpRequiringPassphrase()); - unsigned int nSize = max(GetArgUInt("-keypool", 100), 0); + unsigned int nSize = std::max(GetArgUInt("-keypool", 100), 0); if (params.size() > 0) { if (params[0].get_int() < 0) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected valid size"); @@ -1495,7 +1512,7 @@ void ThreadCleanWalletPassphrase(void* parg) { nWalletUnlockTime = nMyWakeTime; - do + for ( ; ; ) { if (nWalletUnlockTime==0) break; @@ -1507,7 +1524,7 @@ void ThreadCleanWalletPassphrase(void* parg) Sleep(nToSleep); ENTER_CRITICAL_SECTION(cs_nWalletUnlockTime); - } while(1); + }; if (nWalletUnlockTime) { @@ -1529,7 +1546,7 @@ void ThreadCleanWalletPassphrase(void* parg) Value walletpassphrase(const Array& params, bool fHelp) { if (pwalletMain->IsCrypted() && (fHelp || params.size() < 2 || params.size() > 3)) - throw runtime_error( + throw std::runtime_error( "walletpassphrase [mintonly]\n" "Stores the wallet decryption key in memory for seconds.\n" "mintonly is optional true/false allowing only block minting."); @@ -1553,7 +1570,7 @@ Value walletpassphrase(const Array& params, bool fHelp) throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect."); } else - throw runtime_error( + throw std::runtime_error( "walletpassphrase \n" "Stores the wallet decryption key in memory for seconds."); @@ -1574,7 +1591,7 @@ Value walletpassphrase(const Array& params, bool fHelp) Value walletpassphrasechange(const Array& params, bool fHelp) { if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2)) - throw runtime_error( + throw std::runtime_error( "walletpassphrasechange \n" "Changes the wallet passphrase from to ."); if (fHelp) @@ -1593,7 +1610,7 @@ Value walletpassphrasechange(const Array& params, bool fHelp) strNewWalletPass = params[1].get_str().c_str(); if (strOldWalletPass.length() < 1 || strNewWalletPass.length() < 1) - throw runtime_error( + throw std::runtime_error( "walletpassphrasechange \n" "Changes the wallet passphrase from to ."); @@ -1607,7 +1624,7 @@ Value walletpassphrasechange(const Array& params, bool fHelp) Value walletlock(const Array& params, bool fHelp) { if (pwalletMain->IsCrypted() && (fHelp || params.size() != 0)) - throw runtime_error( + throw std::runtime_error( "walletlock\n" "Removes the wallet encryption key from memory, locking the wallet.\n" "After calling this method, you will need to call walletpassphrase again\n" @@ -1630,7 +1647,7 @@ Value walletlock(const Array& params, bool fHelp) Value encryptwallet(const Array& params, bool fHelp) { if (!pwalletMain->IsCrypted() && (fHelp || params.size() != 1)) - throw runtime_error( + throw std::runtime_error( "encryptwallet \n" "Encrypts the wallet with ."); if (fHelp) @@ -1645,7 +1662,7 @@ Value encryptwallet(const Array& params, bool fHelp) strWalletPass = params[0].get_str().c_str(); if (strWalletPass.length() < 1) - throw runtime_error( + throw std::runtime_error( "encryptwallet \n" "Encrypts the wallet with ."); @@ -1659,7 +1676,7 @@ Value encryptwallet(const Array& params, bool fHelp) return "wallet encrypted; NovaCoin server stopping, restart to run with encrypted wallet. The keypool has been flushed, you need to make a new backup."; } -class DescribeAddressVisitor : public boost::static_visitor +class DescribeAddressVisitor { private: isminetype mine; @@ -1674,7 +1691,7 @@ public: obj.push_back(Pair("isscript", false)); if (mine == MINE_SPENDABLE) { pwalletMain->GetPubKey(keyID, vchPubKey); - obj.push_back(Pair("pubkey", HexStr(vchPubKey.Raw()))); + obj.push_back(Pair("pubkey", HexStr(vchPubKey.begin(), vchPubKey.end()))); obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed())); } return obj; @@ -1693,7 +1710,7 @@ public: obj.push_back(Pair("script", GetTxnOutputType(whichType))); obj.push_back(Pair("hex", HexStr(subscript.begin(), subscript.end()))); Array a; - BOOST_FOREACH(const CTxDestination& addr, addresses) + for (const CTxDestination& addr : addresses) a.push_back(CBitcoinAddress(addr).ToString()); obj.push_back(Pair("addresses", a)); if (whichType == TX_MULTISIG) @@ -1706,7 +1723,7 @@ public: Value validateaddress(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) - throw runtime_error( + throw std::runtime_error( "validateaddress \n" "Return information about ."); @@ -1717,18 +1734,35 @@ Value validateaddress(const Array& params, bool fHelp) ret.push_back(Pair("isvalid", isValid)); if (isValid) { - CTxDestination dest = address.Get(); - string currentAddress = address.ToString(); - ret.push_back(Pair("address", currentAddress)); - isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : MINE_NO; - ret.push_back(Pair("ismine", mine != MINE_NO)); - if (mine != MINE_NO) { - ret.push_back(Pair("watchonly", mine == MINE_WATCH_ONLY)); - Object detail = boost::apply_visitor(DescribeAddressVisitor(mine), dest); - ret.insert(ret.end(), detail.begin(), detail.end()); + if (address.IsPair()) + { + CMalleablePubKey mpk; + mpk.setvch(address.GetData()); + ret.push_back(Pair("ispair", true)); + + CMalleableKeyView view; + bool isMine = pwalletMain->GetMalleableView(mpk, view); + ret.push_back(Pair("ismine", isMine)); + ret.push_back(Pair("PubkeyPair", mpk.ToString())); + + if (isMine) + ret.push_back(Pair("KeyView", view.ToString())); + } + else + { + std::string currentAddress = address.ToString(); + CTxDestination dest = address.Get(); + ret.push_back(Pair("address", currentAddress)); + isminetype mine = pwalletMain ? IsMine(*pwalletMain, address) : MINE_NO; + ret.push_back(Pair("ismine", mine != MINE_NO)); + if (mine != MINE_NO) { + ret.push_back(Pair("watchonly", mine == MINE_WATCH_ONLY)); + Object detail = std::visit(DescribeAddressVisitor(mine), dest); + ret.insert(ret.end(), detail.begin(), detail.end()); + } + if (pwalletMain->mapAddressBook.count(address)) + ret.push_back(Pair("account", pwalletMain->mapAddressBook[address])); } - if (pwalletMain->mapAddressBook.count(dest)) - ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest])); } return ret; } @@ -1737,7 +1771,7 @@ Value validateaddress(const Array& params, bool fHelp) Value reservebalance(const Array& params, bool fHelp) { if (fHelp || params.size() > 2) - throw runtime_error( + throw std::runtime_error( "reservebalance [ [amount]]\n" " is true or false to turn balance reserve on or off.\n" " is a real and rounded to cent.\n" @@ -1750,24 +1784,24 @@ Value reservebalance(const Array& params, bool fHelp) if (fReserve) { if (params.size() == 1) - throw runtime_error("must provide amount to reserve balance.\n"); + throw std::runtime_error("must provide amount to reserve balance.\n"); int64_t nAmount = AmountFromValue(params[1]); nAmount = (nAmount / CENT) * CENT; // round to cent if (nAmount < 0) - throw runtime_error("amount cannot be negative.\n"); - mapArgs["-reservebalance"] = FormatMoney(nAmount).c_str(); + throw std::runtime_error("amount cannot be negative.\n"); + mapArgs["-reservebalance"] = FormatMoney(nAmount); } else { if (params.size() > 1) - throw runtime_error("cannot specify amount to turn off reserve.\n"); + throw std::runtime_error("cannot specify amount to turn off reserve.\n"); mapArgs["-reservebalance"] = "0"; } } Object result; if (mapArgs.count("-reservebalance") && !ParseMoney(mapArgs["-reservebalance"], nReserveBalance)) - throw runtime_error("invalid reserve balance amount\n"); + throw std::runtime_error("invalid reserve balance amount\n"); result.push_back(Pair("reserve", (nReserveBalance > 0))); result.push_back(Pair("amount", ValueFromAmount(nReserveBalance))); return result; @@ -1778,7 +1812,7 @@ Value reservebalance(const Array& params, bool fHelp) Value checkwallet(const Array& params, bool fHelp) { if (fHelp || params.size() > 0) - throw runtime_error( + throw std::runtime_error( "checkwallet\n" "Check wallet for integrity.\n"); @@ -1801,7 +1835,7 @@ Value checkwallet(const Array& params, bool fHelp) Value repairwallet(const Array& params, bool fHelp) { if (fHelp || params.size() > 0) - throw runtime_error( + throw std::runtime_error( "repairwallet\n" "Repair wallet if checkwallet reports any problem.\n"); @@ -1823,25 +1857,48 @@ Value repairwallet(const Array& params, bool fHelp) Value resendtx(const Array& params, bool fHelp) { if (fHelp || params.size() > 1) - throw runtime_error( + throw std::runtime_error( "resendtx\n" "Re-send unconfirmed transactions.\n" ); - ResendWalletTransactions(); + ResendWalletTransactions(true); return Value::null; } +Value resendwallettransactions(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw std::runtime_error( + "resendwallettransactions\n" + "Immediately re-broadcast unconfirmed wallet transactions to all peers.\n" + "Intended only for testing; the wallet code periodically re-broadcasts\n" + "automatically.\n" + "Returns array of transaction ids that were re-broadcast.\n" + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + std::vector txids = pwalletMain->ResendWalletTransactionsBefore(GetTime()); + Array result; + for (const uint256& txid : txids) + { + result.push_back(txid.ToString()); + } + return result; +} + + // Make a public-private key pair Value makekeypair(const Array& params, bool fHelp) { if (fHelp || params.size() > 0) - throw runtime_error( + throw std::runtime_error( "makekeypair\n" "Make a public/private key pair.\n"); - string strPrefix = ""; + std::string strPrefix = ""; if (params.size() > 0) strPrefix = params[0].get_str(); @@ -1854,25 +1911,40 @@ Value makekeypair(const Array& params, bool fHelp) bool fCompressed; CSecret vchSecret = key.GetSecret(fCompressed); + CPubKey vchPubKey = key.GetPubKey(); result.push_back(Pair("Secret", HexStr(vchSecret.begin(), vchSecret.end()))); - result.push_back(Pair("PublicKey", HexStr(key.GetPubKey().Raw()))); + result.push_back(Pair("PublicKey", HexStr(vchPubKey.begin(), vchPubKey.end()))); return result; } Value newmalleablekey(const Array& params, bool fHelp) { - if (fHelp || params.size() > 0) - throw runtime_error( + if (fHelp || params.size() > 1) + throw std::runtime_error( "newmalleablekey\n" "Make a malleable public/private key pair.\n"); - CMalleableKey malleableKey; - malleableKey.MakeNewKeys(); - CMalleablePubKey malleablePubKey = malleableKey.GetMalleablePubKey(); + // Parse the account first so we don't generate a key if there's an error + std::string strAccount; + if (params.size() > 0) + strAccount = AccountFromValue(params[0]); + + CMalleableKeyView keyView = pwalletMain->GenerateNewMalleableKey(); + + CMalleableKey mKey; + if (!pwalletMain->GetMalleableKey(keyView, mKey)) + throw std::runtime_error("Unable to generate new malleable key"); + + CMalleablePubKey mPubKey = mKey.GetMalleablePubKey(); + CBitcoinAddress address(mPubKey); + + pwalletMain->SetAddressBookName(address, strAccount); Object result; - result.push_back(Pair("PrivatePair", malleableKey.ToString())); - result.push_back(Pair("PublicPair", malleablePubKey.ToString())); + result.push_back(Pair("PublicPair", mPubKey.ToString())); + result.push_back(Pair("PublicBytes", HexStr(mPubKey.Raw()))); + result.push_back(Pair("Address", address.ToString())); + result.push_back(Pair("KeyView", keyView.ToString())); return result; } @@ -1880,7 +1952,7 @@ Value newmalleablekey(const Array& params, bool fHelp) Value adjustmalleablekey(const Array& params, bool fHelp) { if (fHelp || params.size() != 3) - throw runtime_error( + throw std::runtime_error( "adjustmalleablekey \n" "Calculate new private key using provided malleable key, public key and R data.\n"); @@ -1889,10 +1961,11 @@ Value adjustmalleablekey(const Array& params, bool fHelp) CKey privKeyVariant; CPubKey vchPubKeyVariant = CPubKey(ParseHex(params[1].get_str())); - CPubKey vchR = CPubKey(ParseHex(params[2].get_str())); - if (!malleableKey.CheckKeyVariant(vchR,vchPubKeyVariant, privKeyVariant)) { - throw runtime_error("Unable to calculate the private key"); + CPubKey R(ParseHex(params[2].get_str())); + + if (!malleableKey.CheckKeyVariant(R,vchPubKeyVariant, privKeyVariant)) { + throw std::runtime_error("Unable to calculate the private key"); } Object result; @@ -1907,20 +1980,63 @@ Value adjustmalleablekey(const Array& params, bool fHelp) Value adjustmalleablepubkey(const Array& params, bool fHelp) { if (fHelp || params.size() > 2 || params.size() == 0) - throw runtime_error( - "adjustmalleablepubkey \n" - "Calculate new public key using provided malleable public key data.\n"); + throw std::runtime_error( + "adjustmalleablepubkey \n" + "Calculate new public key using provided data.\n"); + std::string strData = params[0].get_str(); CMalleablePubKey malleablePubKey; - malleablePubKey.SetString(params[0].get_str()); + + do + { + CBitcoinAddress addr(strData); + if (addr.IsValid() && addr.IsPair()) + { + // Initialize malleable pubkey with address data + malleablePubKey = CMalleablePubKey(addr.GetData()); + break; + } + CMalleableKeyView viewTmp(strData); + if (viewTmp.IsValid()) + { + // Shazaam, we have a valid key view here. + malleablePubKey = viewTmp.GetMalleablePubKey(); + break; + } + if (malleablePubKey.SetString(strData)) + break; // A valid public key pair + + throw std::runtime_error("Though your data seems a valid Base58 string, we were unable to recognize it."); + } + while(false); CPubKey R, vchPubKeyVariant; malleablePubKey.GetVariant(R, vchPubKeyVariant); Object result; - result.push_back(Pair("R", HexStr(R.Raw()))); - result.push_back(Pair("PubkeyVariant", HexStr(vchPubKeyVariant.Raw()))); + result.push_back(Pair("R", HexStr(R.begin(), R.end()))); + result.push_back(Pair("PubkeyVariant", HexStr(vchPubKeyVariant.begin(), vchPubKeyVariant.end()))); result.push_back(Pair("KeyVariantID", CBitcoinAddress(vchPubKeyVariant.GetID()).ToString())); return result; } + +Value listmalleableviews(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw std::runtime_error( + "listmalleableviews\n" + "Get list of views for generated malleable keys.\n"); + + std::list keyViewList; + pwalletMain->ListMalleableViews(keyViewList); + + Array result; + for (const CMalleableKeyView &keyView : keyViewList) + { + result.push_back(keyView.ToString()); + } + + return result; +} +