@@ -42,52 +42,51 @@ bool CCoins::Spend(uint32_t nPos)
42
42
return true ;
43
43
}
44
44
45
- bool CCoinsView::GetCoins (const uint256 &txid, CCoins &coins ) const { return false ; }
46
- bool CCoinsView::HaveCoins (const uint256 &txid ) const { return false ; }
45
+ bool CCoinsView::GetCoins (const COutPoint &outpoint, Coin &coin ) const { return false ; }
46
+ bool CCoinsView::HaveCoins (const COutPoint &outpoint ) const { return false ; }
47
47
uint256 CCoinsView::GetBestBlock () const { return uint256 (); }
48
48
bool CCoinsView::BatchWrite (CCoinsMap &mapCoins, const uint256 &hashBlock) { return false ; }
49
49
CCoinsViewCursor *CCoinsView::Cursor () const { return 0 ; }
50
50
51
51
52
52
CCoinsViewBacked::CCoinsViewBacked (CCoinsView *viewIn) : base(viewIn) { }
53
- bool CCoinsViewBacked::GetCoins (const uint256 &txid, CCoins &coins ) const { return base->GetCoins (txid, coins ); }
54
- bool CCoinsViewBacked::HaveCoins (const uint256 &txid ) const { return base->HaveCoins (txid ); }
53
+ bool CCoinsViewBacked::GetCoins (const COutPoint &outpoint, Coin &coin ) const { return base->GetCoins (outpoint, coin ); }
54
+ bool CCoinsViewBacked::HaveCoins (const COutPoint &outpoint ) const { return base->HaveCoins (outpoint ); }
55
55
uint256 CCoinsViewBacked::GetBestBlock () const { return base->GetBestBlock (); }
56
56
void CCoinsViewBacked::SetBackend (CCoinsView &viewIn) { base = &viewIn; }
57
57
bool CCoinsViewBacked::BatchWrite (CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite (mapCoins, hashBlock); }
58
58
CCoinsViewCursor *CCoinsViewBacked::Cursor () const { return base->Cursor (); }
59
59
size_t CCoinsViewBacked::EstimateSize () const { return base->EstimateSize (); }
60
60
61
- SaltedTxidHasher::SaltedTxidHasher () : k0(GetRand(std::numeric_limits<uint64_t >::max())), k1(GetRand(std::numeric_limits<uint64_t >::max())) {}
61
+ SaltedOutpointHasher::SaltedOutpointHasher () : k0(GetRand(std::numeric_limits<uint64_t >::max())), k1(GetRand(std::numeric_limits<uint64_t >::max())) {}
62
62
63
- CCoinsViewCache::CCoinsViewCache (CCoinsView *baseIn) : CCoinsViewBacked(baseIn), cachedCoinsUsage(0 ) { }
63
+ CCoinsViewCache::CCoinsViewCache (CCoinsView *baseIn) : CCoinsViewBacked(baseIn), cachedCoinsUsage(0 ) {}
64
64
65
65
size_t CCoinsViewCache::DynamicMemoryUsage () const {
66
66
return memusage::DynamicUsage (cacheCoins) + cachedCoinsUsage;
67
67
}
68
68
69
- CCoinsMap::iterator CCoinsViewCache::FetchCoins (const uint256 &txid ) const {
70
- CCoinsMap::iterator it = cacheCoins.find (txid );
69
+ CCoinsMap::iterator CCoinsViewCache::FetchCoins (const COutPoint &outpoint ) const {
70
+ CCoinsMap::iterator it = cacheCoins.find (outpoint );
71
71
if (it != cacheCoins.end ())
72
72
return it;
73
- CCoins tmp;
74
- if (!base->GetCoins (txid , tmp))
73
+ Coin tmp;
74
+ if (!base->GetCoins (outpoint , tmp))
75
75
return cacheCoins.end ();
76
- CCoinsMap::iterator ret = cacheCoins.insert (std::make_pair (txid, CCoinsCacheEntry ())).first ;
77
- tmp.swap (ret->second .coins );
76
+ CCoinsMap::iterator ret = cacheCoins.emplace (std::piecewise_construct, std::forward_as_tuple (outpoint), std::forward_as_tuple (std::move (tmp))).first ;
78
77
if (ret->second .coins .IsPruned ()) {
79
- // The parent only has an empty entry for this txid ; we can consider our
78
+ // The parent only has an empty entry for this outpoint ; we can consider our
80
79
// version as fresh.
81
80
ret->second .flags = CCoinsCacheEntry::FRESH;
82
81
}
83
82
cachedCoinsUsage += ret->second .coins .DynamicMemoryUsage ();
84
83
return ret;
85
84
}
86
85
87
- bool CCoinsViewCache::GetCoins (const uint256 &txid, CCoins &coins ) const {
88
- CCoinsMap::const_iterator it = FetchCoins (txid );
86
+ bool CCoinsViewCache::GetCoins (const COutPoint &outpoint, Coin &coin ) const {
87
+ CCoinsMap::const_iterator it = FetchCoins (outpoint );
89
88
if (it != cacheCoins.end ()) {
90
- coins = it->second .coins ;
89
+ coin = it->second .coins ;
91
90
return true ;
92
91
}
93
92
return false ;
@@ -98,23 +97,18 @@ void CCoinsViewCache::AddCoin(const COutPoint &outpoint, Coin&& coin, bool possi
98
97
if (coin.out .scriptPubKey .IsUnspendable ()) return ;
99
98
CCoinsMap::iterator it;
100
99
bool inserted;
101
- std::tie (it, inserted) = cacheCoins.emplace (std::piecewise_construct, std::forward_as_tuple (outpoint. hash ), std::tuple<>());
100
+ std::tie (it, inserted) = cacheCoins.emplace (std::piecewise_construct, std::forward_as_tuple (outpoint), std::tuple<>());
102
101
bool fresh = false ;
103
102
if (!inserted) {
104
103
cachedCoinsUsage -= it->second .coins .DynamicMemoryUsage ();
105
104
}
106
105
if (!possible_overwrite) {
107
- if (it->second .coins .IsAvailable (outpoint. n )) {
106
+ if (! it->second .coins .IsPruned ( )) {
108
107
throw std::logic_error (" Adding new coin that replaces non-pruned entry" );
109
108
}
110
- fresh = it-> second . coins . IsPruned () && !(it->second .flags & CCoinsCacheEntry::DIRTY);
109
+ fresh = !(it->second .flags & CCoinsCacheEntry::DIRTY);
111
110
}
112
- if (it->second .coins .vout .size () <= outpoint.n ) {
113
- it->second .coins .vout .resize (outpoint.n + 1 );
114
- }
115
- it->second .coins .vout [outpoint.n ] = std::move (coin.out );
116
- it->second .coins .nHeight = coin.nHeight ;
117
- it->second .coins .fCoinBase = coin.fCoinBase ;
111
+ it->second .coins = std::move (coin);
118
112
it->second .flags |= CCoinsCacheEntry::DIRTY | (fresh ? CCoinsCacheEntry::FRESH : 0 );
119
113
cachedCoinsUsage += it->second .coins .DynamicMemoryUsage ();
120
114
}
@@ -130,58 +124,38 @@ void AddCoins(CCoinsViewCache& cache, const CTransaction &tx, int nHeight) {
130
124
}
131
125
132
126
void CCoinsViewCache::SpendCoin (const COutPoint &outpoint, Coin* moveout) {
133
- CCoinsMap::iterator it = FetchCoins (outpoint. hash );
127
+ CCoinsMap::iterator it = FetchCoins (outpoint);
134
128
if (it == cacheCoins.end ()) return ;
135
129
cachedCoinsUsage -= it->second .coins .DynamicMemoryUsage ();
136
- if (moveout && it-> second . coins . IsAvailable (outpoint. n ) ) {
137
- *moveout = Coin (it->second .coins . vout [outpoint. n ], it-> second . coins . nHeight , it-> second . coins . fCoinBase );
130
+ if (moveout) {
131
+ *moveout = std::move (it->second .coins );
138
132
}
139
- it->second .coins .Spend (outpoint.n ); // Ignore return value: SpendCoin has no effect if no UTXO found.
140
- if (it->second .coins .IsPruned () && it->second .flags & CCoinsCacheEntry::FRESH) {
133
+ if (it->second .flags & CCoinsCacheEntry::FRESH) {
141
134
cacheCoins.erase (it);
142
135
} else {
143
- cachedCoinsUsage += it->second .coins .DynamicMemoryUsage ();
144
136
it->second .flags |= CCoinsCacheEntry::DIRTY;
145
- }
146
- }
147
-
148
- const CCoins* CCoinsViewCache::AccessCoins (const uint256 &txid) const {
149
- CCoinsMap::const_iterator it = FetchCoins (txid);
150
- if (it == cacheCoins.end ()) {
151
- return NULL ;
152
- } else {
153
- return &it->second .coins ;
137
+ it->second .coins .Clear ();
154
138
}
155
139
}
156
140
157
141
static const Coin coinEmpty;
158
142
159
- const Coin CCoinsViewCache::AccessCoin (const COutPoint &outpoint) const {
160
- CCoinsMap::const_iterator it = FetchCoins (outpoint. hash );
161
- if (it == cacheCoins.end () || !it-> second . coins . IsAvailable (outpoint. n ) ) {
143
+ const Coin& CCoinsViewCache::AccessCoin (const COutPoint &outpoint) const {
144
+ CCoinsMap::const_iterator it = FetchCoins (outpoint);
145
+ if (it == cacheCoins.end ()) {
162
146
return coinEmpty;
163
147
} else {
164
- return Coin ( it->second .coins . vout [outpoint. n ], it-> second . coins . nHeight , it-> second . coins . fCoinBase ) ;
148
+ return it->second .coins ;
165
149
}
166
150
}
167
151
168
-
169
- bool CCoinsViewCache::HaveCoins (const uint256 &txid) const {
170
- CCoinsMap::const_iterator it = FetchCoins (txid);
171
- // We're using vtx.empty() instead of IsPruned here for performance reasons,
172
- // as we only care about the case where a transaction was replaced entirely
173
- // in a reorganization (which wipes vout entirely, as opposed to spending
174
- // which just cleans individual outputs).
175
- return (it != cacheCoins.end () && !it->second .coins .vout .empty ());
176
- }
177
-
178
152
bool CCoinsViewCache::HaveCoins (const COutPoint &outpoint) const {
179
- CCoinsMap::const_iterator it = FetchCoins (outpoint. hash );
180
- return (it != cacheCoins.end () && it->second .coins .IsAvailable (outpoint. n ));
153
+ CCoinsMap::const_iterator it = FetchCoins (outpoint);
154
+ return (it != cacheCoins.end () && ! it->second .coins .IsPruned ( ));
181
155
}
182
156
183
- bool CCoinsViewCache::HaveCoinsInCache (const uint256 &txid ) const {
184
- CCoinsMap::const_iterator it = cacheCoins.find (txid );
157
+ bool CCoinsViewCache::HaveCoinsInCache (const COutPoint &outpoint ) const {
158
+ CCoinsMap::const_iterator it = cacheCoins.find (outpoint );
185
159
return it != cacheCoins.end ();
186
160
}
187
161
@@ -206,7 +180,7 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn
206
180
// Otherwise we will need to create it in the parent
207
181
// and move the data up and mark it as dirty
208
182
CCoinsCacheEntry& entry = cacheCoins[it->first ];
209
- entry.coins . swap (it->second .coins );
183
+ entry.coins = std::move (it->second .coins );
210
184
cachedCoinsUsage += entry.coins .DynamicMemoryUsage ();
211
185
entry.flags = CCoinsCacheEntry::DIRTY;
212
186
// We can mark it FRESH in the parent if it was FRESH in the child
@@ -233,7 +207,7 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn
233
207
} else {
234
208
// A normal modification.
235
209
cachedCoinsUsage -= itUs->second .coins .DynamicMemoryUsage ();
236
- itUs->second .coins . swap (it->second .coins );
210
+ itUs->second .coins = std::move (it->second .coins );
237
211
cachedCoinsUsage += itUs->second .coins .DynamicMemoryUsage ();
238
212
itUs->second .flags |= CCoinsCacheEntry::DIRTY;
239
213
// NOTE: It is possible the child has a FRESH flag here in
@@ -258,7 +232,7 @@ bool CCoinsViewCache::Flush() {
258
232
return fOk ;
259
233
}
260
234
261
- void CCoinsViewCache::Uncache (const uint256 & hash)
235
+ void CCoinsViewCache::Uncache (const COutPoint & hash)
262
236
{
263
237
CCoinsMap::iterator it = cacheCoins.find (hash);
264
238
if (it != cacheCoins.end () && it->second .flags == 0 ) {
@@ -273,9 +247,9 @@ unsigned int CCoinsViewCache::GetCacheSize() const {
273
247
274
248
const CTxOut &CCoinsViewCache::GetOutputFor (const CTxIn& input) const
275
249
{
276
- const CCoins* coins = AccessCoins (input.prevout . hash );
277
- assert (coins && coins-> IsAvailable (input. prevout . n ));
278
- return coins-> vout [input. prevout . n ] ;
250
+ const Coin& coin = AccessCoin (input.prevout );
251
+ assert (!coin. IsPruned ( ));
252
+ return coin. out ;
279
253
}
280
254
281
255
CAmount CCoinsViewCache::GetValueIn (const CTransaction& tx) const
@@ -294,23 +268,17 @@ bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const
294
268
{
295
269
if (!tx.IsCoinBase ()) {
296
270
for (unsigned int i = 0 ; i < tx.vin .size (); i++) {
297
- const COutPoint &prevout = tx.vin [i].prevout ;
298
- const CCoins* coins = AccessCoins (prevout.hash );
299
- if (!coins || !coins->IsAvailable (prevout.n )) {
271
+ if (!HaveCoins (tx.vin [i].prevout )) {
300
272
return false ;
301
273
}
302
274
}
303
275
}
304
276
return true ;
305
277
}
306
278
307
- CCoinsViewCursor::~CCoinsViewCursor ()
308
- {
309
- }
310
-
311
279
static const size_t MAX_OUTPUTS_PER_BLOCK = MAX_BLOCK_BASE_SIZE / ::GetSerializeSize(CTxOut(), SER_NETWORK, PROTOCOL_VERSION); // TODO: merge with similar definition in undo.h.
312
280
313
- const Coin AccessByTxid (const CCoinsViewCache& view, const uint256& txid)
281
+ const Coin& AccessByTxid (const CCoinsViewCache& view, const uint256& txid)
314
282
{
315
283
COutPoint iter (txid, 0 );
316
284
while (iter.n < MAX_OUTPUTS_PER_BLOCK) {
0 commit comments