99
1010#include < assert.h>
1111
12+ using namespace CFund ;
13+
1214/* *
1315 * calculate number of bytes for the bitmask, and its number of non-zero bytes
1416 * each bit in the bitmask represents the availability of one output, but the
@@ -42,18 +44,34 @@ bool CCoins::Spend(uint32_t nPos)
4244}
4345
4446bool CCoinsView::GetCoins (const uint256 &txid, CCoins &coins) const { return false ; }
47+ bool CCoinsView::GetProposal (const uint256 &pid, CProposal &proposal) const { return false ; }
48+ bool CCoinsView::GetAllProposals (CProposalMap& map) { return false ; }
49+ bool CCoinsView::GetPaymentRequest (const uint256 &prid, CPaymentRequest &prequest) const { return false ; }
50+ bool CCoinsView::GetAllPaymentRequests (CPaymentRequestMap& map) { return false ; }
4551bool CCoinsView::HaveCoins (const uint256 &txid) const { return false ; }
52+ bool CCoinsView::HaveProposal (const uint256 &pid) const { return false ; }
53+ bool CCoinsView::HavePaymentRequest (const uint256 &prid) const { return false ; }
4654uint256 CCoinsView::GetBestBlock () const { return uint256 (); }
47- bool CCoinsView::BatchWrite (CCoinsMap &mapCoins, const uint256 &hashBlock) { return false ; }
55+ bool CCoinsView::BatchWrite (CCoinsMap &mapCoins, CProposalMap &mapProposals,
56+ CPaymentRequestMap &mapPaymentRequests, const uint256 &hashBlock) { return false ; }
4857CCoinsViewCursor *CCoinsView::Cursor () const { return 0 ; }
4958
5059
5160CCoinsViewBacked::CCoinsViewBacked (CCoinsView *viewIn) : base(viewIn) { }
5261bool CCoinsViewBacked::GetCoins (const uint256 &txid, CCoins &coins) const { return base->GetCoins (txid, coins); }
62+ bool CCoinsViewBacked::GetProposal (const uint256 &pid, CProposal &proposal) const { return base->GetProposal (pid, proposal); }
63+ bool CCoinsViewBacked::GetAllProposals (CProposalMap& map) { return base->GetAllProposals (map); }
64+ bool CCoinsViewBacked::GetPaymentRequest (const uint256 &prid, CPaymentRequest &prequest) const { return base->GetPaymentRequest (prid, prequest); }
65+ bool CCoinsViewBacked::GetAllPaymentRequests (CPaymentRequestMap& map) { return base->GetAllPaymentRequests (map); }
5366bool CCoinsViewBacked::HaveCoins (const uint256 &txid) const { return base->HaveCoins (txid); }
67+ bool CCoinsViewBacked::HaveProposal (const uint256 &pid) const { return base->HaveProposal (pid); }
68+ bool CCoinsViewBacked::HavePaymentRequest (const uint256 &prid) const { return base->HavePaymentRequest (prid); }
5469uint256 CCoinsViewBacked::GetBestBlock () const { return base->GetBestBlock (); }
5570void CCoinsViewBacked::SetBackend (CCoinsView &viewIn) { base = &viewIn; }
56- bool CCoinsViewBacked::BatchWrite (CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite (mapCoins, hashBlock); }
71+ bool CCoinsViewBacked::BatchWrite (CCoinsMap &mapCoins, CProposalMap &mapProposals,
72+ CPaymentRequestMap &mapPaymentRequests, const uint256 &hashBlock) {
73+ return base->BatchWrite (mapCoins, mapProposals, mapPaymentRequests, hashBlock);
74+ }
5775CCoinsViewCursor *CCoinsViewBacked::Cursor () const { return base->Cursor (); }
5876
5977SaltedTxidHasher::SaltedTxidHasher () : k0(GetRand(std::numeric_limits<uint64_t >::max())), k1(GetRand(std::numeric_limits<uint64_t >::max())) {}
@@ -87,6 +105,41 @@ CCoinsMap::const_iterator CCoinsViewCache::FetchCoins(const uint256 &txid) const
87105 return ret;
88106}
89107
108+ CProposalMap::const_iterator CCoinsViewCache::FetchProposal (const uint256 &pid) const {
109+ CProposalMap::iterator it = cacheProposals.find (pid);
110+
111+ if (it != cacheProposals.end ())
112+ return it;
113+
114+ CProposal tmp;
115+
116+ if (!base->GetProposal (pid, tmp))
117+ return cacheProposals.end ();
118+
119+ CProposalMap::iterator ret = cacheProposals.insert (std::make_pair (pid, CProposal ())).first ;
120+ tmp.swap (ret->second );
121+
122+ return ret;
123+ }
124+
125+ CPaymentRequestMap::const_iterator CCoinsViewCache::FetchPaymentRequest (const uint256 &prid) const {
126+ CPaymentRequestMap::iterator it = cachePaymentRequests.find (prid);
127+
128+ if (it != cachePaymentRequests.end ())
129+ return it;
130+
131+ CPaymentRequest tmp;
132+
133+ if (!base->GetPaymentRequest (prid, tmp))
134+ return cachePaymentRequests.end ();
135+
136+ CPaymentRequestMap::iterator ret = cachePaymentRequests.insert (std::make_pair (prid, CPaymentRequest ())).first ;
137+ tmp.swap (ret->second );
138+
139+ return ret;
140+ }
141+
142+
90143bool CCoinsViewCache::GetCoins (const uint256 &txid, CCoins &coins) const {
91144 CCoinsMap::const_iterator it = FetchCoins (txid);
92145 if (it != cacheCoins.end ()) {
@@ -96,6 +149,54 @@ bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) const {
96149 return false ;
97150}
98151
152+ bool CCoinsViewCache::GetProposal (const uint256 &pid, CProposal &proposal) const {
153+ CProposalMap::const_iterator it = FetchProposal (pid);
154+ if (it != cacheProposals.end ()) {
155+ proposal = it->second ;
156+ return true ;
157+ }
158+ return false ;
159+ }
160+
161+ bool CCoinsViewCache::GetAllProposals (CProposalMap& mapProposal) {
162+ mapProposal.clear ();
163+ mapProposal.insert (cacheProposals.begin (), cacheProposals.end ());
164+
165+ CProposalMap baseMap;
166+
167+ if (!base->GetAllProposals (baseMap))
168+ return false ;
169+
170+ for (CProposalMap::iterator it = baseMap.begin (); it != baseMap.end (); it++)
171+ mapProposal.insert (make_pair (it->first , it->second ));
172+
173+ return true ;
174+ }
175+
176+ bool CCoinsViewCache::GetPaymentRequest (const uint256 &pid, CPaymentRequest &prequest) const {
177+ CPaymentRequestMap::const_iterator it = FetchPaymentRequest (pid);
178+ if (it != cachePaymentRequests.end ()) {
179+ prequest = it->second ;
180+ return true ;
181+ }
182+ return false ;
183+ }
184+
185+ bool CCoinsViewCache::GetAllPaymentRequests (CPaymentRequestMap& mapPaymentRequests) {
186+ mapPaymentRequests.clear ();
187+ mapPaymentRequests.insert (cachePaymentRequests.begin (), cachePaymentRequests.end ());
188+
189+ CPaymentRequestMap baseMap;
190+
191+ if (!base->GetAllPaymentRequests (baseMap))
192+ return false ;
193+
194+ for (CPaymentRequestMap::iterator it = baseMap.begin (); it != baseMap.end (); it++)
195+ mapPaymentRequests.insert (make_pair (it->first , it->second ));
196+
197+ return true ;
198+ }
199+
99200CCoinsModifier CCoinsViewCache::ModifyCoins (const uint256 &txid) {
100201 assert (!hasModifier);
101202 std::pair<CCoinsMap::iterator, bool > ret = cacheCoins.insert (std::make_pair (txid, CCoinsCacheEntry ()));
@@ -117,6 +218,20 @@ CCoinsModifier CCoinsViewCache::ModifyCoins(const uint256 &txid) {
117218 return CCoinsModifier (*this , ret.first , cachedCoinUsage);
118219}
119220
221+ CProposalModifier CCoinsViewCache::ModifyProposal (const uint256 &pid) {
222+ assert (!hasModifier);
223+ std::pair<CProposalMap::iterator, bool > ret = cacheProposals.insert (std::make_pair (pid, CProposal ()));
224+ ret.first ->second .fDirty = true ;
225+ return CProposalModifier (*this , ret.first );
226+ }
227+
228+ CPaymentRequestModifier CCoinsViewCache::ModifyPaymentRequest (const uint256 &prid) {
229+ assert (!hasModifier);
230+ std::pair<CPaymentRequestMap::iterator, bool > ret = cachePaymentRequests.insert (std::make_pair (prid, CPaymentRequest ()));
231+ ret.first ->second .fDirty = true ;
232+ return CPaymentRequestModifier (*this , ret.first );
233+ }
234+
120235// ModifyNewCoins has to know whether the new outputs its creating are for a
121236// coinbase or not. If they are for a coinbase, it can not mark them as fresh.
122237// This is to ensure that the historical duplicate coinbases before BIP30 was
@@ -132,6 +247,46 @@ CCoinsModifier CCoinsViewCache::ModifyNewCoins(const uint256 &txid, bool coinbas
132247 return CCoinsModifier (*this , ret.first , 0 );
133248}
134249
250+ bool CCoinsViewCache::AddProposal (const CProposal& proposal) const {
251+ if (HaveProposal (proposal.hash ))
252+ return false ;
253+
254+ cacheProposals.insert (std::make_pair (proposal.hash , proposal));
255+
256+ return true ;
257+ }
258+
259+ bool CCoinsViewCache::AddPaymentRequest (const CPaymentRequest& prequest) const {
260+ if (HavePaymentRequest (prequest.hash ))
261+ return false ;
262+ cachePaymentRequests.insert (std::make_pair (prequest.hash , prequest));
263+ return true ;
264+ }
265+
266+ bool CCoinsViewCache::RemoveProposal (const uint256 &pid) const {
267+ if (!HaveProposal (pid))
268+ return false ;
269+
270+ cacheProposals[pid] = CProposal ();
271+ cacheProposals[pid].SetNull ();
272+
273+ assert (cacheProposals[pid].IsNull ());
274+
275+ return true ;
276+ }
277+
278+ bool CCoinsViewCache::RemovePaymentRequest (const uint256 &prid) const {
279+ if (!HavePaymentRequest (prid))
280+ return false ;
281+
282+ cachePaymentRequests[prid] = CPaymentRequest ();
283+ cachePaymentRequests[prid].SetNull ();
284+
285+ assert (cachePaymentRequests[prid].IsNull ());
286+
287+ return true ;
288+ }
289+
135290const CCoins* CCoinsViewCache::AccessCoins (const uint256 &txid) const {
136291 CCoinsMap::const_iterator it = FetchCoins (txid);
137292 if (it == cacheCoins.end ()) {
@@ -150,6 +305,16 @@ bool CCoinsViewCache::HaveCoins(const uint256 &txid) const {
150305 return (it != cacheCoins.end () && !it->second .coins .vout .empty ());
151306}
152307
308+ bool CCoinsViewCache::HaveProposal (const uint256 &id) const {
309+ CProposalMap::const_iterator it = FetchProposal (id);
310+ return (it != cacheProposals.end () && !it->second .IsNull ());
311+ }
312+
313+ bool CCoinsViewCache::HavePaymentRequest (const uint256 &id) const {
314+ CPaymentRequestMap::const_iterator it = FetchPaymentRequest (id);
315+ return (it != cachePaymentRequests.end () && !it->second .IsNull ());
316+ }
317+
153318bool CCoinsViewCache::HaveCoinsInCache (const uint256 &txid) const {
154319 CCoinsMap::const_iterator it = cacheCoins.find (txid);
155320 return it != cacheCoins.end ();
@@ -165,7 +330,7 @@ void CCoinsViewCache::SetBestBlock(const uint256 &hashBlockIn) {
165330 hashBlock = hashBlockIn;
166331}
167332
168- bool CCoinsViewCache::BatchWrite (CCoinsMap &mapCoins, const uint256 &hashBlockIn) {
333+ bool CCoinsViewCache::BatchWrite (CCoinsMap &mapCoins, CProposalMap &mapProposals, CPaymentRequestMap &mapPaymentRequests, const uint256 &hashBlockIn) {
169334 assert (!hasModifier);
170335 for (CCoinsMap::iterator it = mapCoins.begin (); it != mapCoins.end ();) {
171336 if (it->second .flags & CCoinsCacheEntry::DIRTY) { // Ignore non-dirty entries (optimization).
@@ -206,12 +371,41 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn
206371 CCoinsMap::iterator itOld = it++;
207372 mapCoins.erase (itOld);
208373 }
374+
375+ for (CProposalMap::iterator it = mapProposals.begin (); it != mapProposals.end ();) {
376+ if (it->second .IsNull ()) {
377+ CProposalMap::iterator itUs = cacheProposals.find (it->first );
378+ if (itUs != cacheProposals.end ()) {
379+ cacheProposals.erase (itUs);
380+ }
381+ } else {
382+ CProposal& entry = cacheProposals[it->first ];
383+ entry.swap (it->second );
384+ }
385+ CProposalMap::iterator itOld = it++;
386+ mapProposals.erase (itOld);
387+ }
388+
389+ for (CPaymentRequestMap::iterator it = mapPaymentRequests.begin (); it != mapPaymentRequests.end ();) {
390+ if (it->second .IsNull ()) {
391+ CPaymentRequestMap::iterator itUs = cachePaymentRequests.find (it->first );
392+ if (itUs != cachePaymentRequests.end ()) {
393+ cachePaymentRequests.erase (itUs);
394+ }
395+ } else {
396+ CPaymentRequest& entry = cachePaymentRequests[it->first ];
397+ entry.swap (it->second );
398+ }
399+ CPaymentRequestMap::iterator itOld = it++;
400+ mapPaymentRequests.erase (itOld);
401+ }
402+
209403 hashBlock = hashBlockIn;
210404 return true ;
211405}
212406
213407bool CCoinsViewCache::Flush () {
214- bool fOk = base->BatchWrite (cacheCoins, hashBlock);
408+ bool fOk = base->BatchWrite (cacheCoins, cacheProposals, cachePaymentRequests, hashBlock);
215409 cacheCoins.clear ();
216410 cachedCoinsUsage = 0 ;
217411 return fOk ;
@@ -301,6 +495,36 @@ CCoinsModifier::~CCoinsModifier()
301495 }
302496}
303497
498+ CProposalModifier::CProposalModifier (CCoinsViewCache& cache_, CProposalMap::iterator it_) : cache(cache_), it(it_) {
499+ assert (!cache.hasModifier );
500+ cache.hasModifier = true ;
501+ }
502+
503+ CProposalModifier::~CProposalModifier ()
504+ {
505+ assert (cache.hasModifier );
506+ cache.hasModifier = false ;
507+
508+ if (it->second .IsNull ()) {
509+ cache.cacheProposals .erase (it);
510+ }
511+ }
512+
513+ CPaymentRequestModifier::CPaymentRequestModifier (CCoinsViewCache& cache_, CPaymentRequestMap::iterator it_) : cache(cache_), it(it_) {
514+ assert (!cache.hasModifier );
515+ cache.hasModifier = true ;
516+ }
517+
518+ CPaymentRequestModifier::~CPaymentRequestModifier ()
519+ {
520+ assert (cache.hasModifier );
521+ cache.hasModifier = false ;
522+
523+ if (it->second .IsNull ()) {
524+ cache.cachePaymentRequests .erase (it);
525+ }
526+ }
527+
304528CCoinsViewCursor::~CCoinsViewCursor ()
305529{
306530}
0 commit comments