Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto 2 : // Copyright (c) 2009-2019 The Bitcoin Core developers 3 : // Distributed under the MIT software license, see the accompanying 4 : // file COPYING or http://www.opensource.org/licenses/mit-license.php. 5 : 6 : #ifndef BITCOIN_CONSENSUS_VALIDATION_H 7 : #define BITCOIN_CONSENSUS_VALIDATION_H 8 : 9 : #include <string> 10 : #include <version.h> 11 : #include <consensus/consensus.h> 12 : #include <primitives/transaction.h> 13 : #include <primitives/block.h> 14 : 15 : /** A "reason" why a transaction was invalid, suitable for determining whether the 16 : * provider of the transaction should be banned/ignored/disconnected/etc. 17 : */ 18 : enum class TxValidationResult { 19 : TX_RESULT_UNSET = 0, //!< initial value. Tx has not yet been rejected 20 : TX_CONSENSUS, //!< invalid by consensus rules 21 : /** 22 : * Invalid by a change to consensus rules more recent than SegWit. 23 : * Currently unused as there are no such consensus rule changes, and any download 24 : * sources realistically need to support SegWit in order to provide useful data, 25 : * so differentiating between always-invalid and invalid-by-pre-SegWit-soft-fork 26 : * is uninteresting. 27 : */ 28 : TX_RECENT_CONSENSUS_CHANGE, 29 : TX_INPUTS_NOT_STANDARD, //!< inputs (covered by txid) failed policy rules 30 : TX_NOT_STANDARD, //!< otherwise didn't meet our local policy rules 31 : TX_MISSING_INPUTS, //!< transaction was missing some of its inputs 32 : TX_PREMATURE_SPEND, //!< transaction spends a coinbase too early, or violates locktime/sequence locks 33 : /** 34 : * Transaction might have a witness prior to SegWit 35 : * activation, or witness may have been malleated (which includes 36 : * non-standard witnesses). 37 : */ 38 : TX_WITNESS_MUTATED, 39 : /** 40 : * Transaction is missing a witness. 41 : */ 42 : TX_WITNESS_STRIPPED, 43 : /** 44 : * Tx already in mempool or conflicts with a tx in the chain 45 : * (if it conflicts with another tx in mempool, we use MEMPOOL_POLICY as it failed to reach the RBF threshold) 46 : * Currently this is only used if the transaction already exists in the mempool or on chain. 47 : */ 48 : TX_CONFLICT, 49 : TX_MEMPOOL_POLICY, //!< violated mempool's fee/size/descendant/RBF/etc limits 50 : }; 51 : 52 : /** A "reason" why a block was invalid, suitable for determining whether the 53 : * provider of the block should be banned/ignored/disconnected/etc. 54 : * These are much more granular than the rejection codes, which may be more 55 : * useful for some other use-cases. 56 : */ 57 : enum class BlockValidationResult { 58 : BLOCK_RESULT_UNSET = 0, //!< initial value. Block has not yet been rejected 59 : BLOCK_CONSENSUS, //!< invalid by consensus rules (excluding any below reasons) 60 : /** 61 : * Invalid by a change to consensus rules more recent than SegWit. 62 : * Currently unused as there are no such consensus rule changes, and any download 63 : * sources realistically need to support SegWit in order to provide useful data, 64 : * so differentiating between always-invalid and invalid-by-pre-SegWit-soft-fork 65 : * is uninteresting. 66 : */ 67 : BLOCK_RECENT_CONSENSUS_CHANGE, 68 : BLOCK_CACHED_INVALID, //!< this block was cached as being invalid and we didn't store the reason why 69 : BLOCK_INVALID_HEADER, //!< invalid proof of work or time too old 70 : BLOCK_MUTATED, //!< the block's data didn't match the data committed to by the PoW 71 : BLOCK_MISSING_PREV, //!< We don't have the previous block the checked one is built on 72 : BLOCK_INVALID_PREV, //!< A block this one builds on is invalid 73 : BLOCK_TIME_FUTURE, //!< block timestamp was > 2 hours in the future (or our clock is bad) 74 : BLOCK_CHECKPOINT, //!< the block failed to meet one of our checkpoints 75 : }; 76 : 77 : 78 : 79 : /** Template for capturing information about block/transaction validation. This is instantiated 80 : * by TxValidationState and BlockValidationState for validation information on transactions 81 : * and blocks respectively. */ 82 : template <typename Result> 83 11520597 : class ValidationState 84 : { 85 : private: 86 : enum class ModeState { 87 : M_VALID, //!< everything ok 88 : M_INVALID, //!< network rule violation (DoS value may be set) 89 : M_ERROR, //!< run-time error 90 5760117 : } m_mode{ModeState::M_VALID}; 91 5760117 : Result m_result{}; 92 : std::string m_reject_reason; 93 : std::string m_debug_message; 94 : 95 : public: 96 68516 : bool Invalid(Result result, 97 : const std::string& reject_reason = "", 98 : const std::string& debug_message = "") 99 : { 100 68516 : m_result = result; 101 68516 : m_reject_reason = reject_reason; 102 68516 : m_debug_message = debug_message; 103 68516 : if (m_mode != ModeState::M_ERROR) m_mode = ModeState::M_INVALID; 104 68516 : return false; 105 : } 106 1 : bool Error(const std::string& reject_reason) 107 : { 108 1 : if (m_mode == ModeState::M_VALID) 109 1 : m_reject_reason = reject_reason; 110 1 : m_mode = ModeState::M_ERROR; 111 1 : return false; 112 : } 113 125422 : bool IsValid() const { return m_mode == ModeState::M_VALID; } 114 53272 : bool IsInvalid() const { return m_mode == ModeState::M_INVALID; } 115 1465 : bool IsError() const { return m_mode == ModeState::M_ERROR; } 116 2412 : Result GetResult() const { return m_result; } 117 336 : std::string GetRejectReason() const { return m_reject_reason; } 118 267 : std::string GetDebugMessage() const { return m_debug_message; } 119 61043 : std::string ToString() const 120 : { 121 61043 : if (IsValid()) { 122 59251 : return "Valid"; 123 : } 124 : 125 1792 : if (!m_debug_message.empty()) { 126 661 : return m_reject_reason + ", " + m_debug_message; 127 : } 128 : 129 1131 : return m_reject_reason; 130 61043 : } 131 : }; 132 : 133 22288704 : class TxValidationState : public ValidationState<TxValidationResult> {}; 134 752126 : class BlockValidationState : public ValidationState<BlockValidationResult> {}; 135 : 136 : // These implement the weight = (stripped_size * 4) + witness_size formula, 137 : // using only serialization with and without witness data. As witness_size 138 : // is equal to total_size - stripped_size, this formula is identical to: 139 : // weight = (stripped_size * 3) + total_size. 140 110105 : static inline int64_t GetTransactionWeight(const CTransaction& tx) 141 : { 142 110105 : return ::GetSerializeSize(tx, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(tx, PROTOCOL_VERSION); 143 : } 144 90875 : static inline int64_t GetBlockWeight(const CBlock& block) 145 : { 146 90875 : return ::GetSerializeSize(block, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(block, PROTOCOL_VERSION); 147 : } 148 228428 : static inline int64_t GetTransactionInputWeight(const CTxIn& txin) 149 : { 150 : // scriptWitness size is added here because witnesses and txins are split up in segwit serialization. 151 228428 : return ::GetSerializeSize(txin, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(txin, PROTOCOL_VERSION) + ::GetSerializeSize(txin.scriptWitness.stack, PROTOCOL_VERSION); 152 : } 153 : 154 : #endif // BITCOIN_CONSENSUS_VALIDATION_H