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: 2021-06-29 14:35:33 Functions: 33 165 20.0 %
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-2020 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                 :            : };
#      57                 :            : 
#      58                 :            : /** A "reason" why a block was invalid, suitable for determining whether the
#      59                 :            :   * provider of the block should be banned/ignored/disconnected/etc.
#      60                 :            :   * These are much more granular than the rejection codes, which may be more
#      61                 :            :   * useful for some other use-cases.
#      62                 :            :   */
#      63                 :            : enum class BlockValidationResult {
#      64                 :            :     BLOCK_RESULT_UNSET = 0,  //!< initial value. Block has not yet been rejected
#      65                 :            :     BLOCK_CONSENSUS,         //!< invalid by consensus rules (excluding any below reasons)
#      66                 :            :     /**
#      67                 :            :      * Invalid by a change to consensus rules more recent than SegWit.
#      68                 :            :      * Currently unused as there are no such consensus rule changes, and any download
#      69                 :            :      * sources realistically need to support SegWit in order to provide useful data,
#      70                 :            :      * so differentiating between always-invalid and invalid-by-pre-SegWit-soft-fork
#      71                 :            :      * is uninteresting.
#      72                 :            :      */
#      73                 :            :     BLOCK_RECENT_CONSENSUS_CHANGE,
#      74                 :            :     BLOCK_CACHED_INVALID,    //!< this block was cached as being invalid and we didn't store the reason why
#      75                 :            :     BLOCK_INVALID_HEADER,    //!< invalid proof of work or time too old
#      76                 :            :     BLOCK_MUTATED,           //!< the block's data didn't match the data committed to by the PoW
#      77                 :            :     BLOCK_MISSING_PREV,      //!< We don't have the previous block the checked one is built on
#      78                 :            :     BLOCK_INVALID_PREV,      //!< A block this one builds on is invalid
#      79                 :            :     BLOCK_TIME_FUTURE,       //!< block timestamp was > 2 hours in the future (or our clock is bad)
#      80                 :            :     BLOCK_CHECKPOINT,        //!< the block failed to meet one of our checkpoints
#      81                 :            : };
#      82                 :            : 
#      83                 :            : 
#      84                 :            : 
#      85                 :            : /** Template for capturing information about block/transaction validation. This is instantiated
#      86                 :            :  *  by TxValidationState and BlockValidationState for validation information on transactions
#      87                 :            :  *  and blocks respectively. */
#      88                 :            : template <typename Result>
#      89                 :            : class ValidationState
#      90                 :            : {
#      91                 :            : private:
#      92                 :            :     enum class ModeState {
#      93                 :            :         M_VALID,   //!< everything ok
#      94                 :            :         M_INVALID, //!< network rule violation (DoS value may be set)
#      95                 :            :         M_ERROR,   //!< run-time error
#      96                 :            :     } m_mode{ModeState::M_VALID};
#      97                 :            :     Result m_result{};
#      98                 :            :     std::string m_reject_reason;
#      99                 :            :     std::string m_debug_message;
#     100                 :            : 
#     101                 :            : public:
#     102                 :            :     bool Invalid(Result result,
#     103                 :            :                  const std::string& reject_reason = "",
#     104                 :            :                  const std::string& debug_message = "")
#     105                 :     141687 :     {
#     106                 :     141687 :         m_result = result;
#     107                 :     141687 :         m_reject_reason = reject_reason;
#     108                 :     141687 :         m_debug_message = debug_message;
#     109 [ +  - ][ +  - ]:     141687 :         if (m_mode != ModeState::M_ERROR) m_mode = ModeState::M_INVALID;
#                 [ +  - ]
#     110                 :     141687 :         return false;
#     111                 :     141687 :     }
#     112                 :            :     bool Error(const std::string& reject_reason)
#     113                 :          1 :     {
#     114         [ +  - ]:          1 :         if (m_mode == ModeState::M_VALID)
#     115                 :          1 :             m_reject_reason = reject_reason;
#     116                 :          1 :         m_mode = ModeState::M_ERROR;
#     117                 :          1 :         return false;
#     118                 :          1 :     }
#     119                 :     197256 :     bool IsValid() const { return m_mode == ModeState::M_VALID; }
#     120                 :      88806 :     bool IsInvalid() const { return m_mode == ModeState::M_INVALID; }
#     121                 :       4207 :     bool IsError() const { return m_mode == ModeState::M_ERROR; }
#     122                 :      12485 :     Result GetResult() const { return m_result; }
#     123                 :       5566 :     std::string GetRejectReason() const { return m_reject_reason; }
#     124                 :       2970 :     std::string GetDebugMessage() const { return m_debug_message; }
#     125                 :            :     std::string ToString() const
#     126                 :      88029 :     {
#     127 [ +  + ][ -  + ]:      88029 :         if (IsValid()) {
#     128                 :      73220 :             return "Valid";
#     129                 :      73220 :         }
#     130                 :            : 
#     131 [ +  + ][ +  + ]:      14809 :         if (!m_debug_message.empty()) {
#     132                 :       1196 :             return m_reject_reason + ", " + m_debug_message;
#     133                 :       1196 :         }
#     134                 :            : 
#     135                 :      13613 :         return m_reject_reason;
#     136                 :      13613 :     }
#     137                 :            : };
#     138                 :            : 
#     139                 :            : class TxValidationState : public ValidationState<TxValidationResult> {};
#     140                 :            : class BlockValidationState : public ValidationState<BlockValidationResult> {};
#     141                 :            : 
#     142                 :            : // These implement the weight = (stripped_size * 4) + witness_size formula,
#     143                 :            : // using only serialization with and without witness data. As witness_size
#     144                 :            : // is equal to total_size - stripped_size, this formula is identical to:
#     145                 :            : // weight = (stripped_size * 3) + total_size.
#     146                 :            : static inline int64_t GetTransactionWeight(const CTransaction& tx)
#     147                 :     124712 : {
#     148                 :     124712 :     return ::GetSerializeSize(tx, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(tx, PROTOCOL_VERSION);
#     149                 :     124712 : }
#     150                 :            : static inline int64_t GetBlockWeight(const CBlock& block)
#     151                 :     132243 : {
#     152                 :     132243 :     return ::GetSerializeSize(block, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(block, PROTOCOL_VERSION);
#     153                 :     132243 : }
#     154                 :            : static inline int64_t GetTransactionInputWeight(const CTxIn& txin)
#     155                 :     406527 : {
#     156                 :            :     // scriptWitness size is added here because witnesses and txins are split up in segwit serialization.
#     157                 :     406527 :     return ::GetSerializeSize(txin, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(txin, PROTOCOL_VERSION) + ::GetSerializeSize(txin.scriptWitness.stack, PROTOCOL_VERSION);
#     158                 :     406527 : }
#     159                 :            : 
#     160                 :            : /** Compute at which vout of the block's coinbase transaction the witness commitment occurs, or -1 if not found */
#     161                 :            : inline int GetWitnessCommitmentIndex(const CBlock& block)
#     162                 :     173556 : {
#     163                 :     173556 :     int commitpos = NO_WITNESS_COMMITMENT;
#     164         [ +  - ]:     173556 :     if (!block.vtx.empty()) {
#     165         [ +  + ]:     492426 :         for (size_t o = 0; o < block.vtx[0]->vout.size(); o++) {
#     166                 :     318870 :             const CTxOut& vout = block.vtx[0]->vout[o];
#     167         [ +  + ]:     318870 :             if (vout.scriptPubKey.size() >= MINIMUM_WITNESS_COMMITMENT &&
#     168         [ +  + ]:     318870 :                 vout.scriptPubKey[0] == OP_RETURN &&
#     169         [ +  - ]:     318870 :                 vout.scriptPubKey[1] == 0x24 &&
#     170         [ +  - ]:     318870 :                 vout.scriptPubKey[2] == 0xaa &&
#     171         [ +  - ]:     318870 :                 vout.scriptPubKey[3] == 0x21 &&
#     172         [ +  - ]:     318870 :                 vout.scriptPubKey[4] == 0xa9 &&
#     173         [ +  - ]:     318870 :                 vout.scriptPubKey[5] == 0xed) {
#     174                 :     132406 :                 commitpos = o;
#     175                 :     132406 :             }
#     176                 :     318870 :         }
#     177                 :     173556 :     }
#     178                 :     173556 :     return commitpos;
#     179                 :     173556 : }
#     180                 :            : 
#     181                 :            : #endif // BITCOIN_CONSENSUS_VALIDATION_H

Generated by: LCOV version 1.14