@@ -24,14 +24,14 @@ struct DBVal {
2424 uint64_t bogo_size;
2525 CAmount total_amount;
2626 CAmount total_subsidy;
27- CAmount block_unspendable_amount ;
28- CAmount block_prevout_spent_amount ;
29- CAmount block_new_outputs_ex_coinbase_amount ;
30- CAmount block_coinbase_amount ;
31- CAmount unspendables_genesis_block ;
32- CAmount unspendables_bip30 ;
33- CAmount unspendables_scripts ;
34- CAmount unspendables_unclaimed_rewards ;
27+ CAmount total_unspendable_amount ;
28+ CAmount total_prevout_spent_amount ;
29+ CAmount total_new_outputs_ex_coinbase_amount ;
30+ CAmount total_coinbase_amount ;
31+ CAmount total_unspendables_genesis_block ;
32+ CAmount total_unspendables_bip30 ;
33+ CAmount total_unspendables_scripts ;
34+ CAmount total_unspendables_unclaimed_rewards ;
3535
3636 SERIALIZE_METHODS (DBVal, obj)
3737 {
@@ -40,14 +40,14 @@ struct DBVal {
4040 READWRITE (obj.bogo_size );
4141 READWRITE (obj.total_amount );
4242 READWRITE (obj.total_subsidy );
43- READWRITE (obj.block_unspendable_amount );
44- READWRITE (obj.block_prevout_spent_amount );
45- READWRITE (obj.block_new_outputs_ex_coinbase_amount );
46- READWRITE (obj.block_coinbase_amount );
47- READWRITE (obj.unspendables_genesis_block );
48- READWRITE (obj.unspendables_bip30 );
49- READWRITE (obj.unspendables_scripts );
50- READWRITE (obj.unspendables_unclaimed_rewards );
43+ READWRITE (obj.total_unspendable_amount );
44+ READWRITE (obj.total_prevout_spent_amount );
45+ READWRITE (obj.total_new_outputs_ex_coinbase_amount );
46+ READWRITE (obj.total_coinbase_amount );
47+ READWRITE (obj.total_unspendables_genesis_block );
48+ READWRITE (obj.total_unspendables_bip30 );
49+ READWRITE (obj.total_unspendables_scripts );
50+ READWRITE (obj.total_unspendables_unclaimed_rewards );
5151 }
5252};
5353
@@ -122,9 +122,12 @@ bool CoinStatsIndex::WriteBlock(const CBlock& block, const CBlockIndex* pindex)
122122
123123 uint256 expected_block_hash{pindex->pprev ->GetBlockHash ()};
124124 if (read_out.first != expected_block_hash) {
125+ LogPrintf (" WARNING: previous block header belongs to unexpected block %s; expected %s\n " ,
126+ read_out.first .ToString (), expected_block_hash.ToString ());
127+
125128 if (!m_db->Read (DBHashKey (expected_block_hash), read_out)) {
126- return error (" %s: previous block header belongs to unexpected block %s ; expected %s" ,
127- __func__, read_out. first . ToString (), expected_block_hash.ToString ());
129+ return error (" %s: previous block header not found ; expected %s" ,
130+ __func__, expected_block_hash.ToString ());
128131 }
129132 }
130133
@@ -138,29 +141,29 @@ bool CoinStatsIndex::WriteBlock(const CBlock& block, const CBlockIndex* pindex)
138141
139142 // Skip duplicate txid coinbase transactions (BIP30).
140143 if (is_bip30_block && tx->IsCoinBase ()) {
141- m_block_unspendable_amount += block_subsidy;
142- m_unspendables_bip30 += block_subsidy;
144+ m_total_unspendable_amount += block_subsidy;
145+ m_total_unspendables_bip30 += block_subsidy;
143146 continue ;
144147 }
145148
146- for (size_t j = 0 ; j < tx->vout .size (); ++j) {
149+ for (uint32_t j = 0 ; j < tx->vout .size (); ++j) {
147150 const CTxOut& out{tx->vout [j]};
148151 Coin coin{out, pindex->nHeight , tx->IsCoinBase ()};
149- COutPoint outpoint{tx->GetHash (), static_cast < uint32_t >(j) };
152+ COutPoint outpoint{tx->GetHash (), j };
150153
151154 // Skip unspendable coins
152155 if (coin.out .scriptPubKey .IsUnspendable ()) {
153- m_block_unspendable_amount += coin.out .nValue ;
154- m_unspendables_scripts += coin.out .nValue ;
156+ m_total_unspendable_amount += coin.out .nValue ;
157+ m_total_unspendables_scripts += coin.out .nValue ;
155158 continue ;
156159 }
157160
158161 m_muhash.Insert (MakeUCharSpan (TxOutSer (outpoint, coin)));
159162
160163 if (tx->IsCoinBase ()) {
161- m_block_coinbase_amount += coin.out .nValue ;
164+ m_total_coinbase_amount += coin.out .nValue ;
162165 } else {
163- m_block_new_outputs_ex_coinbase_amount += coin.out .nValue ;
166+ m_total_new_outputs_ex_coinbase_amount += coin.out .nValue ;
164167 }
165168
166169 ++m_transaction_output_count;
@@ -178,7 +181,7 @@ bool CoinStatsIndex::WriteBlock(const CBlock& block, const CBlockIndex* pindex)
178181
179182 m_muhash.Remove (MakeUCharSpan (TxOutSer (outpoint, coin)));
180183
181- m_block_prevout_spent_amount += coin.out .nValue ;
184+ m_total_prevout_spent_amount += coin.out .nValue ;
182185
183186 --m_transaction_output_count;
184187 m_total_amount -= coin.out .nValue ;
@@ -188,38 +191,41 @@ bool CoinStatsIndex::WriteBlock(const CBlock& block, const CBlockIndex* pindex)
188191 }
189192 } else {
190193 // genesis block
191- m_block_unspendable_amount += block_subsidy;
192- m_unspendables_genesis_block += block_subsidy;
194+ m_total_unspendable_amount += block_subsidy;
195+ m_total_unspendables_genesis_block += block_subsidy;
193196 }
194197
195198 // If spent prevouts + block subsidy are still a higher amount than
196199 // new outputs + coinbase + current unspendable amount this means
197200 // the miner did not claim the full block reward. Unclaimed block
198201 // rewards are also unspendable.
199- const CAmount unclaimed_rewards{(m_block_prevout_spent_amount + m_total_subsidy) - (m_block_new_outputs_ex_coinbase_amount + m_block_coinbase_amount + m_block_unspendable_amount )};
200- m_block_unspendable_amount += unclaimed_rewards;
201- m_unspendables_unclaimed_rewards += unclaimed_rewards;
202+ const CAmount unclaimed_rewards{(m_total_prevout_spent_amount + m_total_subsidy) - (m_total_new_outputs_ex_coinbase_amount + m_total_coinbase_amount + m_total_unspendable_amount )};
203+ m_total_unspendable_amount += unclaimed_rewards;
204+ m_total_unspendables_unclaimed_rewards += unclaimed_rewards;
202205
203206 std::pair<uint256, DBVal> value;
204207 value.first = pindex->GetBlockHash ();
205208 value.second .transaction_output_count = m_transaction_output_count;
206209 value.second .bogo_size = m_bogo_size;
207210 value.second .total_amount = m_total_amount;
208211 value.second .total_subsidy = m_total_subsidy;
209- value.second .block_unspendable_amount = m_block_unspendable_amount ;
210- value.second .block_prevout_spent_amount = m_block_prevout_spent_amount ;
211- value.second .block_new_outputs_ex_coinbase_amount = m_block_new_outputs_ex_coinbase_amount ;
212- value.second .block_coinbase_amount = m_block_coinbase_amount ;
213- value.second .unspendables_genesis_block = m_unspendables_genesis_block ;
214- value.second .unspendables_bip30 = m_unspendables_bip30 ;
215- value.second .unspendables_scripts = m_unspendables_scripts ;
216- value.second .unspendables_unclaimed_rewards = m_unspendables_unclaimed_rewards ;
212+ value.second .total_unspendable_amount = m_total_unspendable_amount ;
213+ value.second .total_prevout_spent_amount = m_total_prevout_spent_amount ;
214+ value.second .total_new_outputs_ex_coinbase_amount = m_total_new_outputs_ex_coinbase_amount ;
215+ value.second .total_coinbase_amount = m_total_coinbase_amount ;
216+ value.second .total_unspendables_genesis_block = m_total_unspendables_genesis_block ;
217+ value.second .total_unspendables_bip30 = m_total_unspendables_bip30 ;
218+ value.second .total_unspendables_scripts = m_total_unspendables_scripts ;
219+ value.second .total_unspendables_unclaimed_rewards = m_total_unspendables_unclaimed_rewards ;
217220
218221 uint256 out;
219222 m_muhash.Finalize (out);
220223 value.second .muhash = out;
221224
222- return m_db->Write (DBHeightKey (pindex->nHeight ), value) && m_db->Write (DB_MUHASH, m_muhash);
225+ CDBBatch batch (*m_db);
226+ batch.Write (DBHeightKey (pindex->nHeight ), value);
227+ batch.Write (DB_MUHASH, m_muhash);
228+ return m_db->WriteBatch (batch);
223229}
224230
225231static bool CopyHeightIndexToHashIndex (CDBIterator& db_it, CDBBatch& batch,
@@ -317,14 +323,14 @@ bool CoinStatsIndex::LookUpStats(const CBlockIndex* block_index, CCoinsStats& co
317323 coins_stats.nBogoSize = entry.bogo_size ;
318324 coins_stats.nTotalAmount = entry.total_amount ;
319325 coins_stats.total_subsidy = entry.total_subsidy ;
320- coins_stats.block_unspendable_amount = entry.block_unspendable_amount ;
321- coins_stats.block_prevout_spent_amount = entry.block_prevout_spent_amount ;
322- coins_stats.block_new_outputs_ex_coinbase_amount = entry.block_new_outputs_ex_coinbase_amount ;
323- coins_stats.block_coinbase_amount = entry.block_coinbase_amount ;
324- coins_stats.unspendables_genesis_block = entry.unspendables_genesis_block ;
325- coins_stats.unspendables_bip30 = entry.unspendables_bip30 ;
326- coins_stats.unspendables_scripts = entry.unspendables_scripts ;
327- coins_stats.unspendables_unclaimed_rewards = entry.unspendables_unclaimed_rewards ;
326+ coins_stats.total_unspendable_amount = entry.total_unspendable_amount ;
327+ coins_stats.total_prevout_spent_amount = entry.total_prevout_spent_amount ;
328+ coins_stats.total_new_outputs_ex_coinbase_amount = entry.total_new_outputs_ex_coinbase_amount ;
329+ coins_stats.total_coinbase_amount = entry.total_coinbase_amount ;
330+ coins_stats.total_unspendables_genesis_block = entry.total_unspendables_genesis_block ;
331+ coins_stats.total_unspendables_bip30 = entry.total_unspendables_bip30 ;
332+ coins_stats.total_unspendables_scripts = entry.total_unspendables_scripts ;
333+ coins_stats.total_unspendables_unclaimed_rewards = entry.total_unspendables_unclaimed_rewards ;
328334
329335 return true ;
330336}
@@ -341,33 +347,31 @@ bool CoinStatsIndex::Init()
341347 }
342348 }
343349
344- if (BaseIndex::Init ()) {
345- const CBlockIndex* pindex{CurrentIndex ()};
350+ if (!BaseIndex::Init ()) return false ;
346351
347- if (pindex) {
348- DBVal entry;
349- if (!LookUpOne (*m_db, pindex, entry)) {
350- return false ;
351- }
352+ const CBlockIndex* pindex{CurrentIndex ()};
352353
353- m_transaction_output_count = entry.transaction_output_count ;
354- m_bogo_size = entry.bogo_size ;
355- m_total_amount = entry.total_amount ;
356- m_total_subsidy = entry.total_subsidy ;
357- m_block_unspendable_amount = entry.block_unspendable_amount ;
358- m_block_prevout_spent_amount = entry.block_prevout_spent_amount ;
359- m_block_new_outputs_ex_coinbase_amount = entry.block_new_outputs_ex_coinbase_amount ;
360- m_block_coinbase_amount = entry.block_coinbase_amount ;
361- m_unspendables_genesis_block = entry.unspendables_genesis_block ;
362- m_unspendables_bip30 = entry.unspendables_bip30 ;
363- m_unspendables_scripts = entry.unspendables_scripts ;
364- m_unspendables_unclaimed_rewards = entry.unspendables_unclaimed_rewards ;
354+ if (pindex) {
355+ DBVal entry;
356+ if (!LookUpOne (*m_db, pindex, entry)) {
357+ return false ;
365358 }
366359
367- return true ;
360+ m_transaction_output_count = entry.transaction_output_count ;
361+ m_bogo_size = entry.bogo_size ;
362+ m_total_amount = entry.total_amount ;
363+ m_total_subsidy = entry.total_subsidy ;
364+ m_total_unspendable_amount = entry.total_unspendable_amount ;
365+ m_total_prevout_spent_amount = entry.total_prevout_spent_amount ;
366+ m_total_new_outputs_ex_coinbase_amount = entry.total_new_outputs_ex_coinbase_amount ;
367+ m_total_coinbase_amount = entry.total_coinbase_amount ;
368+ m_total_unspendables_genesis_block = entry.total_unspendables_genesis_block ;
369+ m_total_unspendables_bip30 = entry.total_unspendables_bip30 ;
370+ m_total_unspendables_scripts = entry.total_unspendables_scripts ;
371+ m_total_unspendables_unclaimed_rewards = entry.total_unspendables_unclaimed_rewards ;
368372 }
369373
370- return false ;
374+ return true ;
371375}
372376
373377// Reverse a single block as part of a reorg
@@ -391,9 +395,12 @@ bool CoinStatsIndex::ReverseBlock(const CBlock& block, const CBlockIndex* pindex
391395
392396 uint256 expected_block_hash{pindex->pprev ->GetBlockHash ()};
393397 if (read_out.first != expected_block_hash) {
398+ LogPrintf (" WARNING: previous block header belongs to unexpected block %s; expected %s\n " ,
399+ read_out.first .ToString (), expected_block_hash.ToString ());
400+
394401 if (!m_db->Read (DBHashKey (expected_block_hash), read_out)) {
395- return error (" %s: previous block header belongs to unexpected block %s ; expected %s" ,
396- __func__, read_out. first . ToString (), expected_block_hash.ToString ());
402+ return error (" %s: previous block header not found ; expected %s" ,
403+ __func__, expected_block_hash.ToString ());
397404 }
398405 }
399406 }
@@ -402,24 +409,24 @@ bool CoinStatsIndex::ReverseBlock(const CBlock& block, const CBlockIndex* pindex
402409 for (size_t i = 0 ; i < block.vtx .size (); ++i) {
403410 const auto & tx{block.vtx .at (i)};
404411
405- for (size_t j = 0 ; j < tx->vout .size (); ++j) {
412+ for (uint32_t j = 0 ; j < tx->vout .size (); ++j) {
406413 const CTxOut& out{tx->vout [j]};
407- COutPoint outpoint{tx->GetHash (), static_cast < uint32_t >(j) };
414+ COutPoint outpoint{tx->GetHash (), j };
408415 Coin coin{out, pindex->nHeight , tx->IsCoinBase ()};
409416
410417 // Skip unspendable coins
411418 if (coin.out .scriptPubKey .IsUnspendable ()) {
412- m_block_unspendable_amount -= coin.out .nValue ;
413- m_unspendables_scripts -= coin.out .nValue ;
419+ m_total_unspendable_amount -= coin.out .nValue ;
420+ m_total_unspendables_scripts -= coin.out .nValue ;
414421 continue ;
415422 }
416423
417424 m_muhash.Remove (MakeUCharSpan (TxOutSer (outpoint, coin)));
418425
419426 if (tx->IsCoinBase ()) {
420- m_block_coinbase_amount -= coin.out .nValue ;
427+ m_total_coinbase_amount -= coin.out .nValue ;
421428 } else {
422- m_block_new_outputs_ex_coinbase_amount -= coin.out .nValue ;
429+ m_total_new_outputs_ex_coinbase_amount -= coin.out .nValue ;
423430 }
424431
425432 --m_transaction_output_count;
@@ -437,7 +444,7 @@ bool CoinStatsIndex::ReverseBlock(const CBlock& block, const CBlockIndex* pindex
437444
438445 m_muhash.Insert (MakeUCharSpan (TxOutSer (outpoint, coin)));
439446
440- m_block_prevout_spent_amount -= coin.out .nValue ;
447+ m_total_prevout_spent_amount -= coin.out .nValue ;
441448
442449 m_transaction_output_count++;
443450 m_total_amount += coin.out .nValue ;
@@ -446,9 +453,9 @@ bool CoinStatsIndex::ReverseBlock(const CBlock& block, const CBlockIndex* pindex
446453 }
447454 }
448455
449- const CAmount unclaimed_rewards{(m_block_new_outputs_ex_coinbase_amount + m_block_coinbase_amount + m_block_unspendable_amount ) - (m_block_prevout_spent_amount + m_total_subsidy)};
450- m_block_unspendable_amount -= unclaimed_rewards;
451- m_unspendables_unclaimed_rewards -= unclaimed_rewards;
456+ const CAmount unclaimed_rewards{(m_total_new_outputs_ex_coinbase_amount + m_total_coinbase_amount + m_total_unspendable_amount ) - (m_total_prevout_spent_amount + m_total_subsidy)};
457+ m_total_unspendable_amount -= unclaimed_rewards;
458+ m_total_unspendables_unclaimed_rewards -= unclaimed_rewards;
452459
453460 // Check that the rolled back internal values are consistent with the DB read out
454461 uint256 out;
@@ -459,14 +466,14 @@ bool CoinStatsIndex::ReverseBlock(const CBlock& block, const CBlockIndex* pindex
459466 Assert (m_total_amount == read_out.second .total_amount );
460467 Assert (m_bogo_size == read_out.second .bogo_size );
461468 Assert (m_total_subsidy == read_out.second .total_subsidy );
462- Assert (m_block_unspendable_amount == read_out.second .block_unspendable_amount );
463- Assert (m_block_prevout_spent_amount == read_out.second .block_prevout_spent_amount );
464- Assert (m_block_new_outputs_ex_coinbase_amount == read_out.second .block_new_outputs_ex_coinbase_amount );
465- Assert (m_block_coinbase_amount == read_out.second .block_coinbase_amount );
466- Assert (m_unspendables_genesis_block == read_out.second .unspendables_genesis_block );
467- Assert (m_unspendables_bip30 == read_out.second .unspendables_bip30 );
468- Assert (m_unspendables_scripts == read_out.second .unspendables_scripts );
469- Assert (m_unspendables_unclaimed_rewards == read_out.second .unspendables_unclaimed_rewards );
469+ Assert (m_total_unspendable_amount == read_out.second .total_unspendable_amount );
470+ Assert (m_total_prevout_spent_amount == read_out.second .total_prevout_spent_amount );
471+ Assert (m_total_new_outputs_ex_coinbase_amount == read_out.second .total_new_outputs_ex_coinbase_amount );
472+ Assert (m_total_coinbase_amount == read_out.second .total_coinbase_amount );
473+ Assert (m_total_unspendables_genesis_block == read_out.second .total_unspendables_genesis_block );
474+ Assert (m_total_unspendables_bip30 == read_out.second .total_unspendables_bip30 );
475+ Assert (m_total_unspendables_scripts == read_out.second .total_unspendables_scripts );
476+ Assert (m_total_unspendables_unclaimed_rewards == read_out.second .total_unspendables_unclaimed_rewards );
470477
471478 return m_db->Write (DB_MUHASH, m_muhash);
472479}
0 commit comments