Merge pull request #5669

da29ecb Consensus: MOVEONLY: Move CValidationState from main consensus/validation (jtimon)
27afcd8 Consensus: Refactor: Decouple CValidationState from main::AbortNode() (Cory Fields)
This commit is contained in:
Wladimir J. van der Laan 2015-05-27 13:35:15 +02:00
commit c7c9af381c
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
16 changed files with 128 additions and 114 deletions

View File

@ -92,6 +92,7 @@ BITCOIN_CORE_H = \
compressor.h \ compressor.h \
consensus/consensus.h \ consensus/consensus.h \
consensus/params.h \ consensus/params.h \
consensus/validation.h \
core_io.h \ core_io.h \
eccryptoverify.h \ eccryptoverify.h \
ecwrapper.h \ ecwrapper.h \

View File

@ -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 <string>
/** "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

View File

@ -13,6 +13,7 @@
#include "amount.h" #include "amount.h"
#include "checkpoints.h" #include "checkpoints.h"
#include "compat/sanity.h" #include "compat/sanity.h"
#include "consensus/validation.h"
#include "key.h" #include "key.h"
#include "main.h" #include "main.h"
#include "miner.h" #include "miner.h"

View File

@ -11,6 +11,7 @@
#include "chainparams.h" #include "chainparams.h"
#include "checkpoints.h" #include "checkpoints.h"
#include "checkqueue.h" #include "checkqueue.h"
#include "consensus/validation.h"
#include "init.h" #include "init.h"
#include "merkleblock.h" #include "merkleblock.h"
#include "net.h" #include "net.h"
@ -1562,6 +1563,24 @@ bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uin
return true; 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 } // anon namespace
/** /**
@ -1900,7 +1919,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
if (!FindUndoPos(state, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40)) if (!FindUndoPos(state, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40))
return error("ConnectBlock(): FindUndoPos failed"); return error("ConnectBlock(): FindUndoPos failed");
if (!UndoWriteToDisk(blockundo, pos, pindex->pprev->GetBlockHash())) 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 // update nUndoPos in block index
pindex->nUndoPos = pos.nPos; pindex->nUndoPos = pos.nPos;
@ -1913,7 +1932,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
if (fTxIndex) if (fTxIndex)
if (!pblocktree->WriteTxIndex(vPos)) 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 // add this block to the view's block chain
view.SetBestBlock(pindex->GetBlockHash()); view.SetBestBlock(pindex->GetBlockHash());
@ -2008,7 +2027,7 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) {
setDirtyBlockIndex.erase(it++); setDirtyBlockIndex.erase(it++);
} }
if (!pblocktree->WriteBatchSync(vFiles, nLastBlockFile, vBlocks)) { 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 // Finally remove any pruned files
@ -2027,7 +2046,7 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) {
return state.Error("out of disk space"); return state.Error("out of disk space");
// Flush the chainstate (which may refer to block index entries). // Flush the chainstate (which may refer to block index entries).
if (!pcoinsTip->Flush()) if (!pcoinsTip->Flush())
return state.Abort("Failed to write to coin database"); return AbortNode(state, "Failed to write to coin database");
nLastFlush = nNow; nLastFlush = nNow;
} }
if ((mode == FLUSH_STATE_ALWAYS || mode == FLUSH_STATE_PERIODIC) && nNow > nLastSetChain + (int64_t)DATABASE_WRITE_INTERVAL * 1000000) { if ((mode == FLUSH_STATE_ALWAYS || mode == FLUSH_STATE_PERIODIC) && nNow > nLastSetChain + (int64_t)DATABASE_WRITE_INTERVAL * 1000000) {
@ -2036,7 +2055,7 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) {
nLastSetChain = nNow; nLastSetChain = nNow;
} }
} catch (const std::runtime_error& e) { } 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; return true;
} }
@ -2100,7 +2119,7 @@ bool static DisconnectTip(CValidationState &state) {
// Read block from disk. // Read block from disk.
CBlock block; CBlock block;
if (!ReadBlockFromDisk(block, pindexDelete)) 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. // Apply the block atomically to the chain state.
int64_t nStart = GetTimeMicros(); int64_t nStart = GetTimeMicros();
{ {
@ -2151,7 +2170,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
CBlock block; CBlock block;
if (!pblock) { if (!pblock) {
if (!ReadBlockFromDisk(block, pindexNew)) if (!ReadBlockFromDisk(block, pindexNew))
return state.Abort("Failed to read block"); return AbortNode(state, "Failed to read block");
pblock = &block; pblock = &block;
} }
// Apply the block atomically to the chain state. // Apply the block atomically to the chain state.
@ -2858,11 +2877,11 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex,
return error("AcceptBlock(): FindBlockPos failed"); return error("AcceptBlock(): FindBlockPos failed");
if (dbp == NULL) if (dbp == NULL)
if (!WriteBlockToDisk(block, blockPos)) if (!WriteBlockToDisk(block, blockPos))
return state.Abort("Failed to write block"); AbortNode(state, "Failed to write block");
if (!ReceivedBlockTransactions(block, state, pindex, blockPos)) if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
return error("AcceptBlock(): ReceivedBlockTransactions failed"); return error("AcceptBlock(): ReceivedBlockTransactions failed");
} catch (const std::runtime_error& e) { } 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) if (fCheckForPruning)
@ -2937,24 +2956,6 @@ bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex
return true; 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 * BLOCK PRUNING CODE
*/ */

View File

@ -89,16 +89,6 @@ static const unsigned int DATABASE_FLUSH_INTERVAL = 24 * 60 * 60;
/** Maximum length of reject messages. */ /** Maximum length of reject messages. */
static const unsigned int MAX_REJECT_MESSAGE_LENGTH = 111; 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 struct BlockHasher
{ {
size_t operator()(const uint256& hash) const { return hash.GetCheapHash(); } size_t operator()(const uint256& hash) const { return hash.GetCheapHash(); }
@ -230,8 +220,6 @@ void UnlinkPrunedFiles(std::set<int>& setFilesToPrune);
/** Create a new block index entry for a given block hash */ /** Create a new block index entry for a given block hash */
CBlockIndex * InsertBlockIndex(uint256 hash); CBlockIndex * InsertBlockIndex(uint256 hash);
/** Abort with a message */
bool AbortNode(const std::string &msg, const std::string &userMessage="");
/** Get statistics from node state */ /** Get statistics from node state */
bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats); bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats);
/** Increase a node's misbehavior score. */ /** Increase a node's misbehavior score. */
@ -461,69 +449,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 Abort(const std::string &msg) {
AbortNode(msg);
return Error(msg);
}
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 */ /** RAII wrapper for VerifyDB: Verify consistency of the block and coin databases */
class CVerifyDB { class CVerifyDB {
public: public:

View File

@ -8,6 +8,7 @@
#include "amount.h" #include "amount.h"
#include "chainparams.h" #include "chainparams.h"
#include "consensus/consensus.h" #include "consensus/consensus.h"
#include "consensus/validation.h"
#include "hash.h" #include "hash.h"
#include "main.h" #include "main.h"
#include "net.h" #include "net.h"

View File

@ -4,7 +4,9 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "checkpoints.h" #include "checkpoints.h"
#include "consensus/validation.h"
#include "main.h" #include "main.h"
#include "primitives/transaction.h"
#include "rpcserver.h" #include "rpcserver.h"
#include "sync.h" #include "sync.h"
#include "util.h" #include "util.h"

View File

@ -6,6 +6,7 @@
#include "amount.h" #include "amount.h"
#include "chainparams.h" #include "chainparams.h"
#include "consensus/consensus.h" #include "consensus/consensus.h"
#include "consensus/validation.h"
#include "core_io.h" #include "core_io.h"
#include "init.h" #include "init.h"
#include "main.h" #include "main.h"

View File

@ -4,13 +4,14 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "base58.h" #include "base58.h"
#include "primitives/transaction.h" #include "consensus/validation.h"
#include "core_io.h" #include "core_io.h"
#include "init.h" #include "init.h"
#include "keystore.h" #include "keystore.h"
#include "main.h" #include "main.h"
#include "merkleblock.h" #include "merkleblock.h"
#include "net.h" #include "net.h"
#include "primitives/transaction.h"
#include "rpcserver.h" #include "rpcserver.h"
#include "script/script.h" #include "script/script.h"
#include "script/script_error.h" #include "script/script_error.h"

View File

@ -2,16 +2,11 @@
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
//
// Unit tests for block.CheckBlock()
//
#include "clientversion.h" #include "clientversion.h"
#include "consensus/validation.h"
#include "main.h" #include "main.h"
#include "utiltime.h"
#include "test/test_bitcoin.h" #include "test/test_bitcoin.h"
#include "utiltime.h"
#include <cstdio> #include <cstdio>

View File

@ -2,6 +2,7 @@
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "consensus/validation.h"
#include "main.h" #include "main.h"
#include "miner.h" #include "miner.h"
#include "pubkey.h" #include "pubkey.h"

View File

@ -2,15 +2,16 @@
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "consensus/validation.h"
#include "data/sighash.json.h" #include "data/sighash.json.h"
#include "main.h" #include "main.h"
#include "random.h" #include "random.h"
#include "serialize.h"
#include "script/script.h"
#include "script/interpreter.h" #include "script/interpreter.h"
#include "script/script.h"
#include "serialize.h"
#include "test/test_bitcoin.h"
#include "util.h" #include "util.h"
#include "version.h" #include "version.h"
#include "test/test_bitcoin.h"
#include <iostream> #include <iostream>

View File

@ -7,12 +7,13 @@
#include "test/test_bitcoin.h" #include "test/test_bitcoin.h"
#include "clientversion.h" #include "clientversion.h"
#include "consensus/validation.h"
#include "core_io.h"
#include "key.h" #include "key.h"
#include "keystore.h" #include "keystore.h"
#include "main.h" #include "main.h"
#include "script/script.h" #include "script/script.h"
#include "script/script_error.h" #include "script/script_error.h"
#include "core_io.h"
#include <map> #include <map>
#include <string> #include <string>

View File

@ -7,6 +7,7 @@
#include "clientversion.h" #include "clientversion.h"
#include "consensus/consensus.h" #include "consensus/consensus.h"
#include "consensus/validation.h"
#include "main.h" #include "main.h"
#include "policy/fees.h" #include "policy/fees.h"
#include "streams.h" #include "streams.h"

View File

@ -9,6 +9,7 @@
#include "checkpoints.h" #include "checkpoints.h"
#include "coincontrol.h" #include "coincontrol.h"
#include "consensus/consensus.h" #include "consensus/consensus.h"
#include "consensus/validation.h"
#include "main.h" #include "main.h"
#include "net.h" #include "net.h"
#include "script/script.h" #include "script/script.h"

View File

@ -6,6 +6,7 @@
#include "wallet/walletdb.h" #include "wallet/walletdb.h"
#include "base58.h" #include "base58.h"
#include "consensus/validation.h"
#include "main.h" #include "main.h"
#include "protocol.h" #include "protocol.h"
#include "serialize.h" #include "serialize.h"