From 27afcd89db302d87168e0f504ee141dbf0e1ea22 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Fri, 16 Jan 2015 18:57:14 -0500 Subject: [PATCH 1/2] Consensus: Refactor: Decouple CValidationState from main::AbortNode() --- src/main.cpp | 54 ++++++++++++++++++++++++++-------------------------- src/main.h | 6 ------ 2 files changed, 27 insertions(+), 33 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 5fd9c6248..0a849c035 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1552,6 +1552,24 @@ bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uin return true; } +/** Abort with a message */ +bool AbortNode(const std::string& strMessage, const std::string& userMessage="") +{ + strMiscWarning = strMessage; + LogPrintf("*** %s\n", strMessage); + uiInterface.ThreadSafeMessageBox( + userMessage.empty() ? _("Error: A fatal internal error occured, see debug.log for details") : userMessage, + "", CClientUIInterface::MSG_ERROR); + StartShutdown(); + return false; +} + +bool AbortNode(CValidationState& state, const std::string& strMessage, const std::string& userMessage="") +{ + AbortNode(strMessage, userMessage); + return state.Error(strMessage); +} + } // anon namespace /** @@ -1831,7 +1849,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin if (!FindUndoPos(state, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40)) return error("ConnectBlock(): FindUndoPos failed"); if (!UndoWriteToDisk(blockundo, pos, pindex->pprev->GetBlockHash())) - return state.Abort("Failed to write undo data"); + return AbortNode(state, "Failed to write undo data"); // update nUndoPos in block index pindex->nUndoPos = pos.nPos; @@ -1844,7 +1862,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin if (fTxIndex) if (!pblocktree->WriteTxIndex(vPos)) - return state.Abort("Failed to write transaction index"); + return AbortNode(state, "Failed to write transaction index"); // add this block to the view's block chain view.SetBestBlock(pindex->GetBlockHash()); @@ -1938,7 +1956,7 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) { setDirtyBlockIndex.erase(it++); } if (!pblocktree->WriteBatchSync(vFiles, nLastBlockFile, vBlocks)) { - return state.Abort("Files to write to block index database"); + return AbortNode(state, "Files to write to block index database"); } } // Finally remove any pruned files @@ -1959,7 +1977,7 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) { return state.Error("out of disk space"); // Flush the chainstate (which may refer to block index entries). if (!pcoinsTip->Flush()) - return state.Abort("Failed to write to coin database"); + return AbortNode(state, "Failed to write to coin database"); nLastFlush = nNow; } if ((mode == FLUSH_STATE_ALWAYS || mode == FLUSH_STATE_PERIODIC) && nNow > nLastSetChain + (int64_t)DATABASE_WRITE_INTERVAL * 1000000) { @@ -1968,7 +1986,7 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) { nLastSetChain = nNow; } } catch (const std::runtime_error& e) { - return state.Abort(std::string("System error while flushing: ") + e.what()); + return AbortNode(state, std::string("System error while flushing: ") + e.what()); } return true; } @@ -2032,7 +2050,7 @@ bool static DisconnectTip(CValidationState &state) { // Read block from disk. CBlock block; if (!ReadBlockFromDisk(block, pindexDelete)) - return state.Abort("Failed to read block"); + return AbortNode(state, "Failed to read block"); // Apply the block atomically to the chain state. int64_t nStart = GetTimeMicros(); { @@ -2083,7 +2101,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * CBlock block; if (!pblock) { if (!ReadBlockFromDisk(block, pindexNew)) - return state.Abort("Failed to read block"); + return AbortNode(state, "Failed to read block"); pblock = █ } // Apply the block atomically to the chain state. @@ -2790,11 +2808,11 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, return error("AcceptBlock(): FindBlockPos failed"); if (dbp == NULL) if (!WriteBlockToDisk(block, blockPos)) - return state.Abort("Failed to write block"); + AbortNode(state, "Failed to write block"); if (!ReceivedBlockTransactions(block, state, pindex, blockPos)) return error("AcceptBlock(): ReceivedBlockTransactions failed"); } catch (const std::runtime_error& e) { - return state.Abort(std::string("System error: ") + e.what()); + return AbortNode(state, std::string("System error: ") + e.what()); } if (fCheckForPruning) @@ -2869,24 +2887,6 @@ bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex return true; } - - - - - - - -bool AbortNode(const std::string &strMessage, const std::string &userMessage) { - strMiscWarning = strMessage; - LogPrintf("*** %s\n", strMessage); - uiInterface.ThreadSafeMessageBox( - userMessage.empty() ? _("Error: A fatal internal error occured, see debug.log for details") : userMessage, - "", CClientUIInterface::MSG_ERROR); - StartShutdown(); - return false; -} - - /** * BLOCK PRUNING CODE */ diff --git a/src/main.h b/src/main.h index fcbc4075d..1fc418daf 100644 --- a/src/main.h +++ b/src/main.h @@ -228,8 +228,6 @@ void UnlinkPrunedFiles(std::set& setFilesToPrune); /** Create a new block index entry for a given block hash */ CBlockIndex * InsertBlockIndex(uint256 hash); -/** Abort with a message */ -bool AbortNode(const std::string &msg, const std::string &userMessage=""); /** Get statistics from node state */ bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats); /** Increase a node's misbehavior score. */ @@ -495,10 +493,6 @@ public: mode = MODE_ERROR; return false; } - bool Abort(const std::string &msg) { - AbortNode(msg); - return Error(msg); - } bool IsValid() const { return mode == MODE_VALID; } From da29ecbcc6c003a603ee2312309d593708ec6fb2 Mon Sep 17 00:00:00 2001 From: jtimon Date: Sat, 24 Jan 2015 15:57:12 +0100 Subject: [PATCH 2/2] Consensus: MOVEONLY: Move CValidationState from main consensus/validation --- src/Makefile.am | 1 + src/consensus/validation.h | 80 ++++++++++++++++++++++++++++++++++ src/init.cpp | 1 + src/main.cpp | 1 + src/main.h | 69 ----------------------------- src/miner.cpp | 1 + src/rpcblockchain.cpp | 2 + src/rpcmining.cpp | 1 + src/rpcrawtransaction.cpp | 3 +- src/test/checkblock_tests.cpp | 9 +--- src/test/miner_tests.cpp | 1 + src/test/sighash_tests.cpp | 7 +-- src/test/transaction_tests.cpp | 3 +- src/txmempool.cpp | 1 + src/wallet/wallet.cpp | 1 + src/wallet/walletdb.cpp | 1 + 16 files changed, 101 insertions(+), 81 deletions(-) create mode 100644 src/consensus/validation.h diff --git a/src/Makefile.am b/src/Makefile.am index 93ad26acf..6ce431e23 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -92,6 +92,7 @@ BITCOIN_CORE_H = \ compressor.h \ consensus/consensus.h \ consensus/params.h \ + consensus/validation.h \ core_io.h \ eccryptoverify.h \ ecwrapper.h \ diff --git a/src/consensus/validation.h b/src/consensus/validation.h new file mode 100644 index 000000000..c92bec4fa --- /dev/null +++ b/src/consensus/validation.h @@ -0,0 +1,80 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_CONSENSUS_VALIDATION_H +#define BITCOIN_CONSENSUS_VALIDATION_H + +#include + +/** "reject" message codes */ +static const unsigned char REJECT_MALFORMED = 0x01; +static const unsigned char REJECT_INVALID = 0x10; +static const unsigned char REJECT_OBSOLETE = 0x11; +static const unsigned char REJECT_DUPLICATE = 0x12; +static const unsigned char REJECT_NONSTANDARD = 0x40; +static const unsigned char REJECT_DUST = 0x41; +static const unsigned char REJECT_INSUFFICIENTFEE = 0x42; +static const unsigned char REJECT_CHECKPOINT = 0x43; + +/** Capture information about block/transaction validation */ +class CValidationState { +private: + enum mode_state { + MODE_VALID, //! everything ok + MODE_INVALID, //! network rule violation (DoS value may be set) + MODE_ERROR, //! run-time error + } mode; + int nDoS; + std::string strRejectReason; + unsigned char chRejectCode; + bool corruptionPossible; +public: + CValidationState() : mode(MODE_VALID), nDoS(0), chRejectCode(0), corruptionPossible(false) {} + bool DoS(int level, bool ret = false, + unsigned char chRejectCodeIn=0, std::string strRejectReasonIn="", + bool corruptionIn=false) { + chRejectCode = chRejectCodeIn; + strRejectReason = strRejectReasonIn; + corruptionPossible = corruptionIn; + if (mode == MODE_ERROR) + return ret; + nDoS += level; + mode = MODE_INVALID; + return ret; + } + bool Invalid(bool ret = false, + unsigned char _chRejectCode=0, std::string _strRejectReason="") { + return DoS(0, ret, _chRejectCode, _strRejectReason); + } + bool Error(std::string strRejectReasonIn="") { + if (mode == MODE_VALID) + strRejectReason = strRejectReasonIn; + mode = MODE_ERROR; + return false; + } + bool IsValid() const { + return mode == MODE_VALID; + } + bool IsInvalid() const { + return mode == MODE_INVALID; + } + bool IsError() const { + return mode == MODE_ERROR; + } + bool IsInvalid(int &nDoSOut) const { + if (IsInvalid()) { + nDoSOut = nDoS; + return true; + } + return false; + } + bool CorruptionPossible() const { + return corruptionPossible; + } + unsigned char GetRejectCode() const { return chRejectCode; } + std::string GetRejectReason() const { return strRejectReason; } +}; + +#endif // BITCOIN_CONSENSUS_VALIDATION_H diff --git a/src/init.cpp b/src/init.cpp index 3c3b3fb23..d31720934 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -13,6 +13,7 @@ #include "amount.h" #include "checkpoints.h" #include "compat/sanity.h" +#include "consensus/validation.h" #include "key.h" #include "main.h" #include "miner.h" diff --git a/src/main.cpp b/src/main.cpp index 0a849c035..481eeaa9e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -11,6 +11,7 @@ #include "chainparams.h" #include "checkpoints.h" #include "checkqueue.h" +#include "consensus/validation.h" #include "init.h" #include "merkleblock.h" #include "net.h" diff --git a/src/main.h b/src/main.h index 1fc418daf..1386339fd 100644 --- a/src/main.h +++ b/src/main.h @@ -89,16 +89,6 @@ static const unsigned int DATABASE_FLUSH_INTERVAL = 24 * 60 * 60; /** Maximum length of reject messages. */ static const unsigned int MAX_REJECT_MESSAGE_LENGTH = 111; -/** "reject" message codes */ -static const unsigned char REJECT_MALFORMED = 0x01; -static const unsigned char REJECT_INVALID = 0x10; -static const unsigned char REJECT_OBSOLETE = 0x11; -static const unsigned char REJECT_DUPLICATE = 0x12; -static const unsigned char REJECT_NONSTANDARD = 0x40; -static const unsigned char REJECT_DUST = 0x41; -static const unsigned char REJECT_INSUFFICIENTFEE = 0x42; -static const unsigned char REJECT_CHECKPOINT = 0x43; - struct BlockHasher { size_t operator()(const uint256& hash) const { return hash.GetCheapHash(); } @@ -457,65 +447,6 @@ public: } }; -/** Capture information about block/transaction validation */ -class CValidationState { -private: - enum mode_state { - MODE_VALID, //! everything ok - MODE_INVALID, //! network rule violation (DoS value may be set) - MODE_ERROR, //! run-time error - } mode; - int nDoS; - std::string strRejectReason; - unsigned char chRejectCode; - bool corruptionPossible; -public: - CValidationState() : mode(MODE_VALID), nDoS(0), chRejectCode(0), corruptionPossible(false) {} - bool DoS(int level, bool ret = false, - unsigned char chRejectCodeIn=0, std::string strRejectReasonIn="", - bool corruptionIn=false) { - chRejectCode = chRejectCodeIn; - strRejectReason = strRejectReasonIn; - corruptionPossible = corruptionIn; - if (mode == MODE_ERROR) - return ret; - nDoS += level; - mode = MODE_INVALID; - return ret; - } - bool Invalid(bool ret = false, - unsigned char _chRejectCode=0, std::string _strRejectReason="") { - return DoS(0, ret, _chRejectCode, _strRejectReason); - } - bool Error(std::string strRejectReasonIn="") { - if (mode == MODE_VALID) - strRejectReason = strRejectReasonIn; - mode = MODE_ERROR; - return false; - } - bool IsValid() const { - return mode == MODE_VALID; - } - bool IsInvalid() const { - return mode == MODE_INVALID; - } - bool IsError() const { - return mode == MODE_ERROR; - } - bool IsInvalid(int &nDoSOut) const { - if (IsInvalid()) { - nDoSOut = nDoS; - return true; - } - return false; - } - bool CorruptionPossible() const { - return corruptionPossible; - } - unsigned char GetRejectCode() const { return chRejectCode; } - std::string GetRejectReason() const { return strRejectReason; } -}; - /** RAII wrapper for VerifyDB: Verify consistency of the block and coin databases */ class CVerifyDB { public: diff --git a/src/miner.cpp b/src/miner.cpp index 4bceb7d7b..daa94e59a 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -8,6 +8,7 @@ #include "amount.h" #include "chainparams.h" #include "consensus/consensus.h" +#include "consensus/validation.h" #include "hash.h" #include "main.h" #include "net.h" diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 4315c5ec1..79528db2f 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -4,7 +4,9 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "checkpoints.h" +#include "consensus/validation.h" #include "main.h" +#include "primitives/transaction.h" #include "rpcserver.h" #include "sync.h" #include "util.h" diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index a6a8b9422..d58d43857 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -6,6 +6,7 @@ #include "amount.h" #include "chainparams.h" #include "consensus/consensus.h" +#include "consensus/validation.h" #include "core_io.h" #include "init.h" #include "main.h" diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index e84d2693a..3e37b797e 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -4,13 +4,14 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "base58.h" -#include "primitives/transaction.h" +#include "consensus/validation.h" #include "core_io.h" #include "init.h" #include "keystore.h" #include "main.h" #include "merkleblock.h" #include "net.h" +#include "primitives/transaction.h" #include "rpcserver.h" #include "script/script.h" #include "script/script_error.h" diff --git a/src/test/checkblock_tests.cpp b/src/test/checkblock_tests.cpp index 7abfad151..51530c4de 100644 --- a/src/test/checkblock_tests.cpp +++ b/src/test/checkblock_tests.cpp @@ -2,16 +2,11 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -// -// Unit tests for block.CheckBlock() -// - - - #include "clientversion.h" +#include "consensus/validation.h" #include "main.h" -#include "utiltime.h" #include "test/test_bitcoin.h" +#include "utiltime.h" #include diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index d7ea91607..b6365b1b3 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -2,6 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "consensus/validation.h" #include "main.h" #include "miner.h" #include "pubkey.h" diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index afb7a41bb..87be2217c 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -2,15 +2,16 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "consensus/validation.h" #include "data/sighash.json.h" #include "main.h" #include "random.h" -#include "serialize.h" -#include "script/script.h" #include "script/interpreter.h" +#include "script/script.h" +#include "serialize.h" +#include "test/test_bitcoin.h" #include "util.h" #include "version.h" -#include "test/test_bitcoin.h" #include diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 2a3083316..d12535e43 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -7,12 +7,13 @@ #include "test/test_bitcoin.h" #include "clientversion.h" +#include "consensus/validation.h" +#include "core_io.h" #include "key.h" #include "keystore.h" #include "main.h" #include "script/script.h" #include "script/script_error.h" -#include "core_io.h" #include #include diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 071fa9d52..1c16e2092 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -7,6 +7,7 @@ #include "clientversion.h" #include "consensus/consensus.h" +#include "consensus/validation.h" #include "main.h" #include "policy/fees.h" #include "streams.h" diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 0afdcd001..afc3d7acd 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -9,6 +9,7 @@ #include "checkpoints.h" #include "coincontrol.h" #include "consensus/consensus.h" +#include "consensus/validation.h" #include "main.h" #include "net.h" #include "script/script.h" diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index de56a2d1a..d16e7825d 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -6,6 +6,7 @@ #include "wallet/walletdb.h" #include "base58.h" +#include "consensus/validation.h" #include "main.h" #include "protocol.h" #include "serialize.h"