diff options
author | Pieter Wuille <pieter.wuille@gmail.com> | 2014-09-03 09:01:24 +0200 |
---|---|---|
committer | Pieter Wuille <pieter.wuille@gmail.com> | 2014-09-23 22:29:12 +0200 |
commit | f28aec014edd29cfc669cf1c3f795c0f1e2ae7e2 (patch) | |
tree | 92c7e9e24f52b4294249b7eeee6e6e3525d1618a /src/coins.h | |
parent | 7a04f3d708faab4af1f1a6aeddc5a6a4db3849a5 (diff) |
Use ModifyCoins instead of mutable GetCoins.
Replace the mutable non-copying GetCoins method with a ModifyCoins, which
returns an encapsulated iterator, so we can keep track of concurrent
modifications (as iterators can be invalidated by those) and run cleanup
code after a modification is finished.
This also removes the overloading of the 'GetCoins' name.
Diffstat (limited to 'src/coins.h')
-rw-r--r-- | src/coins.h | 49 |
1 files changed, 45 insertions, 4 deletions
diff --git a/src/coins.h b/src/coins.h index bf61f55aac..62beea3c23 100644 --- a/src/coins.h +++ b/src/coins.h @@ -83,11 +83,26 @@ public: // as new tx version will probably only be introduced at certain heights int nVersion; - // construct a CCoins from a CTransaction, at a given height - CCoins(const CTransaction &tx, int nHeightIn) : fCoinBase(tx.IsCoinBase()), vout(tx.vout), nHeight(nHeightIn), nVersion(tx.nVersion) { + void FromTx(const CTransaction &tx, int nHeightIn) { + fCoinBase = tx.IsCoinBase(); + vout = tx.vout; + nHeight = nHeightIn; + nVersion = tx.nVersion; ClearUnspendable(); } + // construct a CCoins from a CTransaction, at a given height + CCoins(const CTransaction &tx, int nHeightIn) { + FromTx(tx, nHeightIn); + } + + void Clear() { + fCoinBase = false; + std::vector<CTxOut>().swap(vout); + nHeight = 0; + nVersion = 0; + } + // empty constructor CCoins() : fCoinBase(false), vout(0), nHeight(0), nVersion(0) { } @@ -323,10 +338,31 @@ public: }; +class CCoinsViewCache; + +/** A reference to a mutable cache entry. Encapsulating it allows us to run + * cleanup code after the modification is finished, and keeping track of + * concurrent modifications. */ +class CCoinsModifier +{ +private: + CCoinsViewCache& cache; + CCoinsMap::iterator it; + CCoinsModifier(CCoinsViewCache& cache_, CCoinsMap::iterator it_); + +public: + CCoins* operator->() { return &it->second; } + CCoins& operator*() { return it->second; } + ~CCoinsModifier(); + friend class CCoinsViewCache; +}; + /** CCoinsView that adds a memory cache for transactions to another CCoinsView */ class CCoinsViewCache : public CCoinsViewBacked { protected: + /* Whether this cache has an active modifier. */ + bool hasModifier; /* Make mutable so that we can "fill the cache" even from Get-methods declared as "const". */ @@ -335,6 +371,7 @@ protected: public: CCoinsViewCache(CCoinsView &baseIn, bool fDummy = false); + ~CCoinsViewCache(); // Standard CCoinsView methods bool GetCoins(const uint256 &txid, CCoins &coins) const; @@ -349,8 +386,10 @@ public: // allowed while accessing the returned pointer. const CCoins* AccessCoins(const uint256 &txid) const; - // Return a modifiable reference to a CCoins. Check HaveCoins first. - CCoins &GetCoins(const uint256 &txid); + // Return a modifiable reference to a CCoins. If no entry with the given + // txid exists, a new one is created. Simultaneous modifications are not + // allowed. + CCoinsModifier ModifyCoins(const uint256 &txid); // Push the modifications applied to this cache to its base. // Failure to call this method before destruction will cause the changes to be forgotten. @@ -377,6 +416,8 @@ public: const CTxOut &GetOutputFor(const CTxIn& input) const; + friend class CCoinsModifier; + private: CCoinsMap::iterator FetchCoins(const uint256 &txid); CCoinsMap::const_iterator FetchCoins(const uint256 &txid) const; |