LCOV - code coverage report
Current view: top level - src/script - bitcoinconsensus.cpp (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 53 60 88.3 %
Date: 2022-04-21 14:51:19 Functions: 14 15 93.3 %
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: 14 16 87.5 %

           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                 :            : #include <script/bitcoinconsensus.h>
#       7                 :            : 
#       8                 :            : #include <primitives/transaction.h>
#       9                 :            : #include <pubkey.h>
#      10                 :            : #include <script/interpreter.h>
#      11                 :            : #include <version.h>
#      12                 :            : 
#      13                 :            : namespace {
#      14                 :            : 
#      15                 :            : /** A class that deserializes a single CTransaction one time. */
#      16                 :            : class TxInputStream
#      17                 :            : {
#      18                 :            : public:
#      19                 :            :     TxInputStream(int nVersionIn, const unsigned char *txTo, size_t txToLen) :
#      20                 :            :     m_version(nVersionIn),
#      21                 :            :     m_data(txTo),
#      22                 :            :     m_remaining(txToLen)
#      23                 :       1156 :     {}
#      24                 :            : 
#      25                 :            :     void read(Span<std::byte> dst)
#      26                 :      13964 :     {
#      27         [ +  + ]:      13964 :         if (dst.size() > m_remaining) {
#      28                 :          2 :             throw std::ios_base::failure(std::string(__func__) + ": end of data");
#      29                 :          2 :         }
#      30                 :            : 
#      31         [ -  + ]:      13962 :         if (dst.data() == nullptr) {
#      32                 :          0 :             throw std::ios_base::failure(std::string(__func__) + ": bad destination buffer");
#      33                 :          0 :         }
#      34                 :            : 
#      35         [ -  + ]:      13962 :         if (m_data == nullptr) {
#      36                 :          0 :             throw std::ios_base::failure(std::string(__func__) + ": bad source buffer");
#      37                 :          0 :         }
#      38                 :            : 
#      39                 :      13962 :         memcpy(dst.data(), m_data, dst.size());
#      40                 :      13962 :         m_remaining -= dst.size();
#      41                 :      13962 :         m_data += dst.size();
#      42                 :      13962 :     }
#      43                 :            : 
#      44                 :            :     template<typename T>
#      45                 :            :     TxInputStream& operator>>(T&& obj)
#      46                 :       5232 :     {
#      47                 :       5232 :         ::Unserialize(*this, obj);
#      48                 :       5232 :         return *this;
#      49                 :       5232 :     }
#      50                 :            : 
#      51                 :       1156 :     int GetVersion() const { return m_version; }
#      52                 :            : private:
#      53                 :            :     const int m_version;
#      54                 :            :     const unsigned char* m_data;
#      55                 :            :     size_t m_remaining;
#      56                 :            : };
#      57                 :            : 
#      58                 :            : inline int set_error(bitcoinconsensus_error* ret, bitcoinconsensus_error serror)
#      59                 :       1160 : {
#      60         [ +  + ]:       1160 :     if (ret)
#      61                 :         12 :         *ret = serror;
#      62                 :       1160 :     return 0;
#      63                 :       1160 : }
#      64                 :            : 
#      65                 :            : struct ECCryptoClosure
#      66                 :            : {
#      67                 :            :     ECCVerifyHandle handle;
#      68                 :            : };
#      69                 :            : 
#      70                 :            : ECCryptoClosure instance_of_eccryptoclosure;
#      71                 :            : } // namespace
#      72                 :            : 
#      73                 :            : /** Check that all specified flags are part of the libconsensus interface. */
#      74                 :            : static bool verify_flags(unsigned int flags)
#      75                 :       1158 : {
#      76                 :       1158 :     return (flags & ~(bitcoinconsensus_SCRIPT_FLAGS_VERIFY_ALL)) == 0;
#      77                 :       1158 : }
#      78                 :            : 
#      79                 :            : static int verify_script(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, CAmount amount,
#      80                 :            :                                     const unsigned char *txTo        , unsigned int txToLen,
#      81                 :            :                                     unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err)
#      82                 :       1158 : {
#      83         [ +  + ]:       1158 :     if (!verify_flags(flags)) {
#      84                 :          2 :         return set_error(err, bitcoinconsensus_ERR_INVALID_FLAGS);
#      85                 :          2 :     }
#      86                 :       1156 :     try {
#      87                 :       1156 :         TxInputStream stream(PROTOCOL_VERSION, txTo, txToLen);
#      88                 :       1156 :         CTransaction tx(deserialize, stream);
#      89         [ +  + ]:       1156 :         if (nIn >= tx.vin.size())
#      90                 :          2 :             return set_error(err, bitcoinconsensus_ERR_TX_INDEX);
#      91         [ +  + ]:       1154 :         if (GetSerializeSize(tx, PROTOCOL_VERSION) != txToLen)
#      92                 :          2 :             return set_error(err, bitcoinconsensus_ERR_TX_SIZE_MISMATCH);
#      93                 :            : 
#      94                 :            :         // Regardless of the verification result, the tx did not error.
#      95                 :       1152 :         set_error(err, bitcoinconsensus_ERR_OK);
#      96                 :            : 
#      97                 :       1152 :         PrecomputedTransactionData txdata(tx);
#      98                 :       1152 :         return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), &tx.vin[nIn].scriptWitness, flags, TransactionSignatureChecker(&tx, nIn, amount, txdata, MissingDataBehavior::FAIL), nullptr);
#      99                 :       1154 :     } catch (const std::exception&) {
#     100                 :          2 :         return set_error(err, bitcoinconsensus_ERR_TX_DESERIALIZE); // Error deserializing
#     101                 :          2 :     }
#     102                 :       1156 : }
#     103                 :            : 
#     104                 :            : int bitcoinconsensus_verify_script_with_amount(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, int64_t amount,
#     105                 :            :                                     const unsigned char *txTo        , unsigned int txToLen,
#     106                 :            :                                     unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err)
#     107                 :        658 : {
#     108                 :        658 :     CAmount am(amount);
#     109                 :        658 :     return ::verify_script(scriptPubKey, scriptPubKeyLen, am, txTo, txToLen, nIn, flags, err);
#     110                 :        658 : }
#     111                 :            : 
#     112                 :            : 
#     113                 :            : int bitcoinconsensus_verify_script(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen,
#     114                 :            :                                    const unsigned char *txTo        , unsigned int txToLen,
#     115                 :            :                                    unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err)
#     116                 :        502 : {
#     117         [ +  + ]:        502 :     if (flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS) {
#     118                 :          2 :         return set_error(err, bitcoinconsensus_ERR_AMOUNT_REQUIRED);
#     119                 :          2 :     }
#     120                 :            : 
#     121                 :        500 :     CAmount am(0);
#     122                 :        500 :     return ::verify_script(scriptPubKey, scriptPubKeyLen, am, txTo, txToLen, nIn, flags, err);
#     123                 :        502 : }
#     124                 :            : 
#     125                 :            : unsigned int bitcoinconsensus_version()
#     126                 :          0 : {
#     127                 :            :     // Just use the API version for now
#     128                 :          0 :     return BITCOINCONSENSUS_API_VER;
#     129                 :          0 : }

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