LCOV - code coverage report
Current view: top level - src/primitives - transaction.h (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 141 147 95.9 %
Date: 2021-06-29 14:35:33 Functions: 129 138 93.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: 168 240 70.0 %

           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_PRIMITIVES_TRANSACTION_H
#       7                 :            : #define BITCOIN_PRIMITIVES_TRANSACTION_H
#       8                 :            : 
#       9                 :            : #include <stdint.h>
#      10                 :            : #include <amount.h>
#      11                 :            : #include <script/script.h>
#      12                 :            : #include <serialize.h>
#      13                 :            : #include <uint256.h>
#      14                 :            : 
#      15                 :            : #include <tuple>
#      16                 :            : 
#      17                 :            : /**
#      18                 :            :  * A flag that is ORed into the protocol version to designate that a transaction
#      19                 :            :  * should be (un)serialized without witness data.
#      20                 :            :  * Make sure that this does not collide with any of the values in `version.h`
#      21                 :            :  * or with `ADDRV2_FORMAT`.
#      22                 :            :  */
#      23                 :            : static const int SERIALIZE_TRANSACTION_NO_WITNESS = 0x40000000;
#      24                 :            : 
#      25                 :            : /** An outpoint - a combination of a transaction hash and an index n into its vout */
#      26                 :            : class COutPoint
#      27                 :            : {
#      28                 :            : public:
#      29                 :            :     uint256 hash;
#      30                 :            :     uint32_t n;
#      31                 :            : 
#      32                 :            :     static constexpr uint32_t NULL_INDEX = std::numeric_limits<uint32_t>::max();
#      33                 :            : 
#      34                 :    8864003 :     COutPoint(): n(NULL_INDEX) { }
#      35                 :   23460775 :     COutPoint(const uint256& hashIn, uint32_t nIn): hash(hashIn), n(nIn) { }
#      36                 :            : 
#      37                 :   53319503 :     SERIALIZE_METHODS(COutPoint, obj) { READWRITE(obj.hash, obj.n); }
#      38                 :            : 
#      39                 :      32998 :     void SetNull() { hash.SetNull(); n = NULL_INDEX; }
#      40 [ +  + ][ +  + ]:   16401790 :     bool IsNull() const { return (hash.IsNull() && n == NULL_INDEX); }
#      41                 :            : 
#      42                 :            :     friend bool operator<(const COutPoint& a, const COutPoint& b)
#      43                 :  322929604 :     {
#      44                 :  322929604 :         int cmp = a.hash.Compare(b.hash);
#      45 [ +  + ][ +  + ]:  322929604 :         return cmp < 0 || (cmp == 0 && a.n < b.n);
#                 [ +  + ]
#      46                 :  322929604 :     }
#      47                 :            : 
#      48                 :            :     friend bool operator==(const COutPoint& a, const COutPoint& b)
#      49                 :   54316418 :     {
#      50 [ +  + ][ +  + ]:   54316418 :         return (a.hash == b.hash && a.n == b.n);
#      51                 :   54316418 :     }
#      52                 :            : 
#      53                 :            :     friend bool operator!=(const COutPoint& a, const COutPoint& b)
#      54                 :          0 :     {
#      55                 :          0 :         return !(a == b);
#      56                 :          0 :     }
#      57                 :            : 
#      58                 :            :     std::string ToString() const;
#      59                 :            : };
#      60                 :            : 
#      61                 :            : /** An input of a transaction.  It contains the location of the previous
#      62                 :            :  * transaction's output that it claims and a signature that matches the
#      63                 :            :  * output's public key.
#      64                 :            :  */
#      65                 :            : class CTxIn
#      66                 :            : {
#      67                 :            : public:
#      68                 :            :     COutPoint prevout;
#      69                 :            :     CScript scriptSig;
#      70                 :            :     uint32_t nSequence;
#      71                 :            :     CScriptWitness scriptWitness; //!< Only serialized through CTransaction
#      72                 :            : 
#      73                 :            :     /* Setting nSequence to this value for every input in a transaction
#      74                 :            :      * disables nLockTime. */
#      75                 :            :     static const uint32_t SEQUENCE_FINAL = 0xffffffff;
#      76                 :            : 
#      77                 :            :     /* Below flags apply in the context of BIP 68*/
#      78                 :            :     /* If this flag set, CTxIn::nSequence is NOT interpreted as a
#      79                 :            :      * relative lock-time. */
#      80                 :            :     static const uint32_t SEQUENCE_LOCKTIME_DISABLE_FLAG = (1U << 31);
#      81                 :            : 
#      82                 :            :     /* If CTxIn::nSequence encodes a relative lock-time and this flag
#      83                 :            :      * is set, the relative lock-time has units of 512 seconds,
#      84                 :            :      * otherwise it specifies blocks with a granularity of 1. */
#      85                 :            :     static const uint32_t SEQUENCE_LOCKTIME_TYPE_FLAG = (1 << 22);
#      86                 :            : 
#      87                 :            :     /* If CTxIn::nSequence encodes a relative lock-time, this mask is
#      88                 :            :      * applied to extract that lock-time from the sequence field. */
#      89                 :            :     static const uint32_t SEQUENCE_LOCKTIME_MASK = 0x0000ffff;
#      90                 :            : 
#      91                 :            :     /* In order to use the same number of bits to encode roughly the
#      92                 :            :      * same wall-clock duration, and because blocks are naturally
#      93                 :            :      * limited to occur every 600s on average, the minimum granularity
#      94                 :            :      * for time-based relative lock-time is fixed at 512 seconds.
#      95                 :            :      * Converting from CTxIn::nSequence to seconds is performed by
#      96                 :            :      * multiplying by 512 = 2^9, or equivalently shifting up by
#      97                 :            :      * 9 bits. */
#      98                 :            :     static const int SEQUENCE_LOCKTIME_GRANULARITY = 9;
#      99                 :            : 
#     100                 :            :     CTxIn()
#     101                 :    5673171 :     {
#     102                 :    5673171 :         nSequence = SEQUENCE_FINAL;
#     103                 :    5673171 :     }
#     104                 :            : 
#     105                 :            :     explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=SEQUENCE_FINAL);
#     106                 :            :     CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=SEQUENCE_FINAL);
#     107                 :            : 
#     108                 :    6086686 :     SERIALIZE_METHODS(CTxIn, obj) { READWRITE(obj.prevout, obj.scriptSig, obj.nSequence); }
#     109                 :            : 
#     110                 :            :     friend bool operator==(const CTxIn& a, const CTxIn& b)
#     111                 :        146 :     {
#     112         [ +  + ]:        146 :         return (a.prevout   == b.prevout &&
#     113         [ +  - ]:        146 :                 a.scriptSig == b.scriptSig &&
#     114         [ +  - ]:        146 :                 a.nSequence == b.nSequence);
#     115                 :        146 :     }
#     116                 :            : 
#     117                 :            :     friend bool operator!=(const CTxIn& a, const CTxIn& b)
#     118                 :          0 :     {
#     119                 :          0 :         return !(a == b);
#     120                 :          0 :     }
#     121                 :            : 
#     122                 :            :     std::string ToString() const;
#     123                 :            : };
#     124                 :            : 
#     125                 :            : /** An output of a transaction.  It contains the public key that the next input
#     126                 :            :  * must be able to sign with to claim it.
#     127                 :            :  */
#     128                 :            : class CTxOut
#     129                 :            : {
#     130                 :            : public:
#     131                 :            :     CAmount nValue;
#     132                 :            :     CScript scriptPubKey;
#     133                 :            : 
#     134                 :            :     CTxOut()
#     135                 :   87086333 :     {
#     136                 :   87086333 :         SetNull();
#     137                 :   87086333 :     }
#     138                 :            : 
#     139                 :            :     CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn);
#     140                 :            : 
#     141                 :   43445144 :     SERIALIZE_METHODS(CTxOut, obj) { READWRITE(obj.nValue, obj.scriptPubKey); }
#     142                 :            : 
#     143                 :            :     void SetNull()
#     144                 :   94953331 :     {
#     145                 :   94953331 :         nValue = -1;
#     146                 :   94953331 :         scriptPubKey.clear();
#     147                 :   94953331 :     }
#     148                 :            : 
#     149                 :            :     bool IsNull() const
#     150                 :   90327525 :     {
#     151                 :   90327525 :         return (nValue == -1);
#     152                 :   90327525 :     }
#     153                 :            : 
#     154                 :            :     friend bool operator==(const CTxOut& a, const CTxOut& b)
#     155                 :     732502 :     {
#     156         [ +  - ]:     732502 :         return (a.nValue       == b.nValue &&
#     157         [ +  - ]:     732502 :                 a.scriptPubKey == b.scriptPubKey);
#     158                 :     732502 :     }
#     159                 :            : 
#     160                 :            :     friend bool operator!=(const CTxOut& a, const CTxOut& b)
#     161                 :      22341 :     {
#     162                 :      22341 :         return !(a == b);
#     163                 :      22341 :     }
#     164                 :            : 
#     165                 :            :     std::string ToString() const;
#     166                 :            : };
#     167                 :            : 
#     168                 :            : struct CMutableTransaction;
#     169                 :            : 
#     170                 :            : /**
#     171                 :            :  * Basic transaction serialization format:
#     172                 :            :  * - int32_t nVersion
#     173                 :            :  * - std::vector<CTxIn> vin
#     174                 :            :  * - std::vector<CTxOut> vout
#     175                 :            :  * - uint32_t nLockTime
#     176                 :            :  *
#     177                 :            :  * Extended transaction serialization format:
#     178                 :            :  * - int32_t nVersion
#     179                 :            :  * - unsigned char dummy = 0x00
#     180                 :            :  * - unsigned char flags (!= 0)
#     181                 :            :  * - std::vector<CTxIn> vin
#     182                 :            :  * - std::vector<CTxOut> vout
#     183                 :            :  * - if (flags & 1):
#     184                 :            :  *   - CTxWitness wit;
#     185                 :            :  * - uint32_t nLockTime
#     186                 :            :  */
#     187                 :            : template<typename Stream, typename TxType>
#     188                 :     266137 : inline void UnserializeTransaction(TxType& tx, Stream& s) {
#     189                 :     266137 :     const bool fAllowWitness = !(s.GetVersion() & SERIALIZE_TRANSACTION_NO_WITNESS);
#     190                 :            : 
#     191                 :     266137 :     s >> tx.nVersion;
#     192                 :     266137 :     unsigned char flags = 0;
#     193                 :     266137 :     tx.vin.clear();
#     194                 :     266137 :     tx.vout.clear();
#     195                 :            :     /* Try to read the vin. In case the dummy is there, this will be read as an empty vector. */
#     196                 :     266137 :     s >> tx.vin;
#     197 [ #  # ][ +  + ]:     266137 :     if (tx.vin.size() == 0 && fAllowWitness) {
#         [ +  + ][ +  + ]
#         [ +  + ][ +  + ]
#         [ #  # ][ +  - ]
#         [ +  + ][ +  + ]
#         [ +  - ][ +  - ]
#     198                 :            :         /* We read a dummy or an empty vin. */
#     199                 :     170688 :         s >> flags;
#     200 [ #  # ][ +  - ]:     170688 :         if (flags != 0) {
#         [ +  - ][ +  + ]
#         [ +  - ][ +  - ]
#     201                 :     170676 :             s >> tx.vin;
#     202                 :     170676 :             s >> tx.vout;
#     203                 :     170676 :         }
#     204                 :     170688 :     } else {
#     205                 :            :         /* We read a non-empty vin. Assume a normal vout follows. */
#     206                 :      95449 :         s >> tx.vout;
#     207                 :      95449 :     }
#     208 [ +  + ][ #  # ]:     266137 :     if ((flags & 1) && fAllowWitness) {
#         [ +  + ][ +  + ]
#         [ +  + ][ +  + ]
#         [ +  - ][ +  - ]
#         [ +  - ][ +  - ]
#         [ #  # ][ +  - ]
#     209                 :            :         /* The witness flag is present, and we support witnesses. */
#     210                 :     170436 :         flags ^= 1;
#     211 [ +  + ][ +  + ]:     428106 :         for (size_t i = 0; i < tx.vin.size(); i++) {
#         [ +  + ][ #  # ]
#         [ +  + ][ +  + ]
#     212                 :     257670 :             s >> tx.vin[i].scriptWitness.stack;
#     213                 :     257670 :         }
#     214 [ +  + ][ -  + ]:     170436 :         if (!tx.HasWitness()) {
#         [ -  + ][ -  + ]
#         [ #  # ][ -  + ]
#     215                 :            :             /* It's illegal to encode witnesses when all witness stacks are empty. */
#     216                 :          6 :             throw std::ios_base::failure("Superfluous witness record");
#     217                 :          6 :         }
#     218                 :     266131 :     }
#     219 [ -  + ][ -  + ]:     266131 :     if (flags) {
#         [ #  # ][ -  + ]
#         [ +  + ][ -  + ]
#     220                 :            :         /* Unknown flag in the serialization */
#     221                 :          2 :         throw std::ios_base::failure("Unknown transaction optional data");
#     222                 :          2 :     }
#     223                 :     266129 :     s >> tx.nLockTime;
#     224                 :     266129 : }
#     225                 :            : 
#     226                 :            : template<typename Stream, typename TxType>
#     227                 :    3668394 : inline void SerializeTransaction(const TxType& tx, Stream& s) {
#     228                 :    3668394 :     const bool fAllowWitness = !(s.GetVersion() & SERIALIZE_TRANSACTION_NO_WITNESS);
#     229                 :            : 
#     230                 :    3668394 :     s << tx.nVersion;
#     231                 :    3668394 :     unsigned char flags = 0;
#     232                 :            :     // Consistency check
#     233 [ +  + ][ +  - ]:    3668394 :     if (fAllowWitness) {
#         [ +  + ][ +  - ]
#         [ -  + ][ +  + ]
#         [ +  + ][ +  + ]
#         [ -  + ][ +  + ]
#     234                 :            :         /* Check whether witnesses need to be serialized. */
#     235 [ -  + ][ #  # ]:    1183872 :         if (tx.HasWitness()) {
#         [ -  + ][ +  + ]
#         [ +  - ][ #  # ]
#         [ +  + ][ +  + ]
#         [ +  + ][ +  + ]
#     236                 :     732715 :             flags |= 1;
#     237                 :     732715 :         }
#     238                 :    1183872 :     }
#     239 [ -  + ][ -  + ]:    3668394 :     if (flags) {
#         [ -  + ][ +  + ]
#         [ +  + ][ +  + ]
#         [ +  + ][ +  + ]
#         [ -  + ][ +  + ]
#     240                 :            :         /* Use extended format in case witnesses are to be serialized. */
#     241                 :     732715 :         std::vector<CTxIn> vinDummy;
#     242                 :     732715 :         s << vinDummy;
#     243                 :     732715 :         s << flags;
#     244                 :     732715 :     }
#     245                 :    3668394 :     s << tx.vin;
#     246                 :    3668394 :     s << tx.vout;
#     247 [ -  + ][ +  + ]:    3668394 :     if (flags & 1) {
#         [ +  + ][ +  + ]
#         [ -  + ][ -  + ]
#         [ -  + ][ +  + ]
#         [ +  + ][ +  + ]
#     248 [ +  + ][ +  + ]:    1892655 :         for (size_t i = 0; i < tx.vin.size(); i++) {
#         [ +  + ][ #  # ]
#         [ +  + ][ #  # ]
#         [ #  # ][ +  + ]
#         [ #  # ][ +  + ]
#     249                 :    1159940 :             s << tx.vin[i].scriptWitness.stack;
#     250                 :    1159940 :         }
#     251                 :     732715 :     }
#     252                 :    3668394 :     s << tx.nLockTime;
#     253                 :    3668394 : }
#     254                 :            : 
#     255                 :            : 
#     256                 :            : /** The basic transaction that is broadcasted on the network and contained in
#     257                 :            :  * blocks.  A transaction can contain multiple inputs and outputs.
#     258                 :            :  */
#     259                 :            : class CTransaction
#     260                 :            : {
#     261                 :            : public:
#     262                 :            :     // Default transaction version.
#     263                 :            :     static const int32_t CURRENT_VERSION=2;
#     264                 :            : 
#     265                 :            :     // The local variables are made const to prevent unintended modification
#     266                 :            :     // without updating the cached hash value. However, CTransaction is not
#     267                 :            :     // actually immutable; deserialization and assignment are implemented,
#     268                 :            :     // and bypass the constness. This is safe, as they update the entire
#     269                 :            :     // structure, including the hash.
#     270                 :            :     const std::vector<CTxIn> vin;
#     271                 :            :     const std::vector<CTxOut> vout;
#     272                 :            :     const int32_t nVersion;
#     273                 :            :     const uint32_t nLockTime;
#     274                 :            : 
#     275                 :            : private:
#     276                 :            :     /** Memory only. */
#     277                 :            :     const uint256 hash;
#     278                 :            :     const uint256 m_witness_hash;
#     279                 :            : 
#     280                 :            :     uint256 ComputeHash() const;
#     281                 :            :     uint256 ComputeWitnessHash() const;
#     282                 :            : 
#     283                 :            : public:
#     284                 :            :     /** Convert a CMutableTransaction into a CTransaction. */
#     285                 :            :     explicit CTransaction(const CMutableTransaction& tx);
#     286                 :            :     CTransaction(CMutableTransaction&& tx);
#     287                 :            : 
#     288                 :            :     template <typename Stream>
#     289                 :    3428112 :     inline void Serialize(Stream& s) const {
#     290                 :    3428112 :         SerializeTransaction(*this, s);
#     291                 :    3428112 :     }
#     292                 :            : 
#     293                 :            :     /** This deserializing constructor is provided instead of an Unserialize method.
#     294                 :            :      *  Unserialize is not possible, since it would require overwriting const fields. */
#     295                 :            :     template <typename Stream>
#     296                 :     250342 :     CTransaction(deserialize_type, Stream& s) : CTransaction(CMutableTransaction(deserialize, s)) {}
#     297                 :            : 
#     298                 :      16750 :     bool IsNull() const {
#     299 [ -  + ][ #  # ]:      16750 :         return vin.empty() && vout.empty();
#     300                 :      16750 :     }
#     301                 :            : 
#     302                 : 2391645174 :     const uint256& GetHash() const { return hash; }
#     303                 :    6840026 :     const uint256& GetWitnessHash() const { return m_witness_hash; };
#     304                 :            : 
#     305                 :            :     // Return sum of txouts.
#     306                 :            :     CAmount GetValueOut() const;
#     307                 :            : 
#     308                 :            :     /**
#     309                 :            :      * Get the total transaction size in bytes, including witness data.
#     310                 :            :      * "Total Size" defined in BIP141 and BIP144.
#     311                 :            :      * @return Total transaction size in bytes
#     312                 :            :      */
#     313                 :            :     unsigned int GetTotalSize() const;
#     314                 :            : 
#     315                 :            :     bool IsCoinBase() const
#     316                 :   25508657 :     {
#     317 [ +  + ][ +  + ]:   25508657 :         return (vin.size() == 1 && vin[0].prevout.IsNull());
#     318                 :   25508657 :     }
#     319                 :            : 
#     320                 :            :     friend bool operator==(const CTransaction& a, const CTransaction& b)
#     321                 :       3433 :     {
#     322                 :       3433 :         return a.hash == b.hash;
#     323                 :       3433 :     }
#     324                 :            : 
#     325                 :            :     friend bool operator!=(const CTransaction& a, const CTransaction& b)
#     326                 :         52 :     {
#     327                 :         52 :         return a.hash != b.hash;
#     328                 :         52 :     }
#     329                 :            : 
#     330                 :            :     std::string ToString() const;
#     331                 :            : 
#     332                 :            :     bool HasWitness() const
#     333                 :    2693352 :     {
#     334         [ +  + ]:    4416570 :         for (size_t i = 0; i < vin.size(); i++) {
#     335         [ +  + ]:    2762930 :             if (!vin[i].scriptWitness.IsNull()) {
#     336                 :    1039712 :                 return true;
#     337                 :    1039712 :             }
#     338                 :    2762930 :         }
#     339                 :    2693352 :         return false;
#     340                 :    2693352 :     }
#     341                 :            : };
#     342                 :            : 
#     343                 :            : /** A mutable version of CTransaction. */
#     344                 :            : struct CMutableTransaction
#     345                 :            : {
#     346                 :            :     std::vector<CTxIn> vin;
#     347                 :            :     std::vector<CTxOut> vout;
#     348                 :            :     int32_t nVersion;
#     349                 :            :     uint32_t nLockTime;
#     350                 :            : 
#     351                 :            :     CMutableTransaction();
#     352                 :            :     explicit CMutableTransaction(const CTransaction& tx);
#     353                 :            : 
#     354                 :            :     template <typename Stream>
#     355                 :     240282 :     inline void Serialize(Stream& s) const {
#     356                 :     240282 :         SerializeTransaction(*this, s);
#     357                 :     240282 :     }
#     358                 :            : 
#     359                 :            : 
#     360                 :            :     template <typename Stream>
#     361                 :     266137 :     inline void Unserialize(Stream& s) {
#     362                 :     266137 :         UnserializeTransaction(*this, s);
#     363                 :     266137 :     }
#     364                 :            : 
#     365                 :            :     template <typename Stream>
#     366                 :     250342 :     CMutableTransaction(deserialize_type, Stream& s) {
#     367                 :     250342 :         Unserialize(s);
#     368                 :     250342 :     }
#     369                 :            : 
#     370                 :            :     /** Compute the hash of this CMutableTransaction. This is computed on the
#     371                 :            :      * fly, as opposed to GetHash() in CTransaction, which uses a cached result.
#     372                 :            :      */
#     373                 :            :     uint256 GetHash() const;
#     374                 :            : 
#     375                 :            :     bool HasWitness() const
#     376                 :     173237 :     {
#     377         [ +  + ]:     177169 :         for (size_t i = 0; i < vin.size(); i++) {
#     378         [ +  + ]:     174695 :             if (!vin[i].scriptWitness.IsNull()) {
#     379                 :     170763 :                 return true;
#     380                 :     170763 :             }
#     381                 :     174695 :         }
#     382                 :     173237 :         return false;
#     383                 :     173237 :     }
#     384                 :            : };
#     385                 :            : 
#     386                 :            : typedef std::shared_ptr<const CTransaction> CTransactionRef;
#     387                 :     706267 : template <typename Tx> static inline CTransactionRef MakeTransactionRef(Tx&& txIn) { return std::make_shared<const CTransaction>(std::forward<Tx>(txIn)); }
#     388                 :            : 
#     389                 :            : /** A generic txid reference (txid or wtxid). */
#     390                 :            : class GenTxid
#     391                 :            : {
#     392                 :            :     bool m_is_wtxid;
#     393                 :            :     uint256 m_hash;
#     394                 :            : public:
#     395                 :    2310007 :     GenTxid(bool is_wtxid, const uint256& hash) : m_is_wtxid(is_wtxid), m_hash(hash) {}
#     396                 :    2421109 :     bool IsWtxid() const { return m_is_wtxid; }
#     397                 :    2524388 :     const uint256& GetHash() const { return m_hash; }
#     398 [ +  - ][ +  - ]:      26420 :     friend bool operator==(const GenTxid& a, const GenTxid& b) { return a.m_is_wtxid == b.m_is_wtxid && a.m_hash == b.m_hash; }
#     399                 :       4160 :     friend bool operator<(const GenTxid& a, const GenTxid& b) { return std::tie(a.m_is_wtxid, a.m_hash) < std::tie(b.m_is_wtxid, b.m_hash); }
#     400                 :            : };
#     401                 :            : 
#     402                 :            : #endif // BITCOIN_PRIMITIVES_TRANSACTION_H

Generated by: LCOV version 1.14