MCPcopy Create free account
hub / github.com/BTCGPU/BTCGPU / DisconnectBlock

Method DisconnectBlock

src/validation.cpp:1620–1675  ·  view source on GitHub ↗

Undo the effects of this block (with given index) on the UTXO set represented by coins. * When FAILED is returned, view is left in an indeterminate state. */

Source from the content-addressed store, hash-verified

1618/** Undo the effects of this block (with given index) on the UTXO set represented by coins.
1619 * When FAILED is returned, view is left in an indeterminate state. */
1620DisconnectResult CChainState::DisconnectBlock(const CBlock& block, const CBlockIndex* pindex, CCoinsViewCache& view)
1621{
1622 bool fClean = true;
1623
1624 CBlockUndo blockUndo;
1625 if (!UndoReadFromDisk(blockUndo, pindex)) {
1626 error("DisconnectBlock(): failure reading undo data");
1627 return DISCONNECT_FAILED;
1628 }
1629
1630 if (blockUndo.vtxundo.size() + 1 != block.vtx.size()) {
1631 error("DisconnectBlock(): block and undo data inconsistent");
1632 return DISCONNECT_FAILED;
1633 }
1634
1635 // undo transactions in reverse order
1636 for (int i = block.vtx.size() - 1; i >= 0; i--) {
1637 const CTransaction &tx = *(block.vtx[i]);
1638 uint256 hash = tx.GetHash();
1639 bool is_coinbase = tx.IsCoinBase();
1640
1641 // Check that all outputs are available and match the outputs in the block itself
1642 // exactly.
1643 for (size_t o = 0; o < tx.vout.size(); o++) {
1644 if (!tx.vout[o].scriptPubKey.IsUnspendable()) {
1645 COutPoint out(hash, o);
1646 Coin coin;
1647 bool is_spent = view.SpendCoin(out, &coin);
1648 if (!is_spent || tx.vout[o] != coin.out || pindex->nHeight != coin.nHeight || is_coinbase != coin.fCoinBase) {
1649 fClean = false; // transaction output mismatch
1650 }
1651 }
1652 }
1653
1654 // restore inputs
1655 if (i > 0) { // not coinbases
1656 CTxUndo &txundo = blockUndo.vtxundo[i-1];
1657 if (txundo.vprevout.size() != tx.vin.size()) {
1658 error("DisconnectBlock(): transaction and undo data inconsistent");
1659 return DISCONNECT_FAILED;
1660 }
1661 for (unsigned int j = tx.vin.size(); j-- > 0;) {
1662 const COutPoint &out = tx.vin[j].prevout;
1663 int res = ApplyTxInUndo(std::move(txundo.vprevout[j]), view, out);
1664 if (res == DISCONNECT_FAILED) return DISCONNECT_FAILED;
1665 fClean = fClean && res != DISCONNECT_UNCLEAN;
1666 }
1667 // At this point, all of txundo.vprevout should have been moved out.
1668 }
1669 }
1670
1671 // move best block pointer to prevout block
1672 view.SetBestBlock(pindex->pprev->GetBlockHash());
1673
1674 return fClean ? DISCONNECT_OK : DISCONNECT_UNCLEAN;
1675}
1676
1677void static FlushBlockFile(bool fFinalize = false)

Callers 1

VerifyDBMethod · 0.80

Calls 10

UndoReadFromDiskFunction · 0.85
errorFunction · 0.85
ApplyTxInUndoFunction · 0.85
IsUnspendableMethod · 0.80
SpendCoinMethod · 0.80
SetBestBlockMethod · 0.80
sizeMethod · 0.45
GetHashMethod · 0.45
IsCoinBaseMethod · 0.45
GetBlockHashMethod · 0.45

Tested by

no test coverage detected