| 355 | } |
| 356 | |
| 357 | bool CoinStatsIndex::Init() |
| 358 | { |
| 359 | if (!m_db->Read(DB_MUHASH, m_muhash)) { |
| 360 | // Check that the cause of the read failure is that the key does not |
| 361 | // exist. Any other errors indicate database corruption or a disk |
| 362 | // failure, and starting the index would cause further corruption. |
| 363 | if (m_db->Exists(DB_MUHASH)) { |
| 364 | return error("%s: Cannot read current %s state; index may be corrupted", |
| 365 | __func__, GetName()); |
| 366 | } |
| 367 | } |
| 368 | |
| 369 | if (!BaseIndex::Init()) return false; |
| 370 | |
| 371 | const CBlockIndex* pindex{CurrentIndex()}; |
| 372 | |
| 373 | if (pindex) { |
| 374 | DBVal entry; |
| 375 | if (!LookUpOne(*m_db, pindex, entry)) { |
| 376 | return error("%s: Cannot read current %s state; index may be corrupted", |
| 377 | __func__, GetName()); |
| 378 | } |
| 379 | |
| 380 | uint256 out; |
| 381 | m_muhash.Finalize(out); |
| 382 | if (entry.muhash != out) { |
| 383 | return error("%s: Cannot read current %s state; index may be corrupted", |
| 384 | __func__, GetName()); |
| 385 | } |
| 386 | |
| 387 | m_transaction_output_count = entry.transaction_output_count; |
| 388 | m_bogo_size = entry.bogo_size; |
| 389 | m_total_amount = entry.total_amount; |
| 390 | m_total_subsidy = entry.total_subsidy; |
| 391 | m_total_unspendable_amount = entry.total_unspendable_amount; |
| 392 | m_total_prevout_spent_amount = entry.total_prevout_spent_amount; |
| 393 | m_total_new_outputs_ex_coinbase_amount = entry.total_new_outputs_ex_coinbase_amount; |
| 394 | m_total_coinbase_amount = entry.total_coinbase_amount; |
| 395 | m_total_unspendables_genesis_block = entry.total_unspendables_genesis_block; |
| 396 | m_total_unspendables_bip30 = entry.total_unspendables_bip30; |
| 397 | m_total_unspendables_scripts = entry.total_unspendables_scripts; |
| 398 | m_total_unspendables_unclaimed_rewards = entry.total_unspendables_unclaimed_rewards; |
| 399 | } |
| 400 | |
| 401 | return true; |
| 402 | } |
| 403 | |
| 404 | // Reverse a single block as part of a reorg |
| 405 | bool CoinStatsIndex::ReverseBlock(const CBlock& block, const CBlockIndex* pindex) |