LCOV - code coverage report
Current view: top level - src/consensus - validation.h (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 55 55 100.0 %
Date: 2022-04-21 14:51:19 Functions: 36 426 8.5 %
Legend: Modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed

Not modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed
Branches: 23 34 67.6 %

           Branch data     Line data    Source code
#       1                 :            : // Copyright (c) 2009-2010 Satoshi Nakamoto
#       2                 :            : // Copyright (c) 2009-2021 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                 :            : /** Index marker for when no witness commitment is present in a coinbase transaction. */
#      16                 :            : static constexpr int NO_WITNESS_COMMITMENT{-1};
#      17                 :            : 
#      18                 :            : /** Minimum size of a witness commitment structure. Defined in BIP 141. **/
#      19                 :            : static constexpr size_t MINIMUM_WITNESS_COMMITMENT{38};
#      20                 :            : 
#      21                 :            : /** A "reason" why a transaction was invalid, suitable for determining whether the
#      22                 :            :   * provider of the transaction should be banned/ignored/disconnected/etc.
#      23                 :            :   */
#      24                 :            : enum class TxValidationResult {
#      25                 :            :     TX_RESULT_UNSET = 0,     //!< initial value. Tx has not yet been rejected
#      26                 :            :     TX_CONSENSUS,            //!< invalid by consensus rules
#      27                 :            :     /**
#      28                 :            :      * Invalid by a change to consensus rules more recent than SegWit.
#      29                 :            :      * Currently unused as there are no such consensus rule changes, and any download
#      30                 :            :      * sources realistically need to support SegWit in order to provide useful data,
#      31                 :            :      * so differentiating between always-invalid and invalid-by-pre-SegWit-soft-fork
#      32                 :            :      * is uninteresting.
#      33                 :            :      */
#      34                 :            :     TX_RECENT_CONSENSUS_CHANGE,
#      35                 :            :     TX_INPUTS_NOT_STANDARD,   //!< inputs (covered by txid) failed policy rules
#      36                 :            :     TX_NOT_STANDARD,          //!< otherwise didn't meet our local policy rules
#      37                 :            :     TX_MISSING_INPUTS,        //!< transaction was missing some of its inputs
#      38                 :            :     TX_PREMATURE_SPEND,       //!< transaction spends a coinbase too early, or violates locktime/sequence locks
#      39                 :            :     /**
#      40                 :            :      * Transaction might have a witness prior to SegWit
#      41                 :            :      * activation, or witness may have been malleated (which includes
#      42                 :            :      * non-standard witnesses).
#      43                 :            :      */
#      44                 :            :     TX_WITNESS_MUTATED,
#      45                 :            :     /**
#      46                 :            :      * Transaction is missing a witness.
#      47                 :            :      */
#      48                 :            :     TX_WITNESS_STRIPPED,
#      49                 :            :     /**
#      50                 :            :      * Tx already in mempool or conflicts with a tx in the chain
#      51                 :            :      * (if it conflicts with another tx in mempool, we use MEMPOOL_POLICY as it failed to reach the RBF threshold)
#      52                 :            :      * Currently this is only used if the transaction already exists in the mempool or on chain.
#      53                 :            :      */
#      54                 :            :     TX_CONFLICT,
#      55                 :            :     TX_MEMPOOL_POLICY,        //!< violated mempool's fee/size/descendant/RBF/etc limits
#      56                 :            :     TX_NO_MEMPOOL,            //!< this node does not have a mempool so can't validate the transaction
#      57                 :            : };
#      58                 :            : 
#      59                 :            : /** A "reason" why a block was invalid, suitable for determining whether the
#      60                 :            :   * provider of the block should be banned/ignored/disconnected/etc.
#      61                 :            :   * These are much more granular than the rejection codes, which may be more
#      62                 :            :   * useful for some other use-cases.
#      63                 :            :   */
#      64                 :            : enum class BlockValidationResult {
#      65                 :            :     BLOCK_RESULT_UNSET = 0,  //!< initial value. Block has not yet been rejected
#      66                 :            :     BLOCK_CONSENSUS,         //!< invalid by consensus rules (excluding any below reasons)
#      67                 :            :     /**
#      68                 :            :      * Invalid by a change to consensus rules more recent than SegWit.
#      69                 :            :      * Currently unused as there are no such consensus rule changes, and any download
#      70                 :            :      * sources realistically need to support SegWit in order to provide useful data,
#      71                 :            :      * so differentiating between always-invalid and invalid-by-pre-SegWit-soft-fork
#      72                 :            :      * is uninteresting.
#      73                 :            :      */
#      74                 :            :     BLOCK_RECENT_CONSENSUS_CHANGE,
#      75                 :            :     BLOCK_CACHED_INVALID,    //!< this block was cached as being invalid and we didn't store the reason why
#      76                 :            :     BLOCK_INVALID_HEADER,    //!< invalid proof of work or time too old
#      77                 :            :     BLOCK_MUTATED,           //!< the block's data didn't match the data committed to by the PoW
#      78                 :            :     BLOCK_MISSING_PREV,      //!< We don't have the previous block the checked one is built on
#      79                 :            :     BLOCK_INVALID_PREV,      //!< A block this one builds on is invalid
#      80                 :            :     BLOCK_TIME_FUTURE,       //!< block timestamp was > 2 hours in the future (or our clock is bad)
#      81                 :            :     BLOCK_CHECKPOINT,        //!< the block failed to meet one of our checkpoints
#      82                 :            : };
#      83                 :            : 
#      84                 :            : 
#      85                 :            : 
#      86                 :            : /** Template for capturing information about block/transaction validation. This is instantiated
#      87                 :            :  *  by TxValidationState and BlockValidationState for validation information on transactions
#      88                 :            :  *  and blocks respectively. */
#      89                 :            : template <typename Result>
#      90                 :            : class ValidationState
#      91                 :            : {
#      92                 :            : private:
#      93                 :            :     enum class ModeState {
#      94                 :            :         M_VALID,   //!< everything ok
#      95                 :            :         M_INVALID, //!< network rule violation (DoS value may be set)
#      96                 :            :         M_ERROR,   //!< run-time error
#      97                 :            :     } m_mode{ModeState::M_VALID};
#      98                 :            :     Result m_result{};
#      99                 :            :     std::string m_reject_reason;
#     100                 :            :     std::string m_debug_message;
#     101                 :            : 
#     102                 :            : public:
#     103                 :            :     bool Invalid(Result result,
#     104                 :            :                  const std::string& reject_reason = "",
#     105                 :            :                  const std::string& debug_message = "")
#     106                 :      91644 :     {
#     107                 :      91644 :         m_result = result;
#     108                 :      91644 :         m_reject_reason = reject_reason;
#     109                 :      91644 :         m_debug_message = debug_message;
#     110 [ +  - ][ +  - ]:      91644 :         if (m_mode != ModeState::M_ERROR) m_mode = ModeState::M_INVALID;
#                 [ +  - ]
#     111                 :      91644 :         return false;
#     112                 :      91644 :     }
#     113                 :            :     bool Error(const std::string& reject_reason)
#     114                 :          1 :     {
#     115         [ +  - ]:          1 :         if (m_mode == ModeState::M_VALID)
#     116                 :          1 :             m_reject_reason = reject_reason;
#     117                 :          1 :         m_mode = ModeState::M_ERROR;
#     118                 :          1 :         return false;
#     119                 :          1 :     }
#     120                 :     186155 :     bool IsValid() const { return m_mode == ModeState::M_VALID; }
#     121                 :      85021 :     bool IsInvalid() const { return m_mode == ModeState::M_INVALID; }
#     122                 :       3945 :     bool IsError() const { return m_mode == ModeState::M_ERROR; }
#     123                 :      25310 :     Result GetResult() const { return m_result; }
#     124                 :      11045 :     std::string GetRejectReason() const { return m_reject_reason; }
#     125                 :       4301 :     std::string GetDebugMessage() const { return m_debug_message; }
#     126                 :            :     std::string ToString() const
#     127                 :      82495 :     {
#     128 [ +  + ][ -  + ]:      82495 :         if (IsValid()) {
#     129                 :      64436 :             return "Valid";
#     130                 :      64436 :         }
#     131                 :            : 
#     132 [ +  + ][ +  + ]:      18059 :         if (!m_debug_message.empty()) {
#     133                 :       1243 :             return m_reject_reason + ", " + m_debug_message;
#     134                 :       1243 :         }
#     135                 :            : 
#     136                 :      16816 :         return m_reject_reason;
#     137                 :      18059 :     }
#     138                 :            : };
#     139                 :            : 
#     140                 :            : class TxValidationState : public ValidationState<TxValidationResult> {};
#     141                 :            : class BlockValidationState : public ValidationState<BlockValidationResult> {};
#     142                 :            : 
#     143                 :            : // These implement the weight = (stripped_size * 4) + witness_size formula,
#     144                 :            : // using only serialization with and without witness data. As witness_size
#     145                 :            : // is equal to total_size - stripped_size, this formula is identical to:
#     146                 :            : // weight = (stripped_size * 3) + total_size.
#     147                 :            : static inline int64_t GetTransactionWeight(const CTransaction& tx)
#     148                 :     157144 : {
#     149                 :     157144 :     return ::GetSerializeSize(tx, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(tx, PROTOCOL_VERSION);
#     150                 :     157144 : }
#     151                 :            : static inline int64_t GetBlockWeight(const CBlock& block)
#     152                 :     122812 : {
#     153                 :     122812 :     return ::GetSerializeSize(block, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(block, PROTOCOL_VERSION);
#     154                 :     122812 : }
#     155                 :            : static inline int64_t GetTransactionInputWeight(const CTxIn& txin)
#     156                 :     349288 : {
#     157                 :            :     // scriptWitness size is added here because witnesses and txins are split up in segwit serialization.
#     158                 :     349288 :     return ::GetSerializeSize(txin, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(txin, PROTOCOL_VERSION) + ::GetSerializeSize(txin.scriptWitness.stack, PROTOCOL_VERSION);
#     159                 :     349288 : }
#     160                 :            : 
#     161                 :            : /** Compute at which vout of the block's coinbase transaction the witness commitment occurs, or -1 if not found */
#     162                 :            : inline int GetWitnessCommitmentIndex(const CBlock& block)
#     163                 :     169679 : {
#     164                 :     169679 :     int commitpos = NO_WITNESS_COMMITMENT;
#     165         [ +  - ]:     169679 :     if (!block.vtx.empty()) {
#     166         [ +  + ]:     480823 :         for (size_t o = 0; o < block.vtx[0]->vout.size(); o++) {
#     167                 :     311144 :             const CTxOut& vout = block.vtx[0]->vout[o];
#     168         [ +  + ]:     311144 :             if (vout.scriptPubKey.size() >= MINIMUM_WITNESS_COMMITMENT &&
#     169         [ +  + ]:     311144 :                 vout.scriptPubKey[0] == OP_RETURN &&
#     170         [ +  - ]:     311144 :                 vout.scriptPubKey[1] == 0x24 &&
#     171         [ +  - ]:     311144 :                 vout.scriptPubKey[2] == 0xaa &&
#     172         [ +  - ]:     311144 :                 vout.scriptPubKey[3] == 0x21 &&
#     173         [ +  - ]:     311144 :                 vout.scriptPubKey[4] == 0xa9 &&
#     174         [ +  - ]:     311144 :                 vout.scriptPubKey[5] == 0xed) {
#     175                 :     128395 :                 commitpos = o;
#     176                 :     128395 :             }
#     177                 :     311144 :         }
#     178                 :     169679 :     }
#     179                 :     169679 :     return commitpos;
#     180                 :     169679 : }
#     181                 :            : 
#     182                 :            : #endif // BITCOIN_CONSENSUS_VALIDATION_H

Generated by: LCOV version 0-eol-96201-ge66f56f4af6a