diff options
author | Wladimir J. van der Laan <laanwj@gmail.com> | 2014-07-07 14:56:16 +0200 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@gmail.com> | 2014-07-07 16:06:28 +0200 |
commit | f748ff730b4570a19610db67aa9ded28ba98a8c5 (patch) | |
tree | 2fc11dfafa57ce4f675d29f8b5cddb98ea70f738 /src/wallet.h | |
parent | afe380ef0f1c70185fc7c50e1a75e589ff3382dd (diff) | |
parent | a3e192a3274817517671f624d5744297905e20d2 (diff) |
Merge pull request #4045
a3e192a replaced MINE_ with ISMINE_ (JaSK)
53a2148 fixed bug where validateaddress doesn't display information (JaSK)
f28707a fixed bug in ListReceived() (JaSK)
519dd1c Added MINE_ALL = (spendable|watchonly) (JaSK)
23b0506 Fixed some stuff in TransactionDesc (JaSK)
80dda36 removed default argument values for ismine filter (JaSK)
d5087d1 Use script matching rather than destination matching for watch-only. (Pieter Wuille)
0fa2f88 added includedWatchonly argument to listreceivedbyaddress/...account (JaSK)
f87ba3d added includeWatchonly argument to 'gettransaction' because it affects balance calculation (JaSK)
a5c6c5d fixed tiny glitch and improved readability like laanwj suggested (JaSK)
d7d5d23 Added argument to listtransactions and listsinceblock to include watchonly addresses (JaSK)
952877e Showing 'involvesWatchonly' property for transactions returned by 'listtransactions' and 'listsinceblock'. It is only appended when the transaction involves a watchonly address. (JaSK)
83f3543 Added argument to listaccounts to include watchonly addresses (JaSK)
d4640d7 Added argument to getbalance to include watchonly addresses and fixed errors in balance calculation. (JaSK)
d2692f6 Watchonly transactions are marked in transaction history (JaSK)
ffd40da Watchonly balances are shown separately in gui. (JaSK)
2935b21 qt: Hide unspendable outputs in coin control (Wladimir J. van der Laan)
c898846 Add support for watch-only addresses (Pieter Wuille)
Diffstat (limited to 'src/wallet.h')
-rw-r--r-- | src/wallet.h | 148 |
1 files changed, 120 insertions, 28 deletions
diff --git a/src/wallet.h b/src/wallet.h index 62f13e4630..ab9550a984 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -229,6 +229,11 @@ public: /// Look up a destination data tuple in the store, return true if found false otherwise bool GetDestData(const CTxDestination &dest, const std::string &key, std::string *value) const; + // 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); @@ -260,6 +265,9 @@ public: int64_t GetBalance() const; int64_t GetUnconfirmedBalance() const; int64_t GetImmatureBalance() const; + int64_t GetWatchOnlyBalance() const; + int64_t GetUnconfirmedWatchOnlyBalance() const; + int64_t GetImmatureWatchOnlyBalance() const; bool CreateTransaction(const std::vector<std::pair<CScript, int64_t> >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64_t& nFeeRet, std::string& strFailReason, const CCoinControl *coinControl = NULL); bool CreateTransaction(CScript scriptPubKey, int64_t nValue, @@ -284,17 +292,17 @@ public: std::set<CTxDestination> GetAccountAddresses(std::string strAccount) const; - bool IsMine(const CTxIn& txin) const; - int64_t GetDebit(const CTxIn& txin) const; - bool IsMine(const CTxOut& txout) const + isminetype IsMine(const CTxIn& txin) const; + int64_t GetDebit(const CTxIn& txin, const isminefilter& filter) const; + isminetype IsMine(const CTxOut& txout) const { return ::IsMine(*this, txout.scriptPubKey); } - int64_t GetCredit(const CTxOut& txout) const + int64_t 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_t GetChange(const CTxOut& txout) const @@ -310,9 +318,9 @@ public: return true; return false; } - bool IsFromMe(const CTransaction& tx) const + bool IsFromMe(const CTransaction& tx) const // should probably be renamed to IsRelevantToMe { - return (GetDebit(tx) > 0); + return (GetDebit(tx, ISMINE_ALL) > 0); } bool IsConflicting(const CTransaction& tx) const { @@ -321,23 +329,23 @@ public: return true; return false; } - int64_t GetDebit(const CTransaction& tx) const + int64_t GetDebit(const CTransaction& tx, const isminefilter& filter) const { int64_t 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_t GetCredit(const CTransaction& tx) const + int64_t GetCredit(const CTransaction& tx, const isminefilter& filter) const { int64_t 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"); } @@ -483,11 +491,19 @@ public: mutable bool fCreditCached; mutable bool fImmatureCreditCached; mutable bool fAvailableCreditCached; + mutable bool fWatchDebitCached; + mutable bool fWatchCreditCached; + mutable bool fImmatureWatchCreditCached; + mutable bool fAvailableWatchCreditCached; mutable bool fChangeCached; mutable int64_t nDebitCached; mutable int64_t nCreditCached; mutable int64_t nImmatureCreditCached; mutable int64_t nAvailableCreditCached; + mutable int64_t nWatchDebitCached; + mutable int64_t nWatchCreditCached; + mutable int64_t nImmatureWatchCreditCached; + mutable int64_t nAvailableWatchCreditCached; mutable int64_t nChangeCached; CWalletTx() @@ -524,11 +540,19 @@ public: fCreditCached = false; fImmatureCreditCached = false; fAvailableCreditCached = false; + fWatchDebitCached = false; + fWatchCreditCached = false; + fImmatureWatchCreditCached = false; + fAvailableWatchCreditCached = false; fChangeCached = false; nDebitCached = 0; nCreditCached = 0; nImmatureCreditCached = 0; nAvailableCreditCached = 0; + nWatchDebitCached = 0; + nWatchCreditCached = 0; + nAvailableWatchCreditCached = 0; + nImmatureWatchCreditCached = 0; nChangeCached = 0; nOrderPos = -1; } @@ -581,6 +605,10 @@ public: { fCreditCached = false; fAvailableCreditCached = false; + fWatchDebitCached = false; + fWatchCreditCached = false; + fAvailableWatchCreditCached = false; + fImmatureWatchCreditCached = false; fDebitCached = false; fChangeCached = false; } @@ -591,15 +619,36 @@ public: MarkDirty(); } - int64_t GetDebit() const + // filter decides which addresses will count towards the debit + int64_t GetDebit(const isminefilter& filter) const { if (vin.empty()) return 0; - if (fDebitCached) - return nDebitCached; - nDebitCached = pwallet->GetDebit(*this); - fDebitCached = true; - return nDebitCached; + + int64_t debit = 0; + if(filter & ISMINE_SPENDABLE) + { + if (fDebitCached) + debit += nDebitCached; + else + { + nDebitCached = pwallet->GetDebit(*this, ISMINE_SPENDABLE); + fDebitCached = true; + debit += nDebitCached; + } + } + if(filter & ISMINE_WATCH_ONLY) + { + if(fWatchDebitCached) + debit += nWatchDebitCached; + else + { + nWatchDebitCached = pwallet->GetDebit(*this, ISMINE_WATCH_ONLY); + fWatchDebitCached = true; + debit += nWatchDebitCached; + } + } + return debit; } int64_t GetCredit(bool fUseCache=true) const @@ -611,7 +660,7 @@ public: // GetBalance can assume transactions in mapWallet won't change if (fUseCache && fCreditCached) return nCreditCached; - nCreditCached = pwallet->GetCredit(*this); + nCreditCached = pwallet->GetCredit(*this, ISMINE_ALL); fCreditCached = true; return nCreditCached; } @@ -622,7 +671,7 @@ public: { if (fUseCache && fImmatureCreditCached) return nImmatureCreditCached; - nImmatureCreditCached = pwallet->GetCredit(*this); + nImmatureCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE); fImmatureCreditCached = true; return nImmatureCreditCached; } @@ -649,7 +698,7 @@ public: if (!pwallet->IsSpent(hashTx, i)) { const CTxOut &txout = vout[i]; - nCredit += pwallet->GetCredit(txout); + nCredit += pwallet->GetCredit(txout, ISMINE_SPENDABLE); if (!MoneyRange(nCredit)) throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range"); } @@ -660,6 +709,48 @@ public: return nCredit; } + int64_t GetImmatureWatchOnlyCredit(const bool& fUseCache=true) const + { + if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain()) + { + if (fUseCache && fImmatureWatchCreditCached) + return nImmatureWatchCreditCached; + nImmatureWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY); + fImmatureWatchCreditCached = true; + return nImmatureWatchCreditCached; + } + + return 0; + } + + int64_t GetAvailableWatchOnlyCredit(const bool& fUseCache=true) const + { + if (pwallet == 0) + return 0; + + // Must wait until coinbase is safely deep enough in the chain before valuing it + if (IsCoinBase() && GetBlocksToMaturity() > 0) + return 0; + + if (fUseCache && fAvailableWatchCreditCached) + return nAvailableWatchCreditCached; + + int64_t nCredit = 0; + for (unsigned int i = 0; i < vout.size(); i++) + { + if (!pwallet->IsSpent(GetHash(), i)) + { + const CTxOut &txout = vout[i]; + nCredit += pwallet->GetCredit(txout, ISMINE_WATCH_ONLY); + if (!MoneyRange(nCredit)) + throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range"); + } + } + + nAvailableWatchCreditCached = nCredit; + fAvailableWatchCreditCached = true; + return nCredit; + } int64_t GetChange() const { @@ -671,14 +762,14 @@ public: } void GetAmounts(std::list<std::pair<CTxDestination, int64_t> >& listReceived, - std::list<std::pair<CTxDestination, int64_t> >& listSent, int64_t& nFee, std::string& strSentAccount) const; + std::list<std::pair<CTxDestination, int64_t> >& listSent, int64_t& nFee, std::string& strSentAccount, const isminefilter& filter) const; void GetAccountAmounts(const std::string& strAccount, int64_t& nReceived, - int64_t& nSent, int64_t& nFee) const; + int64_t& nSent, int64_t& nFee, const isminefilter& filter) const; - bool IsFromMe() const + bool IsFromMe(const isminefilter& filter) const { - return (GetDebit() > 0); + return (GetDebit(filter) > 0); } bool IsTrusted() const @@ -691,7 +782,7 @@ public: return true; if (nDepth < 0) return false; - if (!bSpendZeroConfChange || !IsFromMe()) // using wtx's cached debit + if (!bSpendZeroConfChange || !IsFromMe(ISMINE_ALL)) // using wtx's cached debit return false; // Trusted if all inputs are from us and are in the mempool: @@ -702,7 +793,7 @@ public: if (parent == NULL) return false; const CTxOut& parentOut = parent->vout[txin.prevout.n]; - if (!pwallet->IsMine(parentOut)) + if (pwallet->IsMine(parentOut) != ISMINE_SPENDABLE) return false; } return true; @@ -727,10 +818,11 @@ 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 |