X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fwallet.h;h=cb07d3959324bd4cf4ed844f82081c531dfb4f94;hb=b0368da0e15b5506548da3462e14b038ca21ae69;hp=39cd1ceae67e7fc09f84cd2f696c4ca7eed45512;hpb=9d519fcff4e11f4e770c350fa69c302aed881b01;p=novacoin.git diff --git a/src/wallet.h b/src/wallet.h index 39cd1ce..cb07d39 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 @@ -35,14 +37,6 @@ enum WalletFeature 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 +70,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 +127,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 +149,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 CTxDestination &dest); + // Adds a watch-only address to the store, without saving it to disk (used by LoadWallet) + bool LoadWatchOnly(const CTxDestination &dest); + bool Unlock(const SecureString& strWalletPassphrase); bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase); bool EncryptWallet(const SecureString& strWalletPassphrase); @@ -178,28 +179,30 @@ 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; + void GetBalance(int64 &nTotal, int64 &nWatchOnly) const; int64 GetUnconfirmedBalance() const; int64 GetImmatureBalance() 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); + 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); 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 +214,20 @@ public: std::set< std::set > GetAddressGroupings(); std::map GetAddressBalances(); - bool IsMine(const CTxIn& txin) const; + isminetype IsMine(const CTxIn& txin) const; int64 GetDebit(const CTxIn& txin) const; - bool IsMine(const CTxOut& txout) const + isminetype IsMine(const CTxOut& txout) const { return ::IsMine(*this, txout.scriptPubKey); } - int64 GetCredit(const CTxOut& txout) const + int64 GetCredit(const CTxOut& txout, bool fWatchOnly=false) const { if (!MoneyRange(txout.nValue)) throw std::runtime_error("CWallet::GetCredit() : value out of range"); - return (IsMine(txout) ? txout.nValue : 0); + isminetype ismine = IsMine(txout); + if (fWatchOnly && ismine != MINE_WATCH_ONLY) + return 0; + return (ismine != MINE_NO ? txout.nValue : 0); } bool IsChange(const CTxOut& txout) const; int64 GetChange(const CTxOut& txout) const @@ -233,7 +239,7 @@ 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; } @@ -252,12 +258,14 @@ public: } return nDebit; } - int64 GetCredit(const CTransaction& tx) const + int64 GetCredit(const CTransaction& tx, bool fWatchOnly=true) const { int64 nCredit = 0; BOOST_FOREACH(const CTxOut& txout, tx.vout) { - nCredit += GetCredit(txout); + if (!fWatchOnly || (fWatchOnly && IsMine(txout) == MINE_WATCH_ONLY)) + nCredit += GetCredit(txout); + if (!MoneyRange(nCredit)) throw std::runtime_error("CWallet::GetCredit() : value out of range"); } @@ -296,7 +304,7 @@ public: } } - int GetKeyPoolSize() + unsigned int GetKeyPoolSize() { return setKeyPool.size(); } @@ -399,11 +407,15 @@ public: // memory only mutable bool fDebitCached; mutable bool fCreditCached; + mutable bool fWatchOnlyCreditCached; mutable bool fAvailableCreditCached; + mutable bool fAvailableWatchOnlyCreditCached; mutable bool fChangeCached; mutable int64 nDebitCached; mutable int64 nCreditCached; + mutable int64 nWatchOnlyCreditCached; mutable int64 nAvailableCreditCached; + mutable int64 nAvailableWatchOnlyCreditCached; mutable int64 nChangeCached; CWalletTx() @@ -440,11 +452,15 @@ public: vfSpent.clear(); fDebitCached = false; fCreditCached = false; + fWatchOnlyCreditCached = false; fAvailableCreditCached = false; + fAvailableWatchOnlyCreditCached = false; fChangeCached = false; nDebitCached = 0; nCreditCached = 0; + nWatchOnlyCreditCached = 0; nAvailableCreditCached = 0; + nAvailableWatchOnlyCreditCached = 0; nChangeCached = 0; nOrderPos = -1; } @@ -520,7 +536,7 @@ public: { vfSpent[i] = true; fReturn = true; - fAvailableCreditCached = false; + fAvailableCreditCached = fAvailableWatchOnlyCreditCached = false; } } return fReturn; @@ -530,7 +546,7 @@ public: void MarkDirty() { fCreditCached = false; - fAvailableCreditCached = false; + fAvailableCreditCached = fAvailableWatchOnlyCreditCached = false; fDebitCached = false; fChangeCached = false; } @@ -549,7 +565,7 @@ public: if (!vfSpent[nOut]) { vfSpent[nOut] = true; - fAvailableCreditCached = false; + fAvailableCreditCached = fAvailableWatchOnlyCreditCached = false; } } @@ -561,7 +577,7 @@ public: if (vfSpent[nOut]) { vfSpent[nOut] = false; - fAvailableCreditCached = false; + fAvailableCreditCached = fAvailableWatchOnlyCreditCached = false; } } @@ -585,28 +601,46 @@ public: return nDebitCached; } - int64 GetCredit(bool fUseCache=true) const + int64 GetCredit(bool fWatchOnly, 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; // GetBalance can assume transactions in mapWallet won't change - if (fUseCache && fCreditCached) - return nCreditCached; + if (fUseCache) { + if (fWatchOnly && fCreditCached) + return nWatchOnlyCreditCached; + if (fCreditCached) + return nCreditCached; + } + + if (fWatchOnly) { + nWatchOnlyCreditCached = pwallet->GetCredit(*this, true); + fWatchOnlyCreditCached = true; + + return nWatchOnlyCreditCached; + } + nCreditCached = pwallet->GetCredit(*this); fCreditCached = true; + return nCreditCached; } - int64 GetAvailableCredit(bool fUseCache=true) const + int64 GetAvailableCredit(bool fWatchOnly, 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 (fWatchOnly && fAvailableWatchOnlyCreditCached) + return nAvailableWatchOnlyCreditCached; + + if (fAvailableCreditCached) + return nAvailableCreditCached; + } int64 nCredit = 0; for (unsigned int i = 0; i < vout.size(); i++) @@ -614,14 +648,19 @@ public: if (!IsSpent(i)) { const CTxOut &txout = vout[i]; - nCredit += pwallet->GetCredit(txout); + nCredit += pwallet->GetCredit(txout, fWatchOnly); if (!MoneyRange(nCredit)) throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range"); } } - nAvailableCreditCached = nCredit; - fAvailableCreditCached = true; + if (fWatchOnly) { + nAvailableWatchOnlyCreditCached = nCredit; + fAvailableWatchOnlyCreditCached = true; + } else { + nAvailableCreditCached = nCredit; + fAvailableCreditCached = true; + } return nCredit; } @@ -646,14 +685,14 @@ public: return (GetDebit() > 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()) // using wtx's cached debit return false; // If no confirmations but it's from us, we can still @@ -686,6 +725,7 @@ public: vWorkQueue.push_back(mapPrev[txin.prevout.hash]); } } + return true; } @@ -712,15 +752,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