diff --git a/src/bench/coin_selection.cpp b/src/bench/coin_selection.cpp --- a/src/bench/coin_selection.cpp +++ b/src/bench/coin_selection.cpp @@ -3,6 +3,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "bench.h" +#include "chainparams.h" #include "wallet/wallet.h" #include @@ -33,7 +34,7 @@ // either for measurements." // (https://github.com/bitcoin/bitcoin/issues/7883#issuecomment-224807484) static void CoinSelection(benchmark::State &state) { - const CWallet wallet; + const CWallet wallet(Params()); std::vector vCoins; LOCK(wallet.cs_wallet); diff --git a/src/init.cpp b/src/init.cpp --- a/src/init.cpp +++ b/src/init.cpp @@ -1686,7 +1686,7 @@ bool AppInitMain(Config &config, boost::thread_group &threadGroup, CScheduler &scheduler) { - const CChainParams &chainparams = Params(); + const CChainParams &chainparams = config.GetChainParams(); // Step 4a: application initialization // After daemonization get the data directory lock again and hold on to it @@ -1758,7 +1758,7 @@ // Step 5: verify wallet database integrity #ifdef ENABLE_WALLET - if (!CWallet::Verify()) { + if (!CWallet::Verify(chainparams)) { return false; } #endif @@ -2157,7 +2157,7 @@ // Step 8: load wallet #ifdef ENABLE_WALLET - if (!CWallet::InitLoadWallet()) return false; + if (!CWallet::InitLoadWallet(chainparams)) return false; #else LogPrintf("No wallet support compiled in!\n"); #endif diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -232,7 +232,7 @@ if (role == Qt::EditRole) { LOCK(wallet->cs_wallet); /* For SetAddressBook / DelAddressBook */ CTxDestination curAddress = - DecodeDestination(rec->address.toStdString()); + DecodeDestination(rec->address.toStdString(), wallet->chainParams); if (index.column() == Label) { // Do nothing, if old label == new label if (rec->label == value.toString()) { @@ -242,8 +242,8 @@ wallet->SetAddressBook(curAddress, value.toString().toStdString(), strPurpose); } else if (index.column() == Address) { - CTxDestination newAddress = - DecodeDestination(value.toString().toStdString()); + CTxDestination newAddress = DecodeDestination( + value.toString().toStdString(), wallet->chainParams); // Refuse to set invalid address, set error status and return false if (boost::get(&newAddress)) { editStatus = INVALID_ADDRESS; @@ -334,7 +334,8 @@ // Check for duplicate addresses { LOCK(wallet->cs_wallet); - if (wallet->mapAddressBook.count(DecodeDestination(strAddress))) { + if (wallet->mapAddressBook.count( + DecodeDestination(strAddress, wallet->chainParams))) { editStatus = DUPLICATE_ADDRESS; return QString(); } @@ -362,8 +363,9 @@ // Add entry { LOCK(wallet->cs_wallet); - wallet->SetAddressBook(DecodeDestination(strAddress), strLabel, - (type == Send ? "send" : "receive")); + wallet->SetAddressBook( + DecodeDestination(strAddress, wallet->chainParams), strLabel, + (type == Send ? "send" : "receive")); } return QString::fromStdString(strAddress); } @@ -380,7 +382,8 @@ } { LOCK(wallet->cs_wallet); - wallet->DelAddressBook(DecodeDestination(rec->address.toStdString())); + wallet->DelAddressBook( + DecodeDestination(rec->address.toStdString(), wallet->chainParams)); } return true; } @@ -390,7 +393,8 @@ QString AddressTableModel::labelForAddress(const QString &address) const { { LOCK(wallet->cs_wallet); - CTxDestination destination = DecodeDestination(address.toStdString()); + CTxDestination destination = + DecodeDestination(address.toStdString(), wallet->chainParams); std::map::iterator mi = wallet->mapAddressBook.find(destination); if (mi != wallet->mapAddressBook.end()) { diff --git a/src/qt/test/wallettests.cpp b/src/qt/test/wallettests.cpp --- a/src/qt/test/wallettests.cpp +++ b/src/qt/test/wallettests.cpp @@ -1,5 +1,6 @@ #include "wallettests.h" +#include "chainparams.h" #include "dstencode.h" #include "qt/bitcoinamountfield.h" #include "qt/optionsmodel.h" @@ -89,7 +90,7 @@ bitdb.MakeMock(); std::unique_ptr dbw( new CWalletDBWrapper(&bitdb, "wallet_test.dat")); - CWallet wallet(std::move(dbw)); + CWallet wallet(Params(), std::move(dbw)); bool firstRun; wallet.LoadWallet(firstRun); { diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -90,7 +90,8 @@ // Offline transaction if (nNet > Amount(0)) { // Credit - CTxDestination address = DecodeDestination(rec->address); + CTxDestination address = + DecodeDestination(rec->address, wallet->chainParams); if (IsValidDestination(address)) { if (wallet->mapAddressBook.count(address)) { strHTML += @@ -122,7 +123,8 @@ // Online transaction std::string strAddress = wtx.mapValue["to"]; strHTML += "" + tr("To") + ": "; - CTxDestination dest = DecodeDestination(strAddress); + CTxDestination dest = + DecodeDestination(strAddress, wallet->chainParams); if (wallet->mapAddressBook.count(dest) && !wallet->mapAddressBook[dest].name.empty()) strHTML += diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -224,8 +224,8 @@ setAddress.insert(rcp.address); ++nAddresses; - CScript scriptPubKey = GetScriptForDestination( - DecodeDestination(rcp.address.toStdString())); + CScript scriptPubKey = GetScriptForDestination(DecodeDestination( + rcp.address.toStdString(), wallet->chainParams)); CRecipient recipient = {scriptPubKey, Amount(rcp.amount), rcp.fSubtractFeeFromAmount}; vecSend.push_back(recipient); @@ -329,7 +329,8 @@ // Don't touch the address book when we have a payment request if (!rcp.paymentRequest.IsInitialized()) { std::string strAddress = rcp.address.toStdString(); - CTxDestination dest = DecodeDestination(strAddress); + CTxDestination dest = + DecodeDestination(strAddress, wallet->chainParams); std::string strLabel = rcp.label.toStdString(); { LOCK(wallet->cs_wallet); @@ -643,7 +644,7 @@ bool WalletModel::saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest) { - CTxDestination dest = DecodeDestination(sAddress); + CTxDestination dest = DecodeDestination(sAddress, wallet->chainParams); std::stringstream ss; ss << nId; diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -312,23 +312,25 @@ const std::string &ks = keys[i].get_str(); #ifdef ENABLE_WALLET // Case 1: Bitcoin address and we have full public key: - CTxDestination dest = DecodeDestination(ks); - if (pwallet && IsValidDestination(dest)) { - const CKeyID *keyID = boost::get(&dest); - if (!keyID) { - throw std::runtime_error( - strprintf("%s does not refer to a key", ks)); - } - CPubKey vchPubKey; - if (!pwallet->GetPubKey(*keyID, vchPubKey)) { - throw std::runtime_error( - strprintf("no full public key for address %s", ks)); - } - if (!vchPubKey.IsFullyValid()) { - throw std::runtime_error(" Invalid public key: " + ks); + if (pwallet) { + CTxDestination dest = DecodeDestination(ks, pwallet->chainParams); + if (IsValidDestination(dest)) { + const CKeyID *keyID = boost::get(&dest); + if (!keyID) { + throw std::runtime_error( + strprintf("%s does not refer to a key", ks)); + } + CPubKey vchPubKey; + if (!pwallet->GetPubKey(*keyID, vchPubKey)) { + throw std::runtime_error( + strprintf("no full public key for address %s", ks)); + } + if (!vchPubKey.IsFullyValid()) { + throw std::runtime_error(" Invalid public key: " + ks); + } + pubkeys[i] = vchPubKey; + continue; } - pubkeys[i] = vchPubKey; - continue; } #endif // Case 2: hex public key diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -810,7 +810,7 @@ CTxDestination dest; if (!isScript) { - dest = DecodeDestination(output); + dest = DecodeDestination(output, pwallet->chainParams); if (!IsValidDestination(dest)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); diff --git a/src/wallet/test/wallet_test_fixture.cpp b/src/wallet/test/wallet_test_fixture.cpp --- a/src/wallet/test/wallet_test_fixture.cpp +++ b/src/wallet/test/wallet_test_fixture.cpp @@ -3,6 +3,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "wallet/test/wallet_test_fixture.h" +#include "chainparams.h" #include "rpc/server.h" #include "wallet/db.h" @@ -18,7 +19,7 @@ bool fFirstRun; std::unique_ptr dbw( new CWalletDBWrapper(&bitdb, "wallet_test.dat")); - pwalletMain = new CWallet(std::move(dbw)); + pwalletMain = new CWallet(Params(), std::move(dbw)); pwalletMain->LoadWallet(fFirstRun); RegisterValidationInterface(pwalletMain); diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -4,6 +4,7 @@ #include "wallet/wallet.h" +#include "chainparams.h" #include "config.h" #include "rpc/server.h" #include "test/test_bitcoin.h" @@ -36,11 +37,15 @@ BOOST_FIXTURE_TEST_SUITE(wallet_tests, WalletTestingSetup) -static const CWallet wallet; +// Critical section is used to prevent concurrent execution of +// tests in this fixture +static CCriticalSection walletCriticalSection; + static std::vector vCoins; -static void add_coin(const Amount nValue, int nAge = 6 * 24, - bool fIsFromMe = false, int nInput = 0) { +static void add_coin(const CWallet &wallet, const Amount nValue, + int nAge = 6 * 24, bool fIsFromMe = false, + int nInput = 0) { static int nextLockTime = 0; CMutableTransaction tx; tx.nLockTime = nextLockTime++; // so all transactions get different hashes @@ -79,7 +84,8 @@ CoinSet setCoinsRet, setCoinsRet2; Amount nValueRet; - LOCK(wallet.cs_wallet); + const CWallet wallet(Params()); + LOCK(walletCriticalSection); // test multiple times to allow for differences in the shuffle order for (int i = 0; i < RUN_TESTS; i++) { @@ -89,7 +95,7 @@ BOOST_CHECK(!wallet.SelectCoinsMinConf(1 * CENT, 1, 6, 0, vCoins, setCoinsRet, nValueRet)); // add a new 1 cent coin - add_coin(1 * CENT, 4); + add_coin(wallet, 1 * CENT, 4); // with a new 1 cent coin, we still can't find a mature 1 cent BOOST_CHECK(!wallet.SelectCoinsMinConf(1 * CENT, 1, 6, 0, vCoins, @@ -100,7 +106,7 @@ setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); // add a mature 2 cent coin - add_coin(2 * CENT); + add_coin(wallet, 2 * CENT); // we can't make 3 cents of mature coins BOOST_CHECK(!wallet.SelectCoinsMinConf(3 * CENT, 1, 6, 0, vCoins, @@ -112,11 +118,11 @@ BOOST_CHECK_EQUAL(nValueRet, 3 * CENT); // add a mature 5 cent coin, - add_coin(5 * CENT); + add_coin(wallet, 5 * CENT); // a new 10 cent coin sent from one of our own addresses - add_coin(10 * CENT, 3, true); + add_coin(wallet, 10 * CENT, 3, true); // and a mature 20 cent coin - add_coin(20 * CENT); + add_coin(wallet, 20 * CENT); // now we have new: 1+10=11 (of which 10 was self-sent), and mature: // 2+5+20=27. total = 38 @@ -171,12 +177,12 @@ // subsets of smaller coins and the next biggest coin empty_wallet(); - add_coin(6 * CENT); - add_coin(7 * CENT); - add_coin(8 * CENT); - add_coin(20 * CENT); + add_coin(wallet, 6 * CENT); + add_coin(wallet, 7 * CENT); + add_coin(wallet, 8 * CENT); + add_coin(wallet, 20 * CENT); // now we have 6+7+8+20+30 = 71 cents total - add_coin(30 * CENT); + add_coin(wallet, 30 * CENT); // check that we have 71 and not 72 BOOST_CHECK(wallet.SelectCoinsMinConf(71 * CENT, 1, 1, 0, vCoins, @@ -193,7 +199,7 @@ BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); // now we have 5+6+7+8+20+30 = 75 cents total - add_coin(5 * CENT); + add_coin(wallet, 5 * CENT); // now if we try making 16 cents again, the smaller coins can make 5+6+7 // = 18 cents, better than the next biggest coin, 20 @@ -204,7 +210,7 @@ BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); // now we have 5+6+7+8+18+20+30 - add_coin(18 * CENT); + add_coin(wallet, 18 * CENT); // and now if we try making 16 cents again, the smaller coins can make // 5+6+7 = 18 cents, the same as the next biggest coin, 18 @@ -222,11 +228,11 @@ BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); // check that the smallest bigger coin is used - add_coin(1 * COIN); - add_coin(2 * COIN); - add_coin(3 * COIN); + add_coin(wallet, 1 * COIN); + add_coin(wallet, 2 * COIN); + add_coin(wallet, 3 * COIN); // now we have 5+6+7+8+18+20+30+100+200+300+400 = 1094 cents - add_coin(4 * COIN); + add_coin(wallet, 4 * COIN); BOOST_CHECK(wallet.SelectCoinsMinConf(95 * CENT, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); // we should get 1 BCH in 1 coin @@ -243,11 +249,11 @@ // test small change avoidance empty_wallet(); - add_coin(1 * MIN_CHANGE / 10); - add_coin(2 * MIN_CHANGE / 10); - add_coin(3 * MIN_CHANGE / 10); - add_coin(4 * MIN_CHANGE / 10); - add_coin(5 * MIN_CHANGE / 10); + add_coin(wallet, 1 * MIN_CHANGE / 10); + add_coin(wallet, 2 * MIN_CHANGE / 10); + add_coin(wallet, 3 * MIN_CHANGE / 10); + add_coin(wallet, 4 * MIN_CHANGE / 10); + add_coin(wallet, 5 * MIN_CHANGE / 10); // try making 1 * MIN_CHANGE from the 1.5 * MIN_CHANGE we'll get change // smaller than MIN_CHANGE whatever happens, so can expect MIN_CHANGE @@ -257,7 +263,7 @@ BOOST_CHECK_EQUAL(nValueRet, MIN_CHANGE); // but if we add a bigger coin, small change is avoided - add_coin(1111 * MIN_CHANGE); + add_coin(wallet, 1111 * MIN_CHANGE); // try making 1 from 0.1 + 0.2 + 0.3 + 0.4 + 0.5 + 1111 = 1112.5 BOOST_CHECK(wallet.SelectCoinsMinConf(1 * MIN_CHANGE, 1, 1, 0, vCoins, @@ -266,8 +272,8 @@ BOOST_CHECK_EQUAL(nValueRet, 1 * MIN_CHANGE); // if we add more small coins: - add_coin(6 * MIN_CHANGE / 10); - add_coin(7 * MIN_CHANGE / 10); + add_coin(wallet, 6 * MIN_CHANGE / 10); + add_coin(wallet, 7 * MIN_CHANGE / 10); // and try again to make 1.0 * MIN_CHANGE BOOST_CHECK(wallet.SelectCoinsMinConf(1 * MIN_CHANGE, 1, 1, 0, vCoins, @@ -281,7 +287,7 @@ // up with 50k in change empty_wallet(); for (int j = 0; j < 20; j++) { - add_coin(50000 * COIN); + add_coin(wallet, 50000 * COIN); } BOOST_CHECK(wallet.SelectCoinsMinConf(500000 * COIN, 1, 1, 0, vCoins, @@ -297,10 +303,10 @@ // sometimes it will fail, and so we use the next biggest coin: empty_wallet(); - add_coin(5 * MIN_CHANGE / 10); - add_coin(6 * MIN_CHANGE / 10); - add_coin(7 * MIN_CHANGE / 10); - add_coin(1111 * MIN_CHANGE); + add_coin(wallet, 5 * MIN_CHANGE / 10); + add_coin(wallet, 6 * MIN_CHANGE / 10); + add_coin(wallet, 7 * MIN_CHANGE / 10); + add_coin(wallet, 1111 * MIN_CHANGE); BOOST_CHECK(wallet.SelectCoinsMinConf(1 * MIN_CHANGE, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); // we get the bigger coin @@ -310,10 +316,10 @@ // but sometimes it's possible, and we use an exact subset (0.4 + 0.6 = // 1.0) empty_wallet(); - add_coin(4 * MIN_CHANGE / 10); - add_coin(6 * MIN_CHANGE / 10); - add_coin(8 * MIN_CHANGE / 10); - add_coin(1111 * MIN_CHANGE); + add_coin(wallet, 4 * MIN_CHANGE / 10); + add_coin(wallet, 6 * MIN_CHANGE / 10); + add_coin(wallet, 8 * MIN_CHANGE / 10); + add_coin(wallet, 1111 * MIN_CHANGE); BOOST_CHECK(wallet.SelectCoinsMinConf(MIN_CHANGE, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); // we should get the exact amount @@ -323,9 +329,9 @@ // test avoiding small change empty_wallet(); - add_coin(5 * MIN_CHANGE / 100); - add_coin(1 * MIN_CHANGE); - add_coin(100 * MIN_CHANGE); + add_coin(wallet, 5 * MIN_CHANGE / 100); + add_coin(wallet, 1 * MIN_CHANGE); + add_coin(wallet, 100 * MIN_CHANGE); // trying to make 100.01 from these three coins BOOST_CHECK(wallet.SelectCoinsMinConf(10001 * MIN_CHANGE / 100, 1, 1, 0, @@ -347,7 +353,7 @@ // Create 676 inputs (= (old MAX_STANDARD_TX_SIZE == 100000) / 148 // bytes per input) for (uint16_t j = 0; j < 676; j++) { - add_coin(amt); + add_coin(wallet, amt); } BOOST_CHECK(wallet.SelectCoinsMinConf(Amount(2000), 1, 1, 0, vCoins, setCoinsRet, nValueRet)); @@ -369,7 +375,7 @@ { empty_wallet(); for (int i2 = 0; i2 < 100; i2++) { - add_coin(COIN); + add_coin(wallet, COIN); } // picking 50 from 100 coins doesn't depend on the shuffle, but does @@ -396,11 +402,11 @@ // add 75 cents in small change. not enough to make 90 cents, then // try making 90 cents. there are multiple competing "smallest // bigger" coins, one of which should be picked at random - add_coin(5 * CENT); - add_coin(10 * CENT); - add_coin(15 * CENT); - add_coin(20 * CENT); - add_coin(25 * CENT); + add_coin(wallet, 5 * CENT); + add_coin(wallet, 10 * CENT); + add_coin(wallet, 15 * CENT); + add_coin(wallet, 20 * CENT); + add_coin(wallet, 25 * CENT); fails = 0; for (int j = 0; j < RANDOM_REPEATS; j++) { @@ -423,15 +429,16 @@ CoinSet setCoinsRet; Amount nValueRet; - LOCK(wallet.cs_wallet); + const CWallet wallet(Params()); + LOCK(walletCriticalSection); empty_wallet(); // Test vValue sort order for (int i = 0; i < 1000; i++) { - add_coin(1000 * COIN); + add_coin(wallet, 1000 * COIN); } - add_coin(3 * COIN); + add_coin(wallet, 3 * COIN); BOOST_CHECK(wallet.SelectCoinsMinConf(1003 * COIN, 1, 6, 0, vCoins, setCoinsRet, nValueRet)); @@ -453,7 +460,7 @@ // Verify ScanForWalletTransactions picks up transactions in both the old // and new block files. { - CWallet wallet; + CWallet wallet(Params()); LOCK(wallet.cs_wallet); wallet.AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey()); BOOST_CHECK_EQUAL(oldTip, wallet.ScanForWalletTransactions(oldTip)); @@ -467,7 +474,7 @@ // Verify ScanForWalletTransactions only picks transactions in the new block // file. { - CWallet wallet; + CWallet wallet(Params()); LOCK(wallet.cs_wallet); wallet.AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey()); BOOST_CHECK_EQUAL(newTip, wallet.ScanForWalletTransactions(oldTip)); @@ -478,7 +485,7 @@ // before the missing block, and success for a key whose creation time is // after. { - CWallet wallet; + CWallet wallet(Params()); vpwallets.insert(vpwallets.begin(), &wallet); UniValue keys; keys.setArray(); @@ -515,7 +522,7 @@ // Verify ScanForWalletTransactions does not return null when the scan is // elided due to the nTimeFirstKey optimization. { - CWallet wallet; + CWallet wallet(Params()); { LOCK(wallet.cs_wallet); wallet.UpdateTimeFirstKey(newTip->GetBlockTime() + 7200 + 1); @@ -555,7 +562,7 @@ // Import key into wallet and call dumpwallet to create backup file. { - CWallet wallet; + CWallet wallet(Params()); LOCK(wallet.cs_wallet); wallet.mapKeyMetadata[coinbaseKey.GetPubKey().GetID()].nCreateTime = KEY_TIME; @@ -571,7 +578,7 @@ // Call importwallet RPC and verify all blocks with timestamps >= BLOCK_TIME // were scanned, and no prior blocks were scanned. { - CWallet wallet; + CWallet wallet(Params()); JSONRPCRequest request; request.params.setArray(); @@ -599,7 +606,7 @@ // function. Similar tests probably should be written for the other credit and // debit functions. BOOST_FIXTURE_TEST_CASE(coin_mark_dirty_immature_credit, TestChain100Setup) { - CWallet wallet; + CWallet wallet(Params()); CWalletTx wtx(&wallet, MakeTransactionRef(coinbaseTxns.back())); LOCK2(cs_main, wallet.cs_wallet); wtx.hashBlock = chainActive.Tip()->GetBlockHash(); @@ -642,7 +649,7 @@ // Simple test to verify assignment of CWalletTx::nSmartTime value. Could be // expanded to cover more corner cases of smart time logic. BOOST_AUTO_TEST_CASE(ComputeTimeSmart) { - CWallet wallet; + CWallet wallet(Params()); // New transaction should use clock time if lower than block time. BOOST_CHECK_EQUAL(AddTx(wallet, 1, 100, 120), 100); diff --git a/src/wallet/test/walletdb_tests.cpp b/src/wallet/test/walletdb_tests.cpp --- a/src/wallet/test/walletdb_tests.cpp +++ b/src/wallet/test/walletdb_tests.cpp @@ -2,6 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "chainparams.h" #include "test/test_bitcoin.h" #include "wallet/wallet.h" @@ -34,7 +35,7 @@ } static std::unique_ptr LoadWallet(CWalletDB *db) { - std::unique_ptr wallet(new CWallet); + std::unique_ptr wallet(new CWallet(Params())); DBErrors res = db->LoadWallet(wallet.get()); BOOST_CHECK(res == DB_LOAD_OK); return wallet; diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -72,6 +72,7 @@ extern const char *DEFAULT_WALLET_DAT; class CBlockIndex; +class CChainParams; class CCoinControl; class COutput; class CReserveKey; @@ -676,6 +677,7 @@ uint256 hashPrevBestCoinbase; public: + const CChainParams &chainParams; /* * Main wallet lock. * This lock protects all the fields added by CWallet. @@ -710,10 +712,15 @@ unsigned int nMasterKeyMaxID; // Create wallet with dummy database handle - CWallet() : dbw(new CWalletDBWrapper()) { SetNull(); } + CWallet(const CChainParams &chainParams) + : dbw(new CWalletDBWrapper()), chainParams(chainParams) { + SetNull(); + } // Create wallet with passed-in database handle - CWallet(std::unique_ptr dbw_in) : dbw(std::move(dbw_in)) { + CWallet(const CChainParams &chainParams, + std::unique_ptr dbw_in) + : dbw(std::move(dbw_in)), chainParams(chainParams) { SetNull(); } @@ -1060,7 +1067,7 @@ // This function will perform salvage on the wallet if requested, as long as // only one wallet is being loaded (CWallet::ParameterInteraction forbids // -salvagewallet, -zapwallettxes or -upgradewallet with multiwallet). - static bool Verify(); + static bool Verify(const CChainParams &chainParams); /** * Address book entry changed. @@ -1106,8 +1113,9 @@ * Initializes the wallet, returns a new CWallet instance or a null pointer * in case of an error. */ - static CWallet *CreateWalletFromFile(const std::string walletFile); - static bool InitLoadWallet(); + static CWallet *CreateWalletFromFile(const CChainParams &chainParams, + const std::string walletFile); + static bool InitLoadWallet(const CChainParams &chainParams); /** * Wallet post-init setup diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -575,7 +575,7 @@ dbw->Flush(shutdown); } -bool CWallet::Verify() { +bool CWallet::Verify(const CChainParams &chainParams) { if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) { return true; } @@ -622,7 +622,7 @@ if (gArgs.GetBoolArg("-salvagewallet", false)) { // Recover readable keypairs: - CWallet dummyWallet; + CWallet dummyWallet(chainParams); std::string backup_filename; if (!CWalletDB::Recover(walletFile, (void *)&dummyWallet, CWalletDB::RecoverKeysOnlyFilter, @@ -1711,7 +1711,6 @@ LOCK2(cs_main, cs_wallet); int64_t nNow = GetTime(); - const CChainParams &chainParams = Params(); CBlockIndex *pindex = pindexStart; CBlockIndex *ret = pindexStart; @@ -4112,7 +4111,8 @@ return strUsage; } -CWallet *CWallet::CreateWalletFromFile(const std::string walletFile) { +CWallet *CWallet::CreateWalletFromFile(const CChainParams &chainParams, + const std::string walletFile) { // Needed to restore wallet transaction meta data after -zapwallettxes std::vector vWtx; @@ -4121,7 +4121,7 @@ std::unique_ptr dbw( new CWalletDBWrapper(&bitdb, walletFile)); - CWallet *tempWallet = new CWallet(std::move(dbw)); + CWallet *tempWallet = new CWallet(chainParams, std::move(dbw)); DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx); if (nZapWalletRet != DB_LOAD_OK) { InitError( @@ -4139,7 +4139,7 @@ bool fFirstRun = true; std::unique_ptr dbw( new CWalletDBWrapper(&bitdb, walletFile)); - CWallet *walletInstance = new CWallet(std::move(dbw)); + CWallet *walletInstance = new CWallet(chainParams, std::move(dbw)); DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun); if (nLoadWalletRet != DB_LOAD_OK) { if (nLoadWalletRet == DB_CORRUPT) { @@ -4315,14 +4315,14 @@ return walletInstance; } -bool CWallet::InitLoadWallet() { +bool CWallet::InitLoadWallet(const CChainParams &chainParams) { if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) { LogPrintf("Wallet disabled!\n"); return true; } for (const std::string &walletFile : gArgs.GetArgs("-wallet")) { - CWallet *const pwallet = CreateWalletFromFile(walletFile); + CWallet *const pwallet = CreateWalletFromFile(chainParams, walletFile); if (!pwallet) { return false; } diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -284,13 +284,17 @@ if (strType == "name") { std::string strAddress; ssKey >> strAddress; - ssValue >> - pwallet->mapAddressBook[DecodeDestination(strAddress)].name; + ssValue >> pwallet + ->mapAddressBook[DecodeDestination( + strAddress, pwallet->chainParams)] + .name; } else if (strType == "purpose") { std::string strAddress; ssKey >> strAddress; - ssValue >> - pwallet->mapAddressBook[DecodeDestination(strAddress)].purpose; + ssValue >> pwallet + ->mapAddressBook[DecodeDestination( + strAddress, pwallet->chainParams)] + .purpose; } else if (strType == "tx") { uint256 hash; ssKey >> hash; @@ -498,8 +502,9 @@ ssKey >> strAddress; ssKey >> strKey; ssValue >> strValue; - if (!pwallet->LoadDestData(DecodeDestination(strAddress), strKey, - strValue)) { + if (!pwallet->LoadDestData( + DecodeDestination(strAddress, pwallet->chainParams), strKey, + strValue)) { strErr = "Error reading wallet database: LoadDestData failed"; return false; }