diff options
author | Gavin Andresen <gavinandresen@gmail.com> | 2011-04-12 13:31:44 -0400 |
---|---|---|
committer | Gavin Andresen <gavinandresen@gmail.com> | 2011-04-12 13:31:44 -0400 |
commit | 2e8b33824f4bd76efd84837335eeb8a025787b4b (patch) | |
tree | 8343ed061a3a49617124a18e74756e40739c1164 /main.h | |
parent | d12ea887bcf1eab4b029007c4bf5821992c0c6b1 (diff) | |
parent | aca3f961dbce34e460dc02d37969b2035d5b2260 (diff) |
Merge branch 'spentpertxout' of https://github.com/sipa/bitcoin
Diffstat (limited to 'main.h')
-rw-r--r-- | main.h | 124 |
1 files changed, 115 insertions, 9 deletions
@@ -738,6 +738,7 @@ public: fMerkleVerified = false; } + IMPLEMENT_SERIALIZE ( nSerSize += SerReadWrite(s, *(CTransaction*)this, nType, nVersion, ser_action); @@ -774,15 +775,17 @@ public: unsigned int fTimeReceivedIsTxTime; unsigned int nTimeReceived; // time received by this node char fFromMe; - char fSpent; string strFromAccount; + vector<char> vfSpent; // memory only mutable char fDebitCached; mutable char fCreditCached; + mutable char fAvailableCreditCached; mutable char fChangeCached; mutable int64 nDebitCached; mutable int64 nCreditCached; + mutable int64 nAvailableCreditCached; mutable int64 nChangeCached; // memory only UI hints @@ -814,13 +817,15 @@ public: fTimeReceivedIsTxTime = false; nTimeReceived = 0; fFromMe = false; - fSpent = false; strFromAccount.clear(); + vfSpent.clear(); fDebitCached = false; fCreditCached = false; + fAvailableCreditCached = false; fChangeCached = false; nDebitCached = 0; nCreditCached = 0; + nAvailableCreditCached = 0; nChangeCached = 0; nTimeDisplayed = 0; nLinesDisplayed = 0; @@ -832,22 +837,96 @@ public: CWalletTx* pthis = const_cast<CWalletTx*>(this); if (fRead) pthis->Init(); - nSerSize += SerReadWrite(s, *(CMerkleTx*)this, nType, nVersion, ser_action); - READWRITE(vtxPrev); + char fSpent = false; - pthis->mapValue["fromaccount"] = pthis->strFromAccount; - READWRITE(mapValue); - pthis->strFromAccount = pthis->mapValue["fromaccount"]; - pthis->mapValue.erase("fromaccount"); - pthis->mapValue.erase("version"); + if (!fRead) + { + pthis->mapValue["fromaccount"] = pthis->strFromAccount; + + string str; + foreach(char f, vfSpent) + { + str += (f ? '1' : '0'); + if (f) + fSpent = true; + } + pthis->mapValue["spent"] = str; + } + nSerSize += SerReadWrite(s, *(CMerkleTx*)this, nType, nVersion,ser_action); + READWRITE(vtxPrev); + READWRITE(mapValue); READWRITE(vOrderForm); READWRITE(fTimeReceivedIsTxTime); READWRITE(nTimeReceived); READWRITE(fFromMe); READWRITE(fSpent); + + if (fRead) + { + pthis->strFromAccount = pthis->mapValue["fromaccount"]; + + if (mapValue.count("spent")) + foreach(char c, pthis->mapValue["spent"]) + pthis->vfSpent.push_back(c != '0'); + else + pthis->vfSpent.assign(vout.size(), fSpent); + } + + pthis->mapValue.erase("fromaccount"); + pthis->mapValue.erase("version"); + pthis->mapValue.erase("spent"); ) + // marks certain txout's as spent + // returns true if any update took place + bool UpdateSpent(const vector<char>& vfNewSpent) + { + bool fReturn = false; + for (int i=0; i < vfNewSpent.size(); i++) + { + if (i == vfSpent.size()) + break; + + if (vfNewSpent[i] && !vfSpent[i]) + { + vfSpent[i] = true; + fReturn = true; + fAvailableCreditCached = false; + } + } + return fReturn; + } + + void MarkDirty() + { + fCreditCached = false; + fAvailableCreditCached = false; + fDebitCached = false; + fChangeCached = false; + } + + void MarkSpent(unsigned int nOut) + { + if (nOut >= vout.size()) + throw runtime_error("CWalletTx::MarkSpent() : nOut out of range"); + vfSpent.resize(vout.size()); + if (!vfSpent[nOut]) + { + vfSpent[nOut] = true; + fAvailableCreditCached = false; + } + } + + bool IsSpent(unsigned int nOut) const + { + if (nOut >= vout.size()) + throw runtime_error("CWalletTx::IsSpent() : nOut out of range"); + if (nOut >= vfSpent.size()) + return false; + return (!!vfSpent[nOut]); + } + int64 GetDebit() const { if (vin.empty()) @@ -873,6 +952,33 @@ public: return nCreditCached; } + int64 GetAvailableCredit(bool fUseCache=true) const + { + // Must wait until coinbase is safely deep enough in the chain before valuing it + if (IsCoinBase() && GetBlocksToMaturity() > 0) + return 0; + + if (fUseCache && fAvailableCreditCached) + return nAvailableCreditCached; + + int64 nCredit = 0; + for (int i = 0; i < vout.size(); i++) + { + if (!IsSpent(i)) + { + const CTxOut &txout = vout[i]; + nCredit += txout.GetCredit(); + if (!MoneyRange(nCredit)) + throw runtime_error("CWalletTx::GetAvailableCredit() : value out of range"); + } + } + + nAvailableCreditCached = nCredit; + fAvailableCreditCached = true; + return nCredit; + } + + int64 GetChange() const { if (fChangeCached) |