MCPcopy Create free account
hub / github.com/ElementsProject/elements / ReverseBlock

Method ReverseBlock

src/index/coinstatsindex.cpp:405–523  ·  view source on GitHub ↗

Reverse a single block as part of a reorg

Source from the content-addressed store, hash-verified

403
404// Reverse a single block as part of a reorg
405bool CoinStatsIndex::ReverseBlock(const CBlock& block, const CBlockIndex* pindex)
406{
407 CBlockUndo block_undo;
408 std::pair<uint256, DBVal> read_out;
409
410 const CAmount block_subsidy{GetBlockSubsidy(pindex->nHeight, Params().GetConsensus())};
411 m_total_subsidy -= block_subsidy;
412
413 CAmount elements_block_fee{0};
414 CAmount elements_coinbase_amount{0};
415
416 // Ignore genesis block
417 if (pindex->nHeight > 0) {
418 if (!UndoReadFromDisk(block_undo, pindex)) {
419 return false;
420 }
421
422 if (!m_db->Read(DBHeightKey(pindex->nHeight - 1), read_out)) {
423 return false;
424 }
425
426 uint256 expected_block_hash{pindex->pprev->GetBlockHash()};
427 if (read_out.first != expected_block_hash) {
428 LogPrintf("WARNING: previous block header belongs to unexpected block %s; expected %s\n",
429 read_out.first.ToString(), expected_block_hash.ToString());
430
431 if (!m_db->Read(DBHashKey(expected_block_hash), read_out)) {
432 return error("%s: previous block header not found; expected %s",
433 __func__, expected_block_hash.ToString());
434 }
435 }
436 }
437
438 // Remove the new UTXOs that were created from the block
439 for (size_t i = 0; i < block.vtx.size(); ++i) {
440 const auto& tx{block.vtx.at(i)};
441
442 for (uint32_t j = 0; j < tx->vout.size(); ++j) {
443 const CTxOut& out{tx->vout[j]};
444 COutPoint outpoint{tx->GetHash(), j};
445 Coin coin{out, pindex->nHeight, tx->IsCoinBase()};
446
447 // Skip unspendable coins
448 if (coin.out.scriptPubKey.IsUnspendable()) {
449 if (coin.out.nValue.IsExplicit()) {
450 if (coin.out.IsFee()) {
451 elements_block_fee += coin.out.nValue.GetAmount();
452 } else {
453 m_total_unspendable_amount -= coin.out.nValue.GetAmount();
454 m_total_unspendables_scripts -= coin.out.nValue.GetAmount();
455 }
456 }
457 continue;
458 }
459
460 m_muhash.Remove(MakeUCharSpan(TxOutSer(outpoint, coin)));
461
462 if (coin.out.nValue.IsExplicit()) {

Callers

nothing calls this directly

Calls 15

GetBlockSubsidyFunction · 0.85
UndoReadFromDiskFunction · 0.85
errorFunction · 0.85
MakeUCharSpanFunction · 0.85
TxOutSerFunction · 0.85
GetBogoSizeFunction · 0.85
IsUnspendableMethod · 0.80
IsExplicitMethod · 0.80
IsFeeMethod · 0.80
GetAmountMethod · 0.80
RemoveMethod · 0.80
DBHeightKeyClass · 0.70

Tested by

no test coverage detected