Skip to content

Commit

Permalink
Templatize ValidationState instead of subclassing
Browse files Browse the repository at this point in the history
This removes boilerplate code in the subclasses which otherwise only
differ by the result type.
  • Loading branch information
jkczyz committed Feb 28, 2020
1 parent 10e85d4 commit 10efc04
Showing 1 changed file with 13 additions and 39 deletions.
52 changes: 13 additions & 39 deletions src/consensus/validation.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* provider of the transaction should be banned/ignored/disconnected/etc.
*/
enum class TxValidationResult {
TX_RESULT_UNSET, //!< initial value. Tx has not yet been rejected
TX_RESULT_UNSET = 0, //!< initial value. Tx has not yet been rejected
TX_CONSENSUS, //!< invalid by consensus rules
/**
* Invalid by a change to consensus rules more recent than SegWit.
Expand Down Expand Up @@ -50,7 +50,7 @@ enum class TxValidationResult {
* useful for some other use-cases.
*/
enum class BlockValidationResult {
BLOCK_RESULT_UNSET, //!< initial value. Block has not yet been rejected
BLOCK_RESULT_UNSET = 0, //!< initial value. Block has not yet been rejected
BLOCK_CONSENSUS, //!< invalid by consensus rules (excluding any below reasons)
/**
* Invalid by a change to consensus rules more recent than SegWit.
Expand All @@ -71,30 +71,31 @@ enum class BlockValidationResult {



/** Base class for capturing information about block/transaction validation. This is subclassed
/** Template for capturing information about block/transaction validation. This is instantiated
* by TxValidationState and BlockValidationState for validation information on transactions
* and blocks respectively. */
template <typename Result>
class ValidationState {
private:
enum mode_state {
MODE_VALID, //!< everything ok
MODE_INVALID, //!< network rule violation (DoS value may be set)
MODE_ERROR, //!< run-time error
} m_mode{MODE_VALID};
Result m_result{};
std::string m_reject_reason;
std::string m_debug_message;
protected:
void Invalid(const std::string &reject_reason="",
public:
bool Invalid(Result result,
const std::string &reject_reason="",
const std::string &debug_message="")
{
m_result = result;
m_reject_reason = reject_reason;
m_debug_message = debug_message;
if (m_mode != MODE_ERROR) m_mode = MODE_INVALID;
return false;
}
public:
// ValidationState is abstract. Have a pure virtual destructor.
virtual ~ValidationState() = 0;

bool Error(const std::string& reject_reason)
{
if (m_mode == MODE_VALID)
Expand All @@ -105,6 +106,7 @@ class ValidationState {
bool IsValid() const { return m_mode == MODE_VALID; }
bool IsInvalid() const { return m_mode == MODE_INVALID; }
bool IsError() const { return m_mode == MODE_ERROR; }
Result GetResult() const { return m_result; }
std::string GetRejectReason() const { return m_reject_reason; }
std::string GetDebugMessage() const { return m_debug_message; }
std::string ToString() const
Expand All @@ -121,36 +123,8 @@ class ValidationState {
}
};

inline ValidationState::~ValidationState() {};

class TxValidationState : public ValidationState {
private:
TxValidationResult m_result = TxValidationResult::TX_RESULT_UNSET;
public:
bool Invalid(TxValidationResult result,
const std::string &reject_reason="",
const std::string &debug_message="")
{
m_result = result;
ValidationState::Invalid(reject_reason, debug_message);
return false;
}
TxValidationResult GetResult() const { return m_result; }
};

class BlockValidationState : public ValidationState {
private:
BlockValidationResult m_result = BlockValidationResult::BLOCK_RESULT_UNSET;
public:
bool Invalid(BlockValidationResult result,
const std::string &reject_reason="",
const std::string &debug_message="") {
m_result = result;
ValidationState::Invalid(reject_reason, debug_message);
return false;
}
BlockValidationResult GetResult() const { return m_result; }
};
class TxValidationState : public ValidationState<TxValidationResult> {};
class BlockValidationState : public ValidationState<BlockValidationResult> {};

// These implement the weight = (stripped_size * 4) + witness_size formula,
// using only serialization with and without witness data. As witness_size
Expand Down

0 comments on commit 10efc04

Please sign in to comment.