diff options
Diffstat (limited to 'src/wallet')
-rw-r--r-- | src/wallet/db.cpp | 10 | ||||
-rw-r--r-- | src/wallet/db.h | 10 | ||||
-rw-r--r-- | src/wallet/rpcdump.cpp | 7 | ||||
-rw-r--r-- | src/wallet/rpcwallet.cpp | 16 | ||||
-rw-r--r-- | src/wallet/rpcwallet.h | 2 | ||||
-rw-r--r-- | src/wallet/test/rpc_wallet_tests.cpp | 229 | ||||
-rw-r--r-- | src/wallet/test/wallet_test_fixture.cpp | 4 | ||||
-rw-r--r-- | src/wallet/test/wallet_tests.cpp | 6 | ||||
-rw-r--r-- | src/wallet/wallet.cpp | 64 | ||||
-rw-r--r-- | src/wallet/wallet.h | 18 | ||||
-rw-r--r-- | src/wallet/walletdb.cpp | 31 |
11 files changed, 93 insertions, 304 deletions
diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index c906785e9e..a809c9ad64 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -43,7 +43,7 @@ void CDBEnv::EnvShutdown() if (ret != 0) LogPrintf("CDBEnv::EnvShutdown: Error %d shutting down database environment: %s\n", ret, DbEnv::strerror(ret)); if (!fMockDb) - DbEnv(0).remove(strPath.c_str(), 0); + DbEnv((u_int32_t)0).remove(strPath.c_str(), 0); } void CDBEnv::Reset() @@ -284,7 +284,7 @@ CDB::CDB(const std::string& strFilename, const char* pszMode, bool fFlushOnClose pdb = NULL; --bitdb.mapFileUseCount[strFile]; strFile = ""; - throw runtime_error(strprintf("CDB: Error %d, can't open database %s", ret, strFile)); + throw runtime_error(strprintf("CDB: Error %d, can't open database %s", ret, strFilename)); } if (fCreate && !Exists(string("version"))) { @@ -387,11 +387,11 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip) while (fSuccess) { CDataStream ssKey(SER_DISK, CLIENT_VERSION); CDataStream ssValue(SER_DISK, CLIENT_VERSION); - int ret = db.ReadAtCursor(pcursor, ssKey, ssValue, DB_NEXT); - if (ret == DB_NOTFOUND) { + int ret1 = db.ReadAtCursor(pcursor, ssKey, ssValue); + if (ret1 == DB_NOTFOUND) { pcursor->close(); break; - } else if (ret != 0) { + } else if (ret1 != 0) { pcursor->close(); fSuccess = false; break; diff --git a/src/wallet/db.h b/src/wallet/db.h index 01b8c71a04..a0f673ecfc 100644 --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -228,19 +228,17 @@ protected: return pcursor; } - int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue, unsigned int fFlags = DB_NEXT) + int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue, bool setRange = false) { // Read at cursor Dbt datKey; - if (fFlags == DB_SET || fFlags == DB_SET_RANGE || fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE) { + unsigned int fFlags = DB_NEXT; + if (setRange) { datKey.set_data(&ssKey[0]); datKey.set_size(ssKey.size()); + fFlags = DB_SET_RANGE; } Dbt datValue; - if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE) { - datValue.set_data(&ssValue[0]); - datValue.set_size(ssValue.size()); - } datKey.set_flags(DB_DBT_MALLOC); datValue.set_flags(DB_DBT_MALLOC); int ret = pcursor->get(&datKey, &datValue, fFlags); diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index fe8b53ceb0..42ebdb9b9b 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -257,14 +257,13 @@ UniValue importprunedfunds(const UniValue& params, bool fHelp) if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - if (fHelp || params.size() < 2 || params.size() > 3) + if (fHelp || 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" "\nArguments:\n" "1. \"rawtransaction\" (string, required) A raw transaction in hex funding an already-existing address in wallet\n" "2. \"txoutproof\" (string, required) The hex output from gettxoutproof that contains the transaction\n" - "3. \"label\" (string, optional) An optional label\n" ); CTransaction tx; @@ -277,10 +276,6 @@ UniValue importprunedfunds(const UniValue& params, bool fHelp) CMerkleBlock merkleBlock; ssMB >> merkleBlock; - string strLabel = ""; - if (params.size() == 3) - strLabel = params[2].get_str(); - //Search partial merkle tree in proof for our transaction and index in valid block vector<uint256> vMatch; vector<unsigned int> vIndex; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index aa0a9374c1..0ba6706baf 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1176,10 +1176,10 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts) if (fByAccounts) { - tallyitem& item = mapAccountTally[strAccount]; - item.nAmount += nAmount; - item.nConf = min(item.nConf, nConf); - item.fIsWatchonly = fIsWatchonly; + tallyitem& _item = mapAccountTally[strAccount]; + _item.nAmount += nAmount; + _item.nConf = min(_item.nConf, nConf); + _item.fIsWatchonly = fIsWatchonly; } else { @@ -1195,9 +1195,9 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts) UniValue transactions(UniValue::VARR); if (it != mapTally.end()) { - BOOST_FOREACH(const uint256& item, (*it).second.txids) + BOOST_FOREACH(const uint256& _item, (*it).second.txids) { - transactions.push_back(item.GetHex()); + transactions.push_back(_item.GetHex()); } } obj.push_back(Pair("txids", transactions)); @@ -2617,8 +2617,8 @@ static const CRPCCommand commands[] = { "wallet", "removeprunedfunds", &removeprunedfunds, true }, }; -void RegisterWalletRPCCommands(CRPCTable &tableRPC) +void RegisterWalletRPCCommands(CRPCTable &t) { for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) - tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]); + t.appendCommand(commands[vcidx].name, &commands[vcidx]); } diff --git a/src/wallet/rpcwallet.h b/src/wallet/rpcwallet.h index a5de7e2de1..3a68ccf1b2 100644 --- a/src/wallet/rpcwallet.h +++ b/src/wallet/rpcwallet.h @@ -7,6 +7,6 @@ class CRPCTable; -void RegisterWalletRPCCommands(CRPCTable &tableRPC); +void RegisterWalletRPCCommands(CRPCTable &t); #endif //BITCOIN_WALLET_RPCWALLET_H diff --git a/src/wallet/test/rpc_wallet_tests.cpp b/src/wallet/test/rpc_wallet_tests.cpp deleted file mode 100644 index 4e7d177f51..0000000000 --- a/src/wallet/test/rpc_wallet_tests.cpp +++ /dev/null @@ -1,229 +0,0 @@ -// Copyright (c) 2013-2015 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "rpc/server.h" -#include "rpc/client.h" - -#include "base58.h" -#include "main.h" -#include "wallet/wallet.h" - -#include "wallet/test/wallet_test_fixture.h" - -#include <boost/algorithm/string.hpp> -#include <boost/test/unit_test.hpp> - -#include <univalue.h> - -using namespace std; - -extern UniValue createArgs(int nRequired, const char* address1 = NULL, const char* address2 = NULL); -extern UniValue CallRPC(string args); - -extern CWallet* pwalletMain; - -BOOST_FIXTURE_TEST_SUITE(rpc_wallet_tests, WalletTestingSetup) - -BOOST_AUTO_TEST_CASE(rpc_addmultisig) -{ - rpcfn_type addmultisig = tableRPC["addmultisigaddress"]->actor; - - // old, 65-byte-long: - const char address1Hex[] = "0434e3e09f49ea168c5bbf53f877ff4206923858aab7c7e1df25bc263978107c95e35065a27ef6f1b27222db0ec97e0e895eaca603d3ee0d4c060ce3d8a00286c8"; - // new, compressed: - const char address2Hex[] = "0388c2037017c62240b6b72ac1a2a5f94da790596ebd06177c8572752922165cb4"; - - UniValue v; - CBitcoinAddress address; - BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(1, address1Hex), false)); - address.SetString(v.get_str()); - BOOST_CHECK(address.IsValid() && address.IsScript()); - - BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(1, address1Hex, address2Hex), false)); - address.SetString(v.get_str()); - BOOST_CHECK(address.IsValid() && address.IsScript()); - - BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(2, address1Hex, address2Hex), false)); - address.SetString(v.get_str()); - BOOST_CHECK(address.IsValid() && address.IsScript()); - - BOOST_CHECK_THROW(addmultisig(createArgs(0), false), runtime_error); - BOOST_CHECK_THROW(addmultisig(createArgs(1), false), runtime_error); - BOOST_CHECK_THROW(addmultisig(createArgs(2, address1Hex), false), runtime_error); - - BOOST_CHECK_THROW(addmultisig(createArgs(1, ""), false), runtime_error); - BOOST_CHECK_THROW(addmultisig(createArgs(1, "NotAValidPubkey"), false), runtime_error); - - string short1(address1Hex, address1Hex + sizeof(address1Hex) - 2); // last byte missing - BOOST_CHECK_THROW(addmultisig(createArgs(2, short1.c_str()), false), runtime_error); - - string short2(address1Hex + 1, address1Hex + sizeof(address1Hex)); // first byte missing - BOOST_CHECK_THROW(addmultisig(createArgs(2, short2.c_str()), false), runtime_error); -} - -BOOST_AUTO_TEST_CASE(rpc_wallet) -{ - // Test RPC calls for various wallet statistics - UniValue r; - CPubKey demoPubkey; - CBitcoinAddress demoAddress; - UniValue retValue; - string strAccount = "walletDemoAccount"; - CBitcoinAddress setaccountDemoAddress; - { - LOCK(pwalletMain->cs_wallet); - - demoPubkey = pwalletMain->GenerateNewKey(); - demoAddress = CBitcoinAddress(CTxDestination(demoPubkey.GetID())); - string strPurpose = "receive"; - BOOST_CHECK_NO_THROW({ /*Initialize Wallet with an account */ - CWalletDB walletdb(pwalletMain->strWalletFile); - CAccount account; - account.vchPubKey = demoPubkey; - pwalletMain->SetAddressBook(account.vchPubKey.GetID(), strAccount, strPurpose); - walletdb.WriteAccount(strAccount, account); - }); - - CPubKey setaccountDemoPubkey = pwalletMain->GenerateNewKey(); - setaccountDemoAddress = CBitcoinAddress(CTxDestination(setaccountDemoPubkey.GetID())); - } - /********************************* - * setaccount - *********************************/ - BOOST_CHECK_NO_THROW(CallRPC("setaccount " + setaccountDemoAddress.ToString() + " nullaccount")); - /* 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ is not owned by the test wallet. */ - BOOST_CHECK_THROW(CallRPC("setaccount 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ nullaccount"), runtime_error); - BOOST_CHECK_THROW(CallRPC("setaccount"), runtime_error); - /* 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X (33 chars) is an illegal address (should be 34 chars) */ - BOOST_CHECK_THROW(CallRPC("setaccount 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X nullaccount"), runtime_error); - - - /********************************* - * getbalance - *********************************/ - BOOST_CHECK_NO_THROW(CallRPC("getbalance")); - BOOST_CHECK_NO_THROW(CallRPC("getbalance " + demoAddress.ToString())); - - /********************************* - * listunspent - *********************************/ - BOOST_CHECK_NO_THROW(CallRPC("listunspent")); - BOOST_CHECK_THROW(CallRPC("listunspent string"), runtime_error); - BOOST_CHECK_THROW(CallRPC("listunspent 0 string"), runtime_error); - BOOST_CHECK_THROW(CallRPC("listunspent 0 1 not_array"), runtime_error); - BOOST_CHECK_THROW(CallRPC("listunspent 0 1 [] extra"), runtime_error); - BOOST_CHECK_NO_THROW(r = CallRPC("listunspent 0 1 []")); - BOOST_CHECK(r.get_array().empty()); - - /********************************* - * listreceivedbyaddress - *********************************/ - BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaddress")); - BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaddress 0")); - BOOST_CHECK_THROW(CallRPC("listreceivedbyaddress not_int"), runtime_error); - BOOST_CHECK_THROW(CallRPC("listreceivedbyaddress 0 not_bool"), runtime_error); - BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaddress 0 true")); - BOOST_CHECK_THROW(CallRPC("listreceivedbyaddress 0 true extra"), runtime_error); - - /********************************* - * listreceivedbyaccount - *********************************/ - BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaccount")); - BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaccount 0")); - BOOST_CHECK_THROW(CallRPC("listreceivedbyaccount not_int"), runtime_error); - BOOST_CHECK_THROW(CallRPC("listreceivedbyaccount 0 not_bool"), runtime_error); - BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaccount 0 true")); - BOOST_CHECK_THROW(CallRPC("listreceivedbyaccount 0 true extra"), runtime_error); - - /********************************* - * listsinceblock - *********************************/ - BOOST_CHECK_NO_THROW(CallRPC("listsinceblock")); - - /********************************* - * listtransactions - *********************************/ - BOOST_CHECK_NO_THROW(CallRPC("listtransactions")); - BOOST_CHECK_NO_THROW(CallRPC("listtransactions " + demoAddress.ToString())); - BOOST_CHECK_NO_THROW(CallRPC("listtransactions " + demoAddress.ToString() + " 20")); - BOOST_CHECK_NO_THROW(CallRPC("listtransactions " + demoAddress.ToString() + " 20 0")); - BOOST_CHECK_THROW(CallRPC("listtransactions " + demoAddress.ToString() + " not_int"), runtime_error); - - /********************************* - * listlockunspent - *********************************/ - BOOST_CHECK_NO_THROW(CallRPC("listlockunspent")); - - /********************************* - * listaccounts - *********************************/ - BOOST_CHECK_NO_THROW(CallRPC("listaccounts")); - - /********************************* - * listaddressgroupings - *********************************/ - BOOST_CHECK_NO_THROW(CallRPC("listaddressgroupings")); - - /********************************* - * getrawchangeaddress - *********************************/ - BOOST_CHECK_NO_THROW(CallRPC("getrawchangeaddress")); - - /********************************* - * getnewaddress - *********************************/ - BOOST_CHECK_NO_THROW(CallRPC("getnewaddress")); - BOOST_CHECK_NO_THROW(CallRPC("getnewaddress getnewaddress_demoaccount")); - - /********************************* - * getaccountaddress - *********************************/ - BOOST_CHECK_NO_THROW(CallRPC("getaccountaddress \"\"")); - BOOST_CHECK_NO_THROW(CallRPC("getaccountaddress accountThatDoesntExists")); // Should generate a new account - BOOST_CHECK_NO_THROW(retValue = CallRPC("getaccountaddress " + strAccount)); - BOOST_CHECK(CBitcoinAddress(retValue.get_str()).Get() == demoAddress.Get()); - - /********************************* - * getaccount - *********************************/ - BOOST_CHECK_THROW(CallRPC("getaccount"), runtime_error); - BOOST_CHECK_NO_THROW(CallRPC("getaccount " + demoAddress.ToString())); - - /********************************* - * signmessage + verifymessage - *********************************/ - BOOST_CHECK_NO_THROW(retValue = CallRPC("signmessage " + demoAddress.ToString() + " mymessage")); - BOOST_CHECK_THROW(CallRPC("signmessage"), runtime_error); - /* Should throw error because this address is not loaded in the wallet */ - BOOST_CHECK_THROW(CallRPC("signmessage 1QFqqMUD55ZV3PJEJZtaKCsQmjLT6JkjvJ mymessage"), runtime_error); - - /* missing arguments */ - BOOST_CHECK_THROW(CallRPC("verifymessage " + demoAddress.ToString()), runtime_error); - BOOST_CHECK_THROW(CallRPC("verifymessage " + demoAddress.ToString() + " " + retValue.get_str()), runtime_error); - /* Illegal address */ - BOOST_CHECK_THROW(CallRPC("verifymessage 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X " + retValue.get_str() + " mymessage"), runtime_error); - /* wrong address */ - BOOST_CHECK(CallRPC("verifymessage 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ " + retValue.get_str() + " mymessage").get_bool() == false); - /* Correct address and signature but wrong message */ - BOOST_CHECK(CallRPC("verifymessage " + demoAddress.ToString() + " " + retValue.get_str() + " wrongmessage").get_bool() == false); - /* Correct address, message and signature*/ - BOOST_CHECK(CallRPC("verifymessage " + demoAddress.ToString() + " " + retValue.get_str() + " mymessage").get_bool() == true); - - /********************************* - * getaddressesbyaccount - *********************************/ - BOOST_CHECK_THROW(CallRPC("getaddressesbyaccount"), runtime_error); - BOOST_CHECK_NO_THROW(retValue = CallRPC("getaddressesbyaccount " + strAccount)); - UniValue arr = retValue.get_array(); - BOOST_CHECK(arr.size() > 0); - BOOST_CHECK(CBitcoinAddress(arr[0].get_str()).Get() == demoAddress.Get()); - - /********************************* - * fundrawtransaction - *********************************/ - BOOST_CHECK_THROW(CallRPC("fundrawtransaction 28z"), runtime_error); - BOOST_CHECK_THROW(CallRPC("fundrawtransaction 01000000000180969800000000001976a91450ce0a4b0ee0ddeb633da85199728b940ac3fe9488ac00000000"), runtime_error); -} - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/wallet/test/wallet_test_fixture.cpp b/src/wallet/test/wallet_test_fixture.cpp index 9036ee26d8..a76db37617 100644 --- a/src/wallet/test/wallet_test_fixture.cpp +++ b/src/wallet/test/wallet_test_fixture.cpp @@ -1,3 +1,7 @@ +// Copyright (c) 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. + #include "wallet/test/wallet_test_fixture.h" #include "rpc/server.h" diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index c6c5058984..acf980c784 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -217,7 +217,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // run the 'mtgox' test (see http://blockexplorer.com/tx/29a3efd3ef04f9153d47a990bd7b048a4b2d213daaa5fb8ed670fb85f13bdbcf) // they tried to consolidate 10 50k coins into one 500k coin, and ended up with 50k in change empty_wallet(); - for (int i = 0; i < 20; i++) + for (int j = 0; j < 20; j++) add_coin(50000 * COIN); BOOST_CHECK( wallet.SelectCoinsMinConf(500000 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet)); @@ -296,7 +296,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) BOOST_CHECK(!equal_sets(setCoinsRet, setCoinsRet2)); int fails = 0; - for (int i = 0; i < RANDOM_REPEATS; i++) + for (int j = 0; j < RANDOM_REPEATS; j++) { // selecting 1 from 100 identical coins depends on the shuffle; this test will fail 1% of the time // run the test RANDOM_REPEATS times and only complain if all of them fail @@ -317,7 +317,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) add_coin(25 * CENT); fails = 0; - for (int i = 0; i < RANDOM_REPEATS; i++) + for (int j = 0; j < RANDOM_REPEATS; j++) { // selecting 1 from 100 identical coins depends on the shuffle; this test will fail 1% of the time // run the test RANDOM_REPEATS times and only complain if all of them fail diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 888aa029a3..10aca2e499 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -98,7 +98,7 @@ CPubKey CWallet::GenerateNewKey() CKeyMetadata metadata(nCreationTime); // use HD key derivation if HD was enabled during wallet creation - if (!hdChain.masterKeyID.IsNull()) { + if (IsHDEnabled()) { // for now we use a fixed keypath scheme of m/0'/0'/k CKey key; //master key seed (256bit) CExtKey masterKey; //hd master key @@ -108,7 +108,7 @@ CPubKey CWallet::GenerateNewKey() // try to get the master key if (!GetKey(hdChain.masterKeyID, key)) - throw std::runtime_error("CWallet::GenerateNewKey(): Master key not found"); + throw std::runtime_error(std::string(__func__) + ": Master key not found"); masterKey.SetMaster(key.begin(), key.size()); @@ -135,7 +135,7 @@ CPubKey CWallet::GenerateNewKey() // update the chain model in the database if (!CWalletDB(strWalletFile).WriteHDChain(hdChain)) - throw std::runtime_error("CWallet::GenerateNewKey(): Writing HD chain model failed"); + throw std::runtime_error(std::string(__func__) + ": Writing HD chain model failed"); } else { secret.MakeNewKey(fCompressed); } @@ -152,7 +152,7 @@ CPubKey CWallet::GenerateNewKey() nTimeFirstKey = nCreationTime; if (!AddKeyPubKey(secret, pubkey)) - throw std::runtime_error("CWallet::GenerateNewKey(): AddKey failed"); + throw std::runtime_error(std::string(__func__) + ": AddKey failed"); return pubkey; } @@ -628,7 +628,7 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) Unlock(strWalletPassphrase); // if we are using HD, replace the HD master key (seed) with a new one - if (!hdChain.masterKeyID.IsNull()) { + if (IsHDEnabled()) { CKey key; CPubKey masterPubKey = GenerateNewHDMasterKey(); if (!SetHDMasterKey(masterPubKey)) @@ -1094,7 +1094,7 @@ isminetype CWallet::IsMine(const CTxOut& txout) const CAmount CWallet::GetCredit(const CTxOut& txout, const isminefilter& filter) const { if (!MoneyRange(txout.nValue)) - throw std::runtime_error("CWallet::GetCredit(): value out of range"); + throw std::runtime_error(std::string(__func__) + ": value out of range"); return ((IsMine(txout) & filter) ? txout.nValue : 0); } @@ -1123,7 +1123,7 @@ bool CWallet::IsChange(const CTxOut& txout) const CAmount CWallet::GetChange(const CTxOut& txout) const { if (!MoneyRange(txout.nValue)) - throw std::runtime_error("CWallet::GetChange(): value out of range"); + throw std::runtime_error(std::string(__func__) + ": value out of range"); return (IsChange(txout) ? txout.nValue : 0); } @@ -1147,7 +1147,7 @@ CAmount CWallet::GetDebit(const CTransaction& tx, const isminefilter& filter) co { nDebit += GetDebit(txin, filter); if (!MoneyRange(nDebit)) - throw std::runtime_error("CWallet::GetDebit(): value out of range"); + throw std::runtime_error(std::string(__func__) + ": value out of range"); } return nDebit; } @@ -1159,7 +1159,7 @@ CAmount CWallet::GetCredit(const CTransaction& tx, const isminefilter& filter) c { nCredit += GetCredit(txout, filter); if (!MoneyRange(nCredit)) - throw std::runtime_error("CWallet::GetCredit(): value out of range"); + throw std::runtime_error(std::string(__func__) + ": value out of range"); } return nCredit; } @@ -1171,7 +1171,7 @@ CAmount CWallet::GetChange(const CTransaction& tx) const { nChange += GetChange(txout); if (!MoneyRange(nChange)) - throw std::runtime_error("CWallet::GetChange(): value out of range"); + throw std::runtime_error(std::string(__func__) + ": value out of range"); } return nChange; } @@ -1200,7 +1200,7 @@ CPubKey CWallet::GenerateNewHDMasterKey() // write the key&metadata to the database if (!AddKeyPubKey(key, pubkey)) - throw std::runtime_error("CWallet::GenerateNewKey(): AddKey failed"); + throw std::runtime_error(std::string(__func__) + ": AddKeyPubKey failed"); } return pubkey; @@ -1227,12 +1227,17 @@ bool CWallet::SetHDChain(const CHDChain& chain, bool memonly) { LOCK(cs_wallet); if (!memonly && !CWalletDB(strWalletFile).WriteHDChain(chain)) - throw runtime_error("AddHDChain(): writing chain failed"); + throw runtime_error(std::string(__func__) + ": writing chain failed"); hdChain = chain; return true; } +bool CWallet::IsHDEnabled() +{ + return !hdChain.masterKeyID.IsNull(); +} + int64_t CWalletTx::GetTxTime() const { int64_t n = nTimeSmart; @@ -2456,7 +2461,6 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) AddToWallet(wtxNew); // Notify that old coins are spent - set<CWalletTx*> setCoins; BOOST_FOREACH(const CTxIn& txin, wtxNew.vin) { CWalletTx &coin = mapWallet[txin.prevout.hash]; @@ -2707,7 +2711,7 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize) if (!setKeyPool.empty()) nEnd = *(--setKeyPool.end()) + 1; if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey()))) - throw runtime_error("TopUpKeyPool(): writing generated key failed"); + throw runtime_error(std::string(__func__) + ": writing generated key failed"); setKeyPool.insert(nEnd); LogPrintf("keypool added key %d, size=%u\n", nEnd, setKeyPool.size()); } @@ -2734,9 +2738,9 @@ void CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool) nIndex = *(setKeyPool.begin()); setKeyPool.erase(setKeyPool.begin()); if (!walletdb.ReadPool(nIndex, keypool)) - throw runtime_error("ReserveKeyFromKeyPool(): read failed"); + throw runtime_error(std::string(__func__) + ": read failed"); if (!HaveKey(keypool.vchPubKey.GetID())) - throw runtime_error("ReserveKeyFromKeyPool(): unknown key in key pool"); + throw runtime_error(std::string(__func__) + ": unknown key in key pool"); assert(keypool.vchPubKey.IsValid()); LogPrintf("keypool reserve %d\n", nIndex); } @@ -2795,7 +2799,7 @@ int64_t CWallet::GetOldestKeyPoolTime() CWalletDB walletdb(strWalletFile); int64_t nIndex = *(setKeyPool.begin()); if (!walletdb.ReadPool(nIndex, keypool)) - throw runtime_error("GetOldestKeyPoolTime(): read oldest key in keypool failed"); + throw runtime_error(std::string(__func__) + ": read oldest key in keypool failed"); assert(keypool.vchPubKey.IsValid()); return keypool.nTime; } @@ -3022,11 +3026,11 @@ void CWallet::GetAllReserveKeys(set<CKeyID>& setAddress) const { CKeyPool keypool; if (!walletdb.ReadPool(id, keypool)) - throw runtime_error("GetAllReserveKeyHashes(): read failed"); + throw runtime_error(std::string(__func__) + ": read failed"); assert(keypool.vchPubKey.IsValid()); CKeyID keyID = keypool.vchPubKey.GetID(); if (!HaveKey(keyID)) - throw runtime_error("GetAllReserveKeyHashes(): unknown key in key pool"); + throw runtime_error(std::string(__func__) + ": unknown key in key pool"); setAddress.insert(keyID); } } @@ -3133,7 +3137,7 @@ void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const { mapKeyBirth[it->first] = it->second.nCreateTime; // map in which we'll infer heights of other keys - CBlockIndex *pindexMax = chainActive[std::max(0, chainActive.Height() - 144)]; // the tip can be reorganised; use a 144-block safety margin + CBlockIndex *pindexMax = chainActive[std::max(0, chainActive.Height() - 144)]; // the tip can be reorganized; use a 144-block safety margin std::map<CKeyID, CBlockIndex*> mapKeyFirstBlock; std::set<CKeyID> setKeys; GetKeys(setKeys); @@ -3322,12 +3326,11 @@ bool CWallet::InitLoadWallet() if (fFirstRun) { // Create new keyUser and set as default key - if (GetBoolArg("-usehd", DEFAULT_USE_HD_WALLET) && walletInstance->hdChain.masterKeyID.IsNull()) { + if (GetBoolArg("-usehd", DEFAULT_USE_HD_WALLET) && !walletInstance->IsHDEnabled()) { // generate a new master key - CKey key; CPubKey masterPubKey = walletInstance->GenerateNewHDMasterKey(); if (!walletInstance->SetHDMasterKey(masterPubKey)) - throw std::runtime_error("CWallet::GenerateNewKey(): Storing master key failed"); + throw std::runtime_error(std::string(__func__) + ": Storing master key failed"); } CPubKey newDefaultKey; if (walletInstance->GetKeyFromPool(newDefaultKey)) { @@ -3340,9 +3343,9 @@ bool CWallet::InitLoadWallet() } else if (mapArgs.count("-usehd")) { bool useHD = GetBoolArg("-usehd", DEFAULT_USE_HD_WALLET); - if (!walletInstance->hdChain.masterKeyID.IsNull() && !useHD) + if (walletInstance->IsHDEnabled() && !useHD) return InitError(strprintf(_("Error loading %s: You can't disable HD on a already existing HD wallet"), walletFile)); - if (walletInstance->hdChain.masterKeyID.IsNull() && useHD) + if (!walletInstance->IsHDEnabled() && useHD) return InitError(strprintf(_("Error loading %s: You can't enable HD on a already existing non-HD wallet"), walletFile)); } @@ -3412,7 +3415,17 @@ bool CWallet::InitLoadWallet() } walletInstance->SetBroadcastTransactions(GetBoolArg("-walletbroadcast", DEFAULT_WALLETBROADCAST)); + { + LOCK(walletInstance->cs_wallet); + LogPrintf("setKeyPool.size() = %u\n", walletInstance->GetKeyPoolSize()); + LogPrintf("mapWallet.size() = %u\n", walletInstance->mapWallet.size()); + LogPrintf("mapAddressBook.size() = %u\n", walletInstance->mapAddressBook.size()); + } + // Add wallet transactions that aren't already in a block to mapTransactions + walletInstance->ReacceptWalletTransactions(); + pwalletMain = walletInstance; + return true; } @@ -3530,7 +3543,6 @@ CWalletKey::CWalletKey(int64_t nExpires) int CMerkleTx::SetMerkleBranch(const CBlockIndex* pindex, int posInBlock) { AssertLockHeld(cs_main); - CBlock blockTmp; // Update the tx's hashBlock hashBlock = pindex->GetBlockHash(); diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 952acd1535..c06513650c 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -582,6 +582,8 @@ private: CHDChain hdChain; bool fFileBacked; + + std::set<int64_t> setKeyPool; public: /* * Main wallet lock. @@ -594,7 +596,18 @@ public: std::string strWalletFile; - std::set<int64_t> setKeyPool; + void LoadKeyPool(int nIndex, const CKeyPool &keypool) + { + setKeyPool.insert(nIndex); + + // If no metadata exists yet, create a default with the pool key's + // creation time. Note that this may be overwritten by actually + // stored metadata for that key later, which is fine. + CKeyID keyid = keypool.vchPubKey.GetID(); + if (mapKeyMetadata.count(keyid) == 0) + mapKeyMetadata[keyid] = CKeyMetadata(keypool.nTime); + } + std::map<CKeyID, CKeyMetadata> mapKeyMetadata; typedef std::map<unsigned int, CMasterKey> MasterKeyMap; @@ -902,6 +915,9 @@ public: bool SetHDChain(const CHDChain& chain, bool memonly); const CHDChain& GetHDChain() { return hdChain; } + /* Returns true if HD is enabled */ + bool IsHDEnabled(); + /* Generates a new HD master key (will not be activated) */ CPubKey GenerateNewHDMasterKey(); diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 543522ca64..80bfe8255d 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -18,7 +18,6 @@ #include <boost/version.hpp> #include <boost/filesystem.hpp> #include <boost/foreach.hpp> -#include <boost/scoped_ptr.hpp> #include <boost/thread.hpp> using namespace std; @@ -215,23 +214,23 @@ void CWalletDB::ListAccountCreditDebit(const string& strAccount, list<CAccountin Dbc* pcursor = GetCursor(); if (!pcursor) - throw runtime_error("CWalletDB::ListAccountCreditDebit(): cannot create DB cursor"); - unsigned int fFlags = DB_SET_RANGE; + throw runtime_error(std::string(__func__) + ": cannot create DB cursor"); + bool setRange = true; while (true) { // Read next record CDataStream ssKey(SER_DISK, CLIENT_VERSION); - if (fFlags == DB_SET_RANGE) + if (setRange) ssKey << std::make_pair(std::string("acentry"), std::make_pair((fAllAccounts ? string("") : strAccount), uint64_t(0))); CDataStream ssValue(SER_DISK, CLIENT_VERSION); - int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags); - fFlags = DB_NEXT; + int ret = ReadAtCursor(pcursor, ssKey, ssValue, setRange); + setRange = false; if (ret == DB_NOTFOUND) break; else if (ret != 0) { pcursor->close(); - throw runtime_error("CWalletDB::ListAccountCreditDebit(): error scanning DB"); + throw runtime_error(std::string(__func__) + ": error scanning DB"); } // Unserialize @@ -556,14 +555,8 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, ssKey >> nIndex; CKeyPool keypool; ssValue >> keypool; - pwallet->setKeyPool.insert(nIndex); - - // If no metadata exists yet, create a default with the pool key's - // creation time. Note that this may be overwritten by actually - // stored metadata for that key later, which is fine. - CKeyID keyid = keypool.vchPubKey.GetID(); - if (pwallet->mapKeyMetadata.count(keyid) == 0) - pwallet->mapKeyMetadata[keyid] = CKeyMetadata(keypool.nTime); + + pwallet->LoadKeyPool(nIndex, keypool); } else if (strType == "version") { @@ -893,8 +886,8 @@ void ThreadFlushWalletDB(const string& strFile) if (nRefCount == 0) { boost::this_thread::interruption_point(); - map<string, int>::iterator mi = bitdb.mapFileUseCount.find(strFile); - if (mi != bitdb.mapFileUseCount.end()) + map<string, int>::iterator _mi = bitdb.mapFileUseCount.find(strFile); + if (_mi != bitdb.mapFileUseCount.end()) { LogPrint("db", "Flushing %s\n", strFile); nLastFlushed = nWalletDBUpdated; @@ -904,7 +897,7 @@ void ThreadFlushWalletDB(const string& strFile) bitdb.CloseDb(strFile); bitdb.CheckpointLSN(strFile); - bitdb.mapFileUseCount.erase(mi++); + bitdb.mapFileUseCount.erase(_mi++); LogPrint("db", "Flushed %s %dms\n", strFile, GetTimeMillis() - nStart); } } @@ -947,7 +940,7 @@ bool CWalletDB::Recover(CDBEnv& dbenv, const std::string& filename, bool fOnlyKe } LogPrintf("Salvage(aggressive) found %u records\n", salvagedData.size()); - boost::scoped_ptr<Db> pdbCopy(new Db(dbenv.dbenv, 0)); + std::unique_ptr<Db> pdbCopy(new Db(dbenv.dbenv, 0)); int ret = pdbCopy->open(NULL, // Txn pointer filename.c_str(), // Filename "main", // Logical db name |