X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fwallet.cpp;h=97ed6aa58028555b78d68b5b7c5a92dcd12d4935;hb=f8dcd5ca6f55ad49807cf7491c1f153f6158400e;hp=42c49aa89176846fabb57cc13ac98ea6afd12f09;hpb=0b807a417f4a15f3e37ae35e70a72e6169f01c02;p=novacoin.git diff --git a/src/wallet.cpp b/src/wallet.cpp index 42c49aa..97ed6aa 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -15,6 +15,23 @@ using namespace std; // mapWallet // +std::vector CWallet::GenerateNewKey() +{ + bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets + + RandAddSeedPerfmon(); + CKey key; + key.MakeNewKey(fCompressed); + + // Compressed public keys were introduced in version 0.6.0 + if (fCompressed) + SetMinVersion(FEATURE_COMPRPUBKEY); + + if (!AddKey(key)) + throw std::runtime_error("CWallet::GenerateNewKey() : AddKey failed"); + return key.GetPubKey(); +} + bool CWallet::AddKey(const CKey& key) { if (!CCryptoKeyStore::AddKey(key)) @@ -32,8 +49,8 @@ bool CWallet::AddCryptedKey(const vector &vchPubKey, const vector return false; if (!fFileBacked) return true; - CRITICAL_BLOCK(cs_wallet) { + LOCK(cs_wallet); if (pwalletdbEncryption) return pwalletdbEncryption->WriteCryptedKey(vchPubKey, vchCryptedSecret); else @@ -59,7 +76,8 @@ bool CWallet::Unlock(const SecureString& strWalletPassphrase) CCrypter crypter; CKeyingMaterial vMasterKey; - CRITICAL_BLOCK(cs_wallet) + { + LOCK(cs_wallet); BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys) { if(!crypter.SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod)) @@ -69,6 +87,7 @@ bool CWallet::Unlock(const SecureString& strWalletPassphrase) if (CCryptoKeyStore::Unlock(vMasterKey)) return true; } + } return false; } @@ -76,8 +95,8 @@ bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, { bool fWasLocked = IsLocked(); - CRITICAL_BLOCK(cs_wallet) { + LOCK(cs_wallet); Lock(); CCrypter crypter; @@ -131,13 +150,20 @@ public: ) }; -bool CWallet::SetMinVersion(int nVersion, CWalletDB* pwalletdbIn) +bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB* pwalletdbIn, bool fExplicit) { if (nWalletVersion >= nVersion) return true; + // when doing an explicit upgrade, if we pass the max version permitted, upgrade all the way + if (fExplicit && nVersion > nWalletMaxVersion) + nVersion = FEATURE_LATEST; + nWalletVersion = nVersion; + if (nVersion > nWalletMaxVersion) + nWalletMaxVersion = nVersion; + if (fFileBacked) { CWalletDB* pwalletdb = pwalletdbIn ? pwalletdbIn : new CWalletDB(strWalletFile); @@ -157,6 +183,17 @@ bool CWallet::SetMinVersion(int nVersion, CWalletDB* pwalletdbIn) return true; } +bool CWallet::SetMaxVersion(int nVersion) +{ + // cannot downgrade below current version + if (nWalletVersion > nVersion) + return false; + + nWalletMaxVersion = nVersion; + + return true; +} + bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) { if (IsCrypted()) @@ -193,8 +230,8 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) if (!crypter.Encrypt(vMasterKey, kMasterKey.vchCryptedKey)) return false; - CRITICAL_BLOCK(cs_wallet) { + LOCK(cs_wallet); mapMasterKeys[++nMasterKeyMaxID] = kMasterKey; if (fFileBacked) { @@ -211,14 +248,14 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) } // Encryption was introduced in version 0.4.0 - SetMinVersion(40000, pwalletdbEncryption); + SetMinVersion(FEATURE_WALLETCRYPT, pwalletdbEncryption, true); if (fFileBacked) { if (!pwalletdbEncryption->TxnCommit()) exit(1); //We now have keys encrypted in memory, but no on disk...die to avoid confusion and let the user reload their unencrypted wallet. - pwalletdbEncryption->Close(); + delete pwalletdbEncryption; pwalletdbEncryption = NULL; } @@ -240,8 +277,8 @@ void CWallet::WalletUpdateSpent(const CTransaction &tx) // Anytime a signature is successfully verified, it's proof the outpoint is spent. // Update the wallet spent flag if it doesn't know due to wallet.dat being // restored from backup or the user making copies of wallet.dat. - CRITICAL_BLOCK(cs_wallet) { + LOCK(cs_wallet); BOOST_FOREACH(const CTxIn& txin, tx.vin) { map::iterator mi = mapWallet.find(txin.prevout.hash); @@ -262,8 +299,8 @@ void CWallet::WalletUpdateSpent(const CTransaction &tx) void CWallet::MarkDirty() { - CRITICAL_BLOCK(cs_wallet) { + LOCK(cs_wallet); BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet) item.second.MarkDirty(); } @@ -272,8 +309,8 @@ void CWallet::MarkDirty() bool CWallet::AddToWallet(const CWalletTx& wtxIn) { uint256 hash = wtxIn.GetHash(); - CRITICAL_BLOCK(cs_wallet) { + LOCK(cs_wallet); // Inserts only if not already there, returns tx inserted or tx found pair::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn)); CWalletTx& wtx = (*ret.first).second; @@ -347,8 +384,8 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn) bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate, bool fFindBlock) { uint256 hash = tx.GetHash(); - CRITICAL_BLOCK(cs_wallet) { + LOCK(cs_wallet); bool fExisted = mapWallet.count(hash); if (fExisted && !fUpdate) return false; if (fExisted || IsMine(tx) || IsFromMe(tx)) @@ -369,8 +406,8 @@ bool CWallet::EraseFromWallet(uint256 hash) { if (!fFileBacked) return false; - CRITICAL_BLOCK(cs_wallet) { + LOCK(cs_wallet); if (mapWallet.erase(hash)) CWalletDB(strWalletFile).EraseTx(hash); } @@ -380,8 +417,8 @@ bool CWallet::EraseFromWallet(uint256 hash) bool CWallet::IsMine(const CTxIn &txin) const { - CRITICAL_BLOCK(cs_wallet) { + LOCK(cs_wallet); map::const_iterator mi = mapWallet.find(txin.prevout.hash); if (mi != mapWallet.end()) { @@ -396,8 +433,8 @@ bool CWallet::IsMine(const CTxIn &txin) const int64 CWallet::GetDebit(const CTxIn &txin) const { - CRITICAL_BLOCK(cs_wallet) { + LOCK(cs_wallet); map::const_iterator mi = mapWallet.find(txin.prevout.hash); if (mi != mapWallet.end()) { @@ -422,9 +459,11 @@ bool CWallet::IsChange(const CTxOut& txout) const // 'the change' will need to be implemented (maybe extend CWalletTx to remember // which output, if any, was change). if (ExtractAddress(txout.scriptPubKey, address) && HaveKey(address)) - CRITICAL_BLOCK(cs_wallet) - if (!mapAddressBook.count(address)) - return true; + { + LOCK(cs_wallet); + if (!mapAddressBook.count(address)) + return true; + } return false; } @@ -437,8 +476,8 @@ int CWalletTx::GetRequestCount() const { // Returns -1 if it wasn't being tracked int nRequests = -1; - CRITICAL_BLOCK(pwallet->cs_wallet) { + LOCK(pwallet->cs_wallet); if (IsCoinBase()) { // Generated block @@ -542,8 +581,8 @@ void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGenerated, i nSent += s.second; nFee = allFee; } - CRITICAL_BLOCK(pwallet->cs_wallet) { + LOCK(pwallet->cs_wallet); BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listReceived) { if (pwallet->mapAddressBook.count(r.first)) @@ -572,8 +611,8 @@ void CWalletTx::AddSupportingTransactions(CTxDB& txdb) vWorkQueue.push_back(txin.prevout.hash); // This critsect is OK because txdb is already open - CRITICAL_BLOCK(pwallet->cs_wallet) { + LOCK(pwallet->cs_wallet); map mapWalletPrev; set setAlreadyDone; for (int i = 0; i < vWorkQueue.size(); i++) @@ -631,8 +670,8 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) int ret = 0; CBlockIndex* pindex = pindexStart; - CRITICAL_BLOCK(cs_wallet) { + LOCK(cs_wallet); while (pindex) { CBlock block; @@ -661,8 +700,9 @@ void CWallet::ReacceptWalletTransactions() { CTxDB txdb("r"); bool fRepeat = true; - while (fRepeat) CRITICAL_BLOCK(cs_wallet) + while (fRepeat) { + LOCK(cs_wallet); fRepeat = false; vector vMissingTx; BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet) @@ -764,8 +804,8 @@ void CWallet::ResendWalletTransactions() // Rebroadcast any of our txes that aren't in a block yet printf("ResendWalletTransactions()\n"); CTxDB txdb("r"); - CRITICAL_BLOCK(cs_wallet) { + LOCK(cs_wallet); // Sort them in chronological order multimap mapSorted; BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet) @@ -798,8 +838,8 @@ void CWallet::ResendWalletTransactions() int64 CWallet::GetBalance() const { int64 nTotal = 0; - CRITICAL_BLOCK(cs_wallet) { + LOCK(cs_wallet); for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) { const CWalletTx* pcoin = &(*it).second; @@ -815,8 +855,8 @@ int64 CWallet::GetBalance() const int64 CWallet::GetUnconfirmedBalance() const { int64 nTotal = 0; - CRITICAL_BLOCK(cs_wallet) { + LOCK(cs_wallet); for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) { const CWalletTx* pcoin = &(*it).second; @@ -840,8 +880,8 @@ bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfThe vector > > vValue; int64 nTotalLower = 0; - CRITICAL_BLOCK(cs_wallet) { + LOCK(cs_wallet); vector vCoins; vCoins.reserve(mapWallet.size()); for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) @@ -997,9 +1037,8 @@ bool CWallet::CreateTransaction(const vector >& vecSend, CW wtxNew.BindWallet(this); - CRITICAL_BLOCK(cs_main) - CRITICAL_BLOCK(cs_wallet) { + LOCK2(cs_main, cs_wallet); // txdb must be opened before the mapWallet lock CTxDB txdb("r"); { @@ -1111,9 +1150,8 @@ bool CWallet::CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& w // Call after CreateTransaction unless you want to abort bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) { - CRITICAL_BLOCK(cs_main) - CRITICAL_BLOCK(cs_wallet) { + LOCK2(cs_main, cs_wallet); printf("CommitTransaction:\n%s", wtxNew.ToString().c_str()); { // This is only to keep the database open to defeat the auto-flush for the @@ -1184,7 +1222,7 @@ string CWallet::SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, return strError; } - if (fAskFee && !ThreadSafeAskFee(nFeeRequired, _("Sending..."), NULL)) + if (fAskFee && !ThreadSafeAskFee(nFeeRequired, _("Sending..."))) return "ABORTED"; if (!CommitTransaction(wtxNew, reservekey)) @@ -1236,19 +1274,6 @@ int CWallet::LoadWallet(bool& fFirstRunRet) return nLoadWalletRet; fFirstRunRet = vchDefaultKey.empty(); - if (!HaveKey(Hash160(vchDefaultKey))) - { - // Create new keyUser and set as default key - RandAddSeedPerfmon(); - - std::vector newDefaultKey; - if (!GetKeyFromPool(newDefaultKey, false)) - return DB_LOAD_FAIL; - SetDefaultKey(newDefaultKey); - if (!SetAddressBookName(CBitcoinAddress(vchDefaultKey), "")) - return DB_LOAD_FAIL; - } - CreateThread(ThreadFlushWalletDB, &strWalletFile); return DB_LOAD_OK; } @@ -1257,6 +1282,7 @@ int CWallet::LoadWallet(bool& fFirstRunRet) bool CWallet::SetAddressBookName(const CBitcoinAddress& address, const string& strName) { mapAddressBook[address] = strName; + AddressBookRepaint(); if (!fFileBacked) return false; return CWalletDB(strWalletFile).WriteName(address.ToString(), strName); @@ -1265,6 +1291,7 @@ bool CWallet::SetAddressBookName(const CBitcoinAddress& address, const string& s bool CWallet::DelAddressBookName(const CBitcoinAddress& address) { mapAddressBook.erase(address); + AddressBookRepaint(); if (!fFileBacked) return false; return CWalletDB(strWalletFile).EraseName(address.ToString()); @@ -1273,8 +1300,8 @@ bool CWallet::DelAddressBookName(const CBitcoinAddress& address) void CWallet::PrintWallet(const CBlock& block) { - CRITICAL_BLOCK(cs_wallet) { + LOCK(cs_wallet); if (mapWallet.count(block.vtx[0].GetHash())) { CWalletTx& wtx = mapWallet[block.vtx[0].GetHash()]; @@ -1286,8 +1313,8 @@ void CWallet::PrintWallet(const CBlock& block) bool CWallet::GetTransaction(const uint256 &hashTx, CWalletTx& wtx) { - CRITICAL_BLOCK(cs_wallet) { + LOCK(cs_wallet); map::iterator mi = mapWallet.find(hashTx); if (mi != mapWallet.end()) { @@ -1323,8 +1350,8 @@ bool GetWalletFile(CWallet* pwallet, string &strWalletFileOut) // bool CWallet::NewKeyPool() { - CRITICAL_BLOCK(cs_wallet) { + LOCK(cs_wallet); CWalletDB walletdb(strWalletFile); BOOST_FOREACH(int64 nIndex, setKeyPool) walletdb.ErasePool(nIndex); @@ -1347,8 +1374,9 @@ bool CWallet::NewKeyPool() bool CWallet::TopUpKeyPool() { - CRITICAL_BLOCK(cs_wallet) { + LOCK(cs_wallet); + if (IsLocked()) return false; @@ -1374,8 +1402,9 @@ void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool) { nIndex = -1; keypool.vchPubKey.clear(); - CRITICAL_BLOCK(cs_wallet) { + LOCK(cs_wallet); + if (!IsLocked()) TopUpKeyPool(); @@ -1398,9 +1427,8 @@ void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool) int64 CWallet::AddReserveKey(const CKeyPool& keypool) { - CRITICAL_BLOCK(cs_main) - CRITICAL_BLOCK(cs_wallet) { + LOCK2(cs_main, cs_wallet); CWalletDB walletdb(strWalletFile); int64 nIndex = 1 + *(--setKeyPool.end()); @@ -1426,8 +1454,10 @@ void CWallet::KeepKey(int64 nIndex) void CWallet::ReturnKey(int64 nIndex) { // Return to key pool - CRITICAL_BLOCK(cs_wallet) + { + LOCK(cs_wallet); setKeyPool.insert(nIndex); + } printf("keypool return %"PRI64d"\n", nIndex); } @@ -1435,8 +1465,8 @@ bool CWallet::GetKeyFromPool(vector& result, bool fAllowReuse) { int64 nIndex = 0; CKeyPool keypool; - CRITICAL_BLOCK(cs_wallet) { + LOCK(cs_wallet); ReserveKeyFromKeyPool(nIndex, keypool); if (nIndex == -1) { @@ -1506,8 +1536,7 @@ void CWallet::GetAllReserveAddresses(set& setAddress) CWalletDB walletdb(strWalletFile); - CRITICAL_BLOCK(cs_main) - CRITICAL_BLOCK(cs_wallet) + LOCK2(cs_main, cs_wallet); BOOST_FOREACH(const int64& id, setKeyPool) { CKeyPool keypool;