Changeset View
Changeset View
Standalone View
Standalone View
src/consensus/validation.h
// Copyright (c) 2009-2010 Satoshi Nakamoto | // Copyright (c) 2009-2010 Satoshi Nakamoto | ||||
// Copyright (c) 2009-2016 The Bitcoin Core developers | // Copyright (c) 2009-2016 The Bitcoin Core developers | ||||
// 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. | ||||
#ifndef BITCOIN_CONSENSUS_VALIDATION_H | #ifndef BITCOIN_CONSENSUS_VALIDATION_H | ||||
#define BITCOIN_CONSENSUS_VALIDATION_H | #define BITCOIN_CONSENSUS_VALIDATION_H | ||||
#include <cassert> | #include <cassert> | ||||
#include <string> | #include <string> | ||||
/** "reject" message codes */ | |||||
static const uint8_t REJECT_MALFORMED = 0x01; | |||||
static const uint8_t REJECT_INVALID = 0x10; | |||||
static const uint8_t REJECT_OBSOLETE = 0x11; | |||||
static const uint8_t REJECT_DUPLICATE = 0x12; | |||||
static const uint8_t REJECT_NONSTANDARD = 0x40; | |||||
static const uint8_t REJECT_INSUFFICIENTFEE = 0x42; | |||||
static const uint8_t REJECT_CHECKPOINT = 0x43; | |||||
/** | /** | ||||
* A "reason" why a transaction was invalid, suitable for determining whether | * A "reason" why a transaction was invalid, suitable for determining whether | ||||
* the provider of the transaction should be banned/ignored/disconnected/etc. | * the provider of the transaction should be banned/ignored/disconnected/etc. | ||||
* These are much more granular than the rejection codes, which may be more | |||||
* useful for some other use-cases. | |||||
*/ | */ | ||||
enum class TxValidationResult { | enum class TxValidationResult { | ||||
//! initial value. Tx has not yet been rejected | //! initial value. Tx has not yet been rejected | ||||
TX_RESULT_UNSET, | TX_RESULT_UNSET, | ||||
//! invalid by consensus rules | //! invalid by consensus rules | ||||
TX_CONSENSUS, | TX_CONSENSUS, | ||||
/** | /** | ||||
* Invalid by a recent change to consensus rules. | * Invalid by a recent change to consensus rules. | ||||
▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | |||||
class ValidationState { | class ValidationState { | ||||
private: | private: | ||||
enum mode_state { | enum mode_state { | ||||
MODE_VALID, //!< everything ok | MODE_VALID, //!< everything ok | ||||
MODE_INVALID, //!< network rule violation (DoS value may be set) | MODE_INVALID, //!< network rule violation (DoS value may be set) | ||||
MODE_ERROR, //!< run-time error | MODE_ERROR, //!< run-time error | ||||
} m_mode; | } m_mode; | ||||
std::string m_reject_reason; | std::string m_reject_reason; | ||||
unsigned int chRejectCode; | |||||
std::string m_debug_message; | std::string m_debug_message; | ||||
protected: | protected: | ||||
void Invalid(unsigned int chRejectCodeIn = 0, | void Invalid(const std::string &reject_reason = "", | ||||
const std::string &reject_reason = "", | |||||
const std::string &debug_message = "") { | const std::string &debug_message = "") { | ||||
chRejectCode = chRejectCodeIn; | |||||
m_reject_reason = reject_reason; | m_reject_reason = reject_reason; | ||||
m_debug_message = debug_message; | m_debug_message = debug_message; | ||||
if (m_mode != MODE_ERROR) { | if (m_mode != MODE_ERROR) { | ||||
m_mode = MODE_INVALID; | m_mode = MODE_INVALID; | ||||
} | } | ||||
} | } | ||||
public: | public: | ||||
// ValidationState is abstract. Have a pure virtual destructor. | // ValidationState is abstract. Have a pure virtual destructor. | ||||
virtual ~ValidationState() = 0; | virtual ~ValidationState() = 0; | ||||
ValidationState() : m_mode(MODE_VALID), chRejectCode(0) {} | ValidationState() : m_mode(MODE_VALID) {} | ||||
bool Error(const std::string &reject_reason) { | bool Error(const std::string &reject_reason) { | ||||
if (m_mode == MODE_VALID) { | if (m_mode == MODE_VALID) { | ||||
m_reject_reason = reject_reason; | m_reject_reason = reject_reason; | ||||
} | } | ||||
m_mode = MODE_ERROR; | m_mode = MODE_ERROR; | ||||
return false; | return false; | ||||
} | } | ||||
bool IsValid() const { return m_mode == MODE_VALID; } | bool IsValid() const { return m_mode == MODE_VALID; } | ||||
bool IsInvalid() const { return m_mode == MODE_INVALID; } | bool IsInvalid() const { return m_mode == MODE_INVALID; } | ||||
bool IsError() const { return m_mode == MODE_ERROR; } | bool IsError() const { return m_mode == MODE_ERROR; } | ||||
unsigned int GetRejectCode() const { return chRejectCode; } | |||||
std::string GetRejectReason() const { return m_reject_reason; } | std::string GetRejectReason() const { return m_reject_reason; } | ||||
std::string GetDebugMessage() const { return m_debug_message; } | std::string GetDebugMessage() const { return m_debug_message; } | ||||
}; | }; | ||||
inline ValidationState::~ValidationState(){}; | inline ValidationState::~ValidationState(){}; | ||||
class TxValidationState : public ValidationState { | class TxValidationState : public ValidationState { | ||||
private: | private: | ||||
TxValidationResult m_result = TxValidationResult::TX_RESULT_UNSET; | TxValidationResult m_result = TxValidationResult::TX_RESULT_UNSET; | ||||
public: | public: | ||||
bool Invalid(TxValidationResult result, unsigned int chRejectCodeIn = 0, | bool Invalid(TxValidationResult result, | ||||
const std::string &reject_reason = "", | const std::string &reject_reason = "", | ||||
const std::string &debug_message = "") { | const std::string &debug_message = "") { | ||||
m_result = result; | m_result = result; | ||||
ValidationState::Invalid(chRejectCodeIn, reject_reason, debug_message); | ValidationState::Invalid(reject_reason, debug_message); | ||||
return false; | return false; | ||||
} | } | ||||
TxValidationResult GetResult() const { return m_result; } | TxValidationResult GetResult() const { return m_result; } | ||||
}; | }; | ||||
class BlockValidationState : public ValidationState { | class BlockValidationState : public ValidationState { | ||||
private: | private: | ||||
BlockValidationResult m_result = BlockValidationResult::BLOCK_RESULT_UNSET; | BlockValidationResult m_result = BlockValidationResult::BLOCK_RESULT_UNSET; | ||||
public: | public: | ||||
bool Invalid(BlockValidationResult result, unsigned int chRejectCodeIn = 0, | bool Invalid(BlockValidationResult result, | ||||
const std::string &reject_reason = "", | const std::string &reject_reason = "", | ||||
const std::string &debug_message = "") { | const std::string &debug_message = "") { | ||||
m_result = result; | m_result = result; | ||||
ValidationState::Invalid(chRejectCodeIn, reject_reason, debug_message); | ValidationState::Invalid(reject_reason, debug_message); | ||||
return false; | return false; | ||||
} | } | ||||
BlockValidationResult GetResult() const { return m_result; } | BlockValidationResult GetResult() const { return m_result; } | ||||
}; | }; | ||||
#endif // BITCOIN_CONSENSUS_VALIDATION_H | #endif // BITCOIN_CONSENSUS_VALIDATION_H |