LCOV - code coverage report
Current view: top level - src/script - bitcoinconsensus.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 50 54 92.6 %
Date: 2020-09-26 01:30:44 Functions: 20 21 95.2 %

          Line data    Source code
       1             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2018 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        1170 :     TxInputStream(int nTypeIn, int nVersionIn, const unsigned char *txTo, size_t txToLen) :
      20         585 :     m_type(nTypeIn),
      21         585 :     m_version(nVersionIn),
      22         585 :     m_data(txTo),
      23         585 :     m_remaining(txToLen)
      24        1170 :     {}
      25             : 
      26        7107 :     void read(char* pch, size_t nSize)
      27             :     {
      28        7107 :         if (nSize > m_remaining)
      29           1 :             throw std::ios_base::failure(std::string(__func__) + ": end of data");
      30             : 
      31        7106 :         if (pch == nullptr)
      32           0 :             throw std::ios_base::failure(std::string(__func__) + ": bad destination buffer");
      33             : 
      34        7106 :         if (m_data == nullptr)
      35           0 :             throw std::ios_base::failure(std::string(__func__) + ": bad source buffer");
      36             : 
      37        7106 :         memcpy(pch, m_data, nSize);
      38        7106 :         m_remaining -= nSize;
      39        7106 :         m_data += nSize;
      40        7107 :     }
      41             : 
      42             :     template<typename T>
      43        2665 :     TxInputStream& operator>>(T&& obj)
      44             :     {
      45        2665 :         ::Unserialize(*this, obj);
      46        2665 :         return *this;
      47             :     }
      48             : 
      49         585 :     int GetVersion() const { return m_version; }
      50             :     int GetType() const { return m_type; }
      51             : private:
      52             :     const int m_type;
      53             :     const int m_version;
      54             :     const unsigned char* m_data;
      55             :     size_t m_remaining;
      56             : };
      57             : 
      58         587 : inline int set_error(bitcoinconsensus_error* ret, bitcoinconsensus_error serror)
      59             : {
      60         587 :     if (ret)
      61           6 :         *ret = serror;
      62         587 :     return 0;
      63             : }
      64             : 
      65         360 : struct ECCryptoClosure
      66             : {
      67             :     ECCVerifyHandle handle;
      68             : };
      69             : 
      70          90 : ECCryptoClosure instance_of_eccryptoclosure;
      71             : } // namespace
      72             : 
      73             : /** Check that all specified flags are part of the libconsensus interface. */
      74         586 : static bool verify_flags(unsigned int flags)
      75             : {
      76         586 :     return (flags & ~(bitcoinconsensus_SCRIPT_FLAGS_VERIFY_ALL)) == 0;
      77             : }
      78             : 
      79         586 : 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             : {
      83         586 :     if (!verify_flags(flags)) {
      84           1 :         return set_error(err, bitcoinconsensus_ERR_INVALID_FLAGS);
      85             :     }
      86             :     try {
      87         585 :         TxInputStream stream(SER_NETWORK, PROTOCOL_VERSION, txTo, txToLen);
      88         585 :         CTransaction tx(deserialize, stream);
      89         584 :         if (nIn >= tx.vin.size())
      90           1 :             return set_error(err, bitcoinconsensus_ERR_TX_INDEX);
      91         583 :         if (GetSerializeSize(tx, PROTOCOL_VERSION) != txToLen)
      92           1 :             return set_error(err, bitcoinconsensus_ERR_TX_SIZE_MISMATCH);
      93             : 
      94             :         // Regardless of the verification result, the tx did not error.
      95         582 :         set_error(err, bitcoinconsensus_ERR_OK);
      96             : 
      97         582 :         PrecomputedTransactionData txdata(tx);
      98         582 :         return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), &tx.vin[nIn].scriptWitness, flags, TransactionSignatureChecker(&tx, nIn, amount, txdata), nullptr);
      99         585 :     } catch (const std::exception&) {
     100           1 :         return set_error(err, bitcoinconsensus_ERR_TX_DESERIALIZE); // Error deserializing
     101           1 :     }
     102         587 : }
     103             : 
     104         336 : 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             : {
     108             :     CAmount am(amount);
     109         336 :     return ::verify_script(scriptPubKey, scriptPubKeyLen, am, txTo, txToLen, nIn, flags, err);
     110             : }
     111             : 
     112             : 
     113         251 : 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             : {
     117         251 :     if (flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS) {
     118           1 :         return set_error(err, bitcoinconsensus_ERR_AMOUNT_REQUIRED);
     119             :     }
     120             : 
     121             :     CAmount am(0);
     122         250 :     return ::verify_script(scriptPubKey, scriptPubKeyLen, am, txTo, txToLen, nIn, flags, err);
     123         251 : }
     124             : 
     125           0 : unsigned int bitcoinconsensus_version()
     126             : {
     127             :     // Just use the API version for now
     128           0 :     return BITCOINCONSENSUS_API_VER;
     129             : }

Generated by: LCOV version 1.15