X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fwallet.h;h=26c49ea617d31df926ca6205739dc864bbec19e5;hb=9167b228998e353585d2d5e45826d57dfddf534e;hp=39cd1ceae67e7fc09f84cd2f696c4ca7eed45512;hpb=9d519fcff4e11f4e770c350fa69c302aed881b01;p=novacoin.git diff --git a/src/wallet.h b/src/wallet.h index 39cd1ce..26c49ea 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -19,10 +19,12 @@ #include "walletdb.h" extern bool fWalletUnlockMintOnly; +extern bool fConfChange; class CAccountingEntry; class CWalletTx; class CReserveKey; class COutput; +class CCoinControl; /** (client) version numbers for particular wallet features */ enum WalletFeature @@ -31,18 +33,9 @@ enum WalletFeature FEATURE_WALLETCRYPT = 40000, // wallet encryption FEATURE_COMPRPUBKEY = 60000, // compressed public keys - FEATURE_LATEST = 60000 }; -/** Stake weight calculation mode */ -enum StakeWeightMode -{ - STAKE_NORMAL = 0, // all 30+ days old inputs - STAKE_MAXWEIGHT = 1, // only 90+ days old inputs - STAKE_MINWEIGHT = 3 // only [30-90] days old inputs -}; - /** A key pool entry */ class CKeyPool { @@ -76,7 +69,8 @@ public: class CWallet : public CCryptoKeyStore { private: - bool SelectCoins(int64 nTargetValue, unsigned int nSpendTime, std::set >& setCoinsRet, int64& nValueRet) const; + bool SelectCoinsSimple(int64 nTargetValue, unsigned int nSpendTime, int nMinConf, std::set >& setCoinsRet, int64& nValueRet) const; + bool SelectCoins(int64 nTargetValue, unsigned int nSpendTime, std::set >& setCoinsRet, int64& nValueRet, const CCoinControl *coinControl=NULL) const; CWalletDB *pwalletdbEncryption; @@ -132,7 +126,8 @@ public: // check whether we are allowed to upgrade (or already support) to the named feature bool CanSupportFeature(enum WalletFeature wf) { return nWalletMaxVersion >= wf; } - void AvailableCoins(std::vector& vCoins, bool fOnlyConfirmed=true) const; + void AvailableCoinsMinConf(std::vector& vCoins, int nConf) const; + void AvailableCoins(std::vector& vCoins, bool fOnlyConfirmed=true, const CCoinControl *coinControl=NULL) const; bool SelectCoinsMinConf(int64 nTargetValue, unsigned int nSpendTime, int nConfMine, int nConfTheirs, std::vector vCoins, std::set >& setCoinsRet, int64& nValueRet) const; // keystore implementation // Generate a new key @@ -153,6 +148,11 @@ public: bool AddCScript(const CScript& redeemScript); bool LoadCScript(const CScript& redeemScript) { return CCryptoKeyStore::AddCScript(redeemScript); } + // Adds a watch-only address to the store, and saves it to disk. + bool AddWatchOnly(const CScript &dest); + // Adds a watch-only address to the store, without saving it to disk (used by LoadWallet) + bool LoadWatchOnly(const CScript &dest); + bool Unlock(const SecureString& strWalletPassphrase); bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase); bool EncryptWallet(const SecureString& strWalletPassphrase); @@ -178,28 +178,35 @@ public: 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); + void WalletUpdateSpent(const CTransaction& prevout, bool fBlock = false); int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false); int ScanForWalletTransaction(const uint256& hashTx); void ReacceptWalletTransactions(); void ResendWalletTransactions(); int64 GetBalance() const; + int64 GetWatchOnlyBalance() const; int64 GetUnconfirmedBalance() const; + int64 GetUnconfirmedWatchOnlyBalance() const; int64 GetImmatureBalance() const; + int64 GetImmatureWatchOnlyBalance() const; int64 GetStake() const; int64 GetNewMint() 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); + int64 GetWatchOnlyStake() const; + int64 GetWatchOnlyNewMint() const; + bool CreateTransaction(const std::vector >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet, const CCoinControl *coinControl=NULL); + bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet, const CCoinControl *coinControl=NULL); bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey); - uint64 GetStakeWeight(const CKeyStore& keystore, enum StakeWeightMode mode=STAKE_NORMAL); - bool CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int64 nSearchInterval, CTransaction& txNew); + bool GetStakeWeight(const CKeyStore& keystore, uint64& nMinWeight, uint64& nMaxWeight, uint64& nWeight); + void GetStakeWeightFromValue(const int64& nTime, const int64& nValue, uint64& nWeight); + bool CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int64 nSearchInterval, CTransaction& txNew, CKey& key); + bool MergeCoins(const int64& nAmount, const int64& nMaxValue, const int64& nOutputValue, list& listMerged); std::string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); std::string SendMoneyToDestination(const CTxDestination &address, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); bool NewKeyPool(); - bool TopUpKeyPool(); + bool TopUpKeyPool(unsigned int nSize = 0); int64 AddReserveKey(const CKeyPool& keypool); void ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool); void KeepKey(int64 nIndex); @@ -211,17 +218,17 @@ public: std::set< std::set > GetAddressGroupings(); std::map GetAddressBalances(); - bool IsMine(const CTxIn& txin) const; - int64 GetDebit(const CTxIn& txin) const; - bool IsMine(const CTxOut& txout) const + isminetype IsMine(const CTxIn& txin) const; + int64 GetDebit(const CTxIn& txin, const isminefilter& filter) const; + isminetype IsMine(const CTxOut& txout) const { return ::IsMine(*this, txout.scriptPubKey); } - int64 GetCredit(const CTxOut& txout) const + int64 GetCredit(const CTxOut& txout, const isminefilter& filter) const { if (!MoneyRange(txout.nValue)) throw std::runtime_error("CWallet::GetCredit() : value out of range"); - return (IsMine(txout) ? txout.nValue : 0); + return (IsMine(txout) & filter ? txout.nValue : 0); } bool IsChange(const CTxOut& txout) const; int64 GetChange(const CTxOut& txout) const @@ -233,31 +240,31 @@ public: bool IsMine(const CTransaction& tx) const { BOOST_FOREACH(const CTxOut& txout, tx.vout) - if (IsMine(txout)) + if (IsMine(txout) && txout.nValue >= nMinimumInputValue) return true; return false; } bool IsFromMe(const CTransaction& tx) const { - return (GetDebit(tx) > 0); + return (GetDebit(tx, MINE_ALL) > 0); } - int64 GetDebit(const CTransaction& tx) const + int64 GetDebit(const CTransaction& tx, const isminefilter& filter) const { int64 nDebit = 0; BOOST_FOREACH(const CTxIn& txin, tx.vin) { - nDebit += GetDebit(txin); + nDebit += GetDebit(txin, filter); if (!MoneyRange(nDebit)) throw std::runtime_error("CWallet::GetDebit() : value out of range"); } return nDebit; } - int64 GetCredit(const CTransaction& tx) const + int64 GetCredit(const CTransaction& tx, const isminefilter& filter) const { int64 nCredit = 0; BOOST_FOREACH(const CTxOut& txout, tx.vout) { - nCredit += GetCredit(txout); + nCredit += GetCredit(txout, filter); if (!MoneyRange(nCredit)) throw std::runtime_error("CWallet::GetCredit() : value out of range"); } @@ -296,7 +303,7 @@ public: } } - int GetKeyPoolSize() + unsigned int GetKeyPoolSize() { return setKeyPool.size(); } @@ -398,12 +405,22 @@ public: // memory only mutable bool fDebitCached; + mutable bool fWatchDebitCached; mutable bool fCreditCached; + mutable bool fWatchCreditCached; mutable bool fAvailableCreditCached; + mutable bool fImmatureCreditCached; + mutable bool fImmatureWatchCreditCached; + mutable bool fAvailableWatchCreditCached; mutable bool fChangeCached; mutable int64 nDebitCached; + mutable int64 nWatchDebitCached; mutable int64 nCreditCached; + mutable int64 nWatchCreditCached; mutable int64 nAvailableCreditCached; + mutable int64 nImmatureCreditCached; + mutable int64 nImmatureWatchCreditCached; + mutable int64 nAvailableWatchCreditCached; mutable int64 nChangeCached; CWalletTx() @@ -439,12 +456,18 @@ public: strFromAccount.clear(); vfSpent.clear(); fDebitCached = false; + fWatchDebitCached = false; fCreditCached = false; + fWatchCreditCached = false; fAvailableCreditCached = false; + fAvailableWatchCreditCached = false; fChangeCached = false; nDebitCached = 0; + nWatchDebitCached = 0; nCreditCached = 0; + nWatchCreditCached = 0; nAvailableCreditCached = 0; + nAvailableWatchCreditCached = 0; nChangeCached = 0; nOrderPos = -1; } @@ -520,7 +543,7 @@ public: { vfSpent[i] = true; fReturn = true; - fAvailableCreditCached = false; + fAvailableCreditCached = fAvailableWatchCreditCached = false; } } return fReturn; @@ -530,8 +553,8 @@ public: void MarkDirty() { fCreditCached = false; - fAvailableCreditCached = false; - fDebitCached = false; + fAvailableCreditCached = fAvailableWatchCreditCached = false; + fDebitCached = fWatchDebitCached = false; fChangeCached = false; } @@ -549,7 +572,7 @@ public: if (!vfSpent[nOut]) { vfSpent[nOut] = true; - fAvailableCreditCached = false; + fAvailableCreditCached = fAvailableWatchCreditCached = false; } } @@ -561,7 +584,7 @@ public: if (vfSpent[nOut]) { vfSpent[nOut] = false; - fAvailableCreditCached = false; + fAvailableCreditCached = fAvailableWatchCreditCached = false; } } @@ -574,15 +597,36 @@ public: return (!!vfSpent[nOut]); } - int64 GetDebit() const + int64 GetDebit(const isminefilter& filter) const { if (vin.empty()) return 0; - if (fDebitCached) - return nDebitCached; - nDebitCached = pwallet->GetDebit(*this); - fDebitCached = true; - return nDebitCached; + + int64 nDebit = 0; + if (filter & MINE_SPENDABLE) + { + if (fDebitCached) + nDebit += nDebitCached; + else + { + nDebitCached = pwallet->GetDebit(*this, MINE_SPENDABLE); + fDebitCached = true; + nDebit += nDebitCached; + } + } + if (filter & MINE_WATCH_ONLY) + { + if (fWatchDebitCached) + nDebit += nWatchDebitCached; + else + { + nWatchDebitCached = pwallet->GetDebit(*this, MINE_WATCH_ONLY); + fWatchDebitCached = true; + nDebit += nWatchDebitCached; + } + } + + return nDebit; } int64 GetCredit(bool fUseCache=true) const @@ -592,21 +636,56 @@ public: return 0; // GetBalance can assume transactions in mapWallet won't change - if (fUseCache && fCreditCached) - return nCreditCached; - nCreditCached = pwallet->GetCredit(*this); + if (fUseCache) { + if (fCreditCached) + return nCreditCached; + } + + nCreditCached = pwallet->GetCredit(*this, MINE_ALL); fCreditCached = true; + return nCreditCached; } + int64 GetImmatureCredit(bool fUseCache=true) const + { + if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain()) + { + if (fUseCache && fImmatureCreditCached) + return nImmatureCreditCached; + nImmatureCreditCached = pwallet->GetCredit(*this, MINE_SPENDABLE); + fImmatureCreditCached = true; + return nImmatureCreditCached; + } + + return 0; + } + + int64 GetImmatureWatchOnlyCredit(bool fUseCache=true) const + { + if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain()) + { + if (fUseCache && fImmatureWatchCreditCached) + return nImmatureWatchCreditCached; + nImmatureWatchCreditCached = pwallet->GetCredit(*this, MINE_WATCH_ONLY); + fImmatureWatchCreditCached = true; + return nImmatureWatchCreditCached; + } + + return 0; + } + + int64 GetAvailableCredit(bool fUseCache=true) const { // Must wait until coinbase is safely deep enough in the chain before valuing it if ((IsCoinBase() || IsCoinStake()) && GetBlocksToMaturity() > 0) return 0; - if (fUseCache && fAvailableCreditCached) - return nAvailableCreditCached; + if (fUseCache) { + if (fAvailableCreditCached) + return nAvailableCreditCached; + } int64 nCredit = 0; for (unsigned int i = 0; i < vout.size(); i++) @@ -614,7 +693,7 @@ public: if (!IsSpent(i)) { const CTxOut &txout = vout[i]; - nCredit += pwallet->GetCredit(txout); + nCredit += pwallet->GetCredit(txout, MINE_SPENDABLE); if (!MoneyRange(nCredit)) throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range"); } @@ -622,9 +701,38 @@ public: nAvailableCreditCached = nCredit; fAvailableCreditCached = true; + return nCredit; } + int64 GetAvailableWatchCredit(bool fUseCache=true) const + { + // Must wait until coinbase is safely deep enough in the chain before valuing it + if ((IsCoinBase() || IsCoinStake()) && GetBlocksToMaturity() > 0) + return 0; + + if (fUseCache) { + if (fAvailableWatchCreditCached) + return nAvailableWatchCreditCached; + } + + int64 nCredit = 0; + for (unsigned int i = 0; i < vout.size(); i++) + { + if (!IsSpent(i)) + { + const CTxOut &txout = vout[i]; + nCredit += pwallet->GetCredit(txout, MINE_WATCH_ONLY); + if (!MoneyRange(nCredit)) + throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range"); + } + } + + nAvailableWatchCreditCached = nCredit; + fAvailableWatchCreditCached = true; + + return nCredit; + } int64 GetChange() const { @@ -636,24 +744,24 @@ public: } void GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, std::list >& listReceived, - std::list >& listSent, int64& nFee, std::string& strSentAccount) const; + std::list >& listSent, int64& nFee, std::string& strSentAccount, const isminefilter& filter) const; void GetAccountAmounts(const std::string& strAccount, int64& nGenerated, int64& nReceived, - int64& nSent, int64& nFee) const; + int64& nSent, int64& nFee, const isminefilter& filter) const; - bool IsFromMe() const + bool IsFromMe(const isminefilter& filter) const { - return (GetDebit() > 0); + return (GetDebit(filter) > 0); } - bool IsConfirmed() const + bool IsTrusted() const { // Quick answer in most cases if (!IsFinal()) return false; if (GetDepthInMainChain() >= 1) return true; - if (!IsFromMe()) // using wtx's cached debit + if (fConfChange || !IsFromMe(MINE_ALL)) // using wtx's cached debit return false; // If no confirmations but it's from us, we can still @@ -686,6 +794,7 @@ public: vWorkQueue.push_back(mapPrev[txin.prevout.hash]); } } + return true; } @@ -712,15 +821,16 @@ public: const CWalletTx *tx; int i; int nDepth; + bool fSpendable; - COutput(const CWalletTx *txIn, int iIn, int nDepthIn) + COutput(const CWalletTx *txIn, int iIn, int nDepthIn, bool fSpendableIn) { - tx = txIn; i = iIn; nDepth = nDepthIn; + tx = txIn; i = iIn; nDepth = nDepthIn; fSpendable = fSpendableIn; } std::string ToString() const { - return strprintf("COutput(%s, %d, %d) [%s]", tx->GetHash().ToString().substr(0,10).c_str(), i, nDepth, FormatMoney(tx->vout[i].nValue).c_str()); + return strprintf("COutput(%s, %d, %d, %d) [%s]", tx->GetHash().ToString().substr(0,10).c_str(), i, fSpendable, nDepth, FormatMoney(tx->vout[i].nValue).c_str()); } void print() const