X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fwallet.h;h=3fdef50c0332b9563d7b81c737d4cae120e72d97;hb=882164196e5b1971313493f95a6d027f05e2ec92;hp=f9d2ea0989a91d9e90ef4f7cfb59c17c2fbc83c9;hpb=e89b9f6a2abaa120ff0fc3cea9ae364e8cbd25e4;p=novacoin.git diff --git a/src/wallet.h b/src/wallet.h index f9d2ea0..3fdef50 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -1,44 +1,237 @@ -// Copyright (c) 2009-2011 Satoshi Nakamoto & Bitcoin developers +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers // Distributed under the MIT/X11 software license, see the accompanying // file license.txt or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_WALLET_H #define BITCOIN_WALLET_H #include "bignum.h" +#include "key.h" +#include "keystore.h" #include "script.h" class CWalletTx; class CReserveKey; class CWalletDB; -extern std::map mapWallet; -extern std::vector vWalletUpdated; -extern CCriticalSection cs_mapWallet; +// A CWallet is an extension of a keystore, which also maintains a set of +// transactions and balances, and provides the ability to create new +// transactions +class CWallet : public CCryptoKeyStore +{ +private: + bool SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfTheirs, std::set >& setCoinsRet, int64& nValueRet) const; + bool SelectCoins(int64 nTargetValue, std::set >& setCoinsRet, int64& nValueRet) const; -extern std::map mapRequestCount; -extern CCriticalSection cs_mapRequestCount; + CWalletDB *pwalletdbEncryption; -extern std::map mapAddressBook; -extern CCriticalSection cs_mapAddressBook; +public: + mutable CCriticalSection cs_wallet; -extern std::vector vchDefaultKey; -extern CKey keyUser; + bool fFileBacked; + std::string strWalletFile; -bool AddToWallet(const CWalletTx& wtxIn); -bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate = false); -bool EraseFromWallet(uint256 hash); -void WalletUpdateSpent(const COutPoint& prevout); -int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false); -void ReacceptWalletTransactions(); -void ResendWalletTransactions(); -int64 GetBalance(); -bool CreateTransaction(const std::vector >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet); -bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet); -bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey); -bool BroadcastTransaction(CWalletTx& wtxNew); -std::string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); -std::string SendMoneyToBitcoinAddress(std::string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); + std::set setKeyPool; + typedef std::map MasterKeyMap; + MasterKeyMap mapMasterKeys; + unsigned int nMasterKeyMaxID; + + CWallet() + { + fFileBacked = false; + nMasterKeyMaxID = 0; + pwalletdbEncryption = NULL; + } + CWallet(std::string strWalletFileIn) + { + strWalletFile = strWalletFileIn; + fFileBacked = true; + nMasterKeyMaxID = 0; + pwalletdbEncryption = NULL; + } + + std::map mapWallet; + std::vector vWalletUpdated; + + std::map mapRequestCount; + + std::map mapAddressBook; + + std::vector vchDefaultKey; + + // keystore implementation + // Adds a key to the store, and saves it to disk. + bool AddKey(const CKey& key); + // Adds a key to the store, without saving it to disk (used by LoadWallet) + bool LoadKey(const CKey& key) { return CCryptoKeyStore::AddKey(key); } + + // Adds an encrypted key to the store, and saves it to disk. + bool AddCryptedKey(const std::vector &vchPubKey, const std::vector &vchCryptedSecret); + // Adds an encrypted key to the store, without saving it to disk (used by LoadWallet) + bool LoadCryptedKey(const std::vector &vchPubKey, const std::vector &vchCryptedSecret) { return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret); } + bool AddCScript(const CScript& redeemScript); + bool LoadCScript(const CScript& redeemScript) { return CCryptoKeyStore::AddCScript(redeemScript); } + + bool Unlock(const SecureString& strWalletPassphrase); + bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase); + bool EncryptWallet(const SecureString& strWalletPassphrase); + + void MarkDirty(); + bool AddToWallet(const CWalletTx& wtxIn); + bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate = false, bool fFindBlock = false); + bool EraseFromWallet(uint256 hash); + void WalletUpdateSpent(const CTransaction& prevout); + int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false); + int ScanForWalletTransaction(const uint256& hashTx); + void ReacceptWalletTransactions(); + void ResendWalletTransactions(); + int64 GetBalance() const; + int64 GetUnconfirmedBalance() const; + bool CreateTransaction(const std::vector >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet); + bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet); + bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey); + std::string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); + std::string SendMoneyToBitcoinAddress(const CBitcoinAddress& address, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); + + bool NewKeyPool(); + bool TopUpKeyPool(); + int64 AddReserveKey(const CKeyPool& keypool); + void ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool); + void KeepKey(int64 nIndex); + void ReturnKey(int64 nIndex); + bool GetKeyFromPool(std::vector &key, bool fAllowReuse=true); + int64 GetOldestKeyPoolTime(); + void GetAllReserveAddresses(std::set& setAddress); + + bool IsMine(const CTxIn& txin) const; + int64 GetDebit(const CTxIn& txin) const; + bool IsMine(const CTxOut& txout) const + { + return ::IsMine(*this, txout.scriptPubKey); + } + int64 GetCredit(const CTxOut& txout) const + { + if (!MoneyRange(txout.nValue)) + throw std::runtime_error("CWallet::GetCredit() : value out of range"); + return (IsMine(txout) ? txout.nValue : 0); + } + bool IsChange(const CTxOut& txout) const; + int64 GetChange(const CTxOut& txout) const + { + if (!MoneyRange(txout.nValue)) + throw std::runtime_error("CWallet::GetChange() : value out of range"); + return (IsChange(txout) ? txout.nValue : 0); + } + bool IsMine(const CTransaction& tx) const + { + BOOST_FOREACH(const CTxOut& txout, tx.vout) + if (IsMine(txout)) + return true; + return false; + } + bool IsFromMe(const CTransaction& tx) const + { + return (GetDebit(tx) > 0); + } + int64 GetDebit(const CTransaction& tx) const + { + int64 nDebit = 0; + BOOST_FOREACH(const CTxIn& txin, tx.vin) + { + nDebit += GetDebit(txin); + if (!MoneyRange(nDebit)) + throw std::runtime_error("CWallet::GetDebit() : value out of range"); + } + return nDebit; + } + int64 GetCredit(const CTransaction& tx) const + { + int64 nCredit = 0; + BOOST_FOREACH(const CTxOut& txout, tx.vout) + { + nCredit += GetCredit(txout); + if (!MoneyRange(nCredit)) + throw std::runtime_error("CWallet::GetCredit() : value out of range"); + } + return nCredit; + } + int64 GetChange(const CTransaction& tx) const + { + int64 nChange = 0; + BOOST_FOREACH(const CTxOut& txout, tx.vout) + { + nChange += GetChange(txout); + if (!MoneyRange(nChange)) + throw std::runtime_error("CWallet::GetChange() : value out of range"); + } + return nChange; + } + void SetBestChain(const CBlockLocator& loc) + { + CWalletDB walletdb(strWalletFile); + walletdb.WriteBestBlock(loc); + } + + int LoadWallet(bool& fFirstRunRet); +// bool BackupWallet(const std::string& strDest); + + bool SetAddressBookName(const CBitcoinAddress& address, const std::string& strName); + + bool DelAddressBookName(const CBitcoinAddress& address); + + void UpdatedTransaction(const uint256 &hashTx) + { + CRITICAL_BLOCK(cs_wallet) + vWalletUpdated.push_back(hashTx); + } + + void PrintWallet(const CBlock& block); + + void Inventory(const uint256 &hash) + { + CRITICAL_BLOCK(cs_wallet) + { + std::map::iterator mi = mapRequestCount.find(hash); + if (mi != mapRequestCount.end()) + (*mi).second++; + } + } + + int GetKeyPoolSize() + { + return setKeyPool.size(); + } + + bool GetTransaction(const uint256 &hashTx, CWalletTx& wtx); + + bool SetDefaultKey(const std::vector &vchPubKey); +}; + + +class CReserveKey +{ +protected: + CWallet* pwallet; + int64 nIndex; + std::vector vchPubKey; +public: + CReserveKey(CWallet* pwalletIn) + { + nIndex = -1; + pwallet = pwalletIn; + } + + ~CReserveKey() + { + if (!fShutdown) + ReturnKey(); + } + + void ReturnKey(); + std::vector GetReservedKey(); + void KeepKey(); +}; // @@ -48,6 +241,9 @@ std::string SendMoneyToBitcoinAddress(std::string strAddress, int64 nValue, CWal // class CWalletTx : public CMerkleTx { +private: + const CWallet* pwallet; + public: std::vector vtxPrev; std::map mapValue; @@ -56,7 +252,7 @@ public: unsigned int nTimeReceived; // time received by this node char fFromMe; std::string strFromAccount; - std::vector vfSpent; + std::vector vfSpent; // which outputs are already spent // memory only mutable char fDebitCached; @@ -73,24 +269,29 @@ public: mutable int nLinesDisplayed; mutable char fConfirmedDisplayed; - CWalletTx() { - Init(); + Init(NULL); + } + + CWalletTx(const CWallet* pwalletIn) + { + Init(pwalletIn); } - CWalletTx(const CMerkleTx& txIn) : CMerkleTx(txIn) + CWalletTx(const CWallet* pwalletIn, const CMerkleTx& txIn) : CMerkleTx(txIn) { - Init(); + Init(pwalletIn); } - CWalletTx(const CTransaction& txIn) : CMerkleTx(txIn) + CWalletTx(const CWallet* pwalletIn, const CTransaction& txIn) : CMerkleTx(txIn) { - Init(); + Init(pwalletIn); } - void Init() + void Init(const CWallet* pwalletIn) { + pwallet = pwalletIn; vtxPrev.clear(); mapValue.clear(); vOrderForm.clear(); @@ -116,7 +317,7 @@ public: ( CWalletTx* pthis = const_cast(this); if (fRead) - pthis->Init(); + pthis->Init(NULL); char fSpent = false; if (!fRead) @@ -178,6 +379,7 @@ public: return fReturn; } + // make sure balances are recalculated void MarkDirty() { fCreditCached = false; @@ -186,6 +388,12 @@ public: fChangeCached = false; } + void BindWallet(CWallet *pwalletIn) + { + pwallet = pwalletIn; + MarkDirty(); + } + void MarkSpent(unsigned int nOut) { if (nOut >= vout.size()) @@ -213,7 +421,7 @@ public: return 0; if (fDebitCached) return nDebitCached; - nDebitCached = CTransaction::GetDebit(); + nDebitCached = pwallet->GetDebit(*this); fDebitCached = true; return nDebitCached; } @@ -227,7 +435,7 @@ public: // GetBalance can assume transactions in mapWallet won't change if (fUseCache && fCreditCached) return nCreditCached; - nCreditCached = CTransaction::GetCredit(); + nCreditCached = pwallet->GetCredit(*this); fCreditCached = true; return nCreditCached; } @@ -247,7 +455,7 @@ public: if (!IsSpent(i)) { const CTxOut &txout = vout[i]; - nCredit += txout.GetCredit(); + nCredit += pwallet->GetCredit(txout); if (!MoneyRange(nCredit)) throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range"); } @@ -263,15 +471,15 @@ public: { if (fChangeCached) return nChangeCached; - nChangeCached = CTransaction::GetChange(); + nChangeCached = pwallet->GetChange(*this); fChangeCached = true; return nChangeCached; } - void GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, std::list >& listReceived, - std::list >& listSent, int64& nFee, std::string& strSentAccount) const; + void GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, std::list >& listReceived, + std::list >& listSent, int64& nFee, std::string& strSentAccount) const; - void GetAccountAmounts(const std::string& strAccount, int64& nGenerated, int64& nReceived, + void GetAccountAmounts(const std::string& strAccount, int64& nGenerated, int64& nReceived, int64& nSent, int64& nFee) const; bool IsFromMe() const @@ -303,7 +511,7 @@ public: return false; if (ptx->GetDepthInMainChain() >= 1) continue; - if (!ptx->IsFromMe()) + if (!pwallet->IsFromMe(*ptx)) return false; if (mapPrev.empty()) @@ -438,4 +646,6 @@ public: ) }; +bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut); + #endif