diff --git a/src/Makefile.am b/src/Makefile.am --- a/src/Makefile.am +++ b/src/Makefile.am @@ -150,6 +150,7 @@ core_io.h \ core_memusage.h \ cuckoocache.h \ + disconnectresult.h \ eventloop.h \ flatfile.h \ fs.h \ diff --git a/src/disconnectresult.h b/src/disconnectresult.h new file mode 100644 --- /dev/null +++ b/src/disconnectresult.h @@ -0,0 +1,17 @@ +// Copyright (c) 2020 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_DISCONNECTRESULT_H +#define BITCOIN_DISCONNECTRESULT_H + +enum class DisconnectResult { + // All good. + OK, + // Rolled back, but UTXO set was inconsistent with block. + UNCLEAN, + // Something else went wrong. + FAILED, +}; + +#endif // BITCOIN_DISCONNECTRESULT_H diff --git a/src/undo.h b/src/undo.h --- a/src/undo.h +++ b/src/undo.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -115,15 +116,6 @@ } }; -enum DisconnectResult { - // All good. - DISCONNECT_OK, - // Rolled back, but UTXO set was inconsistent with block. - DISCONNECT_UNCLEAN, - // Something else went wrong. - DISCONNECT_FAILED, -}; - /** * Restore the UTXO in a Coin at a given COutPoint. * @param undo The Coin to be restored. diff --git a/src/validation.cpp b/src/validation.cpp --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1477,7 +1477,7 @@ const Coin &alternate = AccessByTxid(view, out.GetTxId()); if (alternate.IsSpent()) { // Adding output for transaction without known metadata - return DISCONNECT_FAILED; + return DisconnectResult::FAILED; } // This is somewhat ugly, but hopefully utility is limited. This is only @@ -1493,7 +1493,7 @@ // When fClean is false, a coin already existed and it is an overwrite. view.AddCoin(out, std::move(undo), !fClean); - return fClean ? DISCONNECT_OK : DISCONNECT_UNCLEAN; + return fClean ? DisconnectResult::OK : DisconnectResult::UNCLEAN; } /** @@ -1506,7 +1506,7 @@ CBlockUndo blockUndo; if (!UndoReadFromDisk(blockUndo, pindex)) { error("DisconnectBlock(): failure reading undo data"); - return DISCONNECT_FAILED; + return DisconnectResult::FAILED; } return ApplyBlockUndo(blockUndo, block, pindex, view); @@ -1519,7 +1519,7 @@ if (blockUndo.vtxundo.size() + 1 != block.vtx.size()) { error("DisconnectBlock(): block and undo data inconsistent"); - return DISCONNECT_FAILED; + return DisconnectResult::FAILED; } // First, restore inputs. @@ -1528,17 +1528,17 @@ const CTxUndo &txundo = blockUndo.vtxundo[i - 1]; if (txundo.vprevout.size() != tx.vin.size()) { error("DisconnectBlock(): transaction and undo data inconsistent"); - return DISCONNECT_FAILED; + return DisconnectResult::FAILED; } for (size_t j = 0; j < tx.vin.size(); j++) { const COutPoint &out = tx.vin[j].prevout; const Coin &undo = txundo.vprevout[j]; DisconnectResult res = UndoCoinSpend(undo, view, out); - if (res == DISCONNECT_FAILED) { - return DISCONNECT_FAILED; + if (res == DisconnectResult::FAILED) { + return DisconnectResult::FAILED; } - fClean = fClean && res != DISCONNECT_UNCLEAN; + fClean = fClean && res != DisconnectResult::UNCLEAN; } } @@ -1570,7 +1570,7 @@ // Move best block pointer to previous block. view.SetBestBlock(block.hashPrevBlock); - return fClean ? DISCONNECT_OK : DISCONNECT_UNCLEAN; + return fClean ? DisconnectResult::OK : DisconnectResult::UNCLEAN; } static void FlushBlockFile(bool fFinalize = false) { @@ -2356,7 +2356,8 @@ { CCoinsViewCache view(pcoinsTip.get()); assert(view.GetBestBlock() == pindexDelete->GetBlockHash()); - if (DisconnectBlock(block, pindexDelete, view) != DISCONNECT_OK) { + if (DisconnectBlock(block, pindexDelete, view) != + DisconnectResult::OK) { return error("DisconnectTip(): DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString()); } @@ -4918,14 +4919,14 @@ assert(coins.GetBestBlock() == pindex->GetBlockHash()); DisconnectResult res = g_chainstate.DisconnectBlock(block, pindex, coins); - if (res == DISCONNECT_FAILED) { + if (res == DisconnectResult::FAILED) { return error("VerifyDB(): *** irrecoverable inconsistency in " "block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); } - if (res == DISCONNECT_UNCLEAN) { + if (res == DisconnectResult::UNCLEAN) { nGoodTransactions = 0; pindexFailure = pindex; } else { @@ -5077,19 +5078,19 @@ LogPrintf("Rolling back %s (%i)\n", pindexOld->GetBlockHash().ToString(), pindexOld->nHeight); DisconnectResult res = DisconnectBlock(block, pindexOld, cache); - if (res == DISCONNECT_FAILED) { + if (res == DisconnectResult::FAILED) { return error( "RollbackBlock(): DisconnectBlock failed at %d, hash=%s", pindexOld->nHeight, pindexOld->GetBlockHash().ToString()); } - // If DISCONNECT_UNCLEAN is returned, it means a non-existing UTXO - // was deleted, or an existing UTXO was overwritten. It corresponds - // to cases where the block-to-be-disconnect never had all its - // operations applied to the UTXO set. However, as both writing a - // UTXO and deleting a UTXO are idempotent operations, the result is - // still a version of the UTXO set with the effects of that block - // undone. + // If DisconnectResult::UNCLEAN is returned, it means a non-existing + // UTXO was deleted, or an existing UTXO was overwritten. It + // corresponds to cases where the block-to-be-disconnect never had + // all its operations applied to the UTXO set. However, as both + // writing a UTXO and deleting a UTXO are idempotent operations, the + // result is still a version of the UTXO set with the effects of + // that block undone. } pindexOld = pindexOld->pprev; }