Coverage Report

Created: 2025-06-10 13:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/bitcoin/src/primitives/transaction.h
Line
Count
Source
1
// Copyright (c) 2009-2010 Satoshi Nakamoto
2
// Copyright (c) 2009-2022 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 <attributes.h>
10
#include <consensus/amount.h>
11
#include <script/script.h>
12
#include <serialize.h>
13
#include <uint256.h>
14
#include <util/transaction_identifier.h> // IWYU pragma: export
15
16
#include <cstddef>
17
#include <cstdint>
18
#include <ios>
19
#include <limits>
20
#include <memory>
21
#include <numeric>
22
#include <string>
23
#include <tuple>
24
#include <utility>
25
#include <vector>
26
27
/** An outpoint - a combination of a transaction hash and an index n into its vout */
28
class COutPoint
29
{
30
public:
31
    Txid hash;
32
    uint32_t n;
33
34
    static constexpr uint32_t NULL_INDEX = std::numeric_limits<uint32_t>::max();
35
36
8.37M
    COutPoint(): n(NULL_INDEX) { }
37
12.5M
    COutPoint(const Txid& hashIn, uint32_t nIn): hash(hashIn), n(nIn) { }
38
39
27.0M
    SERIALIZE_METHODS(COutPoint, obj) { READWRITE(obj.hash, obj.n); }
void COutPoint::SerializationOps<ParamsStream<SizeComputer&, TransactionSerParams>, COutPoint const, ActionSerialize>(COutPoint const&, ParamsStream<SizeComputer&, TransactionSerParams>&, ActionSerialize)
Line
Count
Source
39
15.5M
    SERIALIZE_METHODS(COutPoint, obj) { READWRITE(obj.hash, obj.n); }
void COutPoint::SerializationOps<ParamsStream<VectorWriter&, TransactionSerParams>, COutPoint const, ActionSerialize>(COutPoint const&, ParamsStream<VectorWriter&, TransactionSerParams>&, ActionSerialize)
Line
Count
Source
39
10.2k
    SERIALIZE_METHODS(COutPoint, obj) { READWRITE(obj.hash, obj.n); }
void COutPoint::SerializationOps<ParamsStream<DataStream&, TransactionSerParams>, COutPoint, ActionUnserialize>(COutPoint&, ParamsStream<DataStream&, TransactionSerParams>&, ActionUnserialize)
Line
Count
Source
39
2.95M
    SERIALIZE_METHODS(COutPoint, obj) { READWRITE(obj.hash, obj.n); }
void COutPoint::SerializationOps<ParamsStream<SpanReader&, TransactionSerParams>, COutPoint, ActionUnserialize>(COutPoint&, ParamsStream<SpanReader&, TransactionSerParams>&, ActionUnserialize)
Line
Count
Source
39
66.5k
    SERIALIZE_METHODS(COutPoint, obj) { READWRITE(obj.hash, obj.n); }
void COutPoint::SerializationOps<ParamsStream<BufferedWriter<AutoFile>&, TransactionSerParams>, COutPoint const, ActionSerialize>(COutPoint const&, ParamsStream<BufferedWriter<AutoFile>&, TransactionSerParams>&, ActionSerialize)
Line
Count
Source
39
2.34M
    SERIALIZE_METHODS(COutPoint, obj) { READWRITE(obj.hash, obj.n); }
Unexecuted instantiation: void COutPoint::SerializationOps<ParamsStream<AutoFile&, TransactionSerParams>, COutPoint, ActionUnserialize>(COutPoint&, ParamsStream<AutoFile&, TransactionSerParams>&, ActionUnserialize)
void COutPoint::SerializationOps<ParamsStream<AutoFile&, TransactionSerParams>, COutPoint const, ActionSerialize>(COutPoint const&, ParamsStream<AutoFile&, TransactionSerParams>&, ActionSerialize)
Line
Count
Source
39
29.1k
    SERIALIZE_METHODS(COutPoint, obj) { READWRITE(obj.hash, obj.n); }
Unexecuted instantiation: void COutPoint::SerializationOps<ParamsStream<DataStream&, TransactionSerParams>, COutPoint const, ActionSerialize>(COutPoint const&, ParamsStream<DataStream&, TransactionSerParams>&, ActionSerialize)
Unexecuted instantiation: void COutPoint::SerializationOps<DataStream, COutPoint, ActionUnserialize>(COutPoint&, DataStream&, ActionUnserialize)
Unexecuted instantiation: void COutPoint::SerializationOps<ParamsStream<BufferedFile&, TransactionSerParams>, COutPoint, ActionUnserialize>(COutPoint&, ParamsStream<BufferedFile&, TransactionSerParams>&, ActionUnserialize)
void COutPoint::SerializationOps<HashWriter, COutPoint const, ActionSerialize>(COutPoint const&, HashWriter&, ActionSerialize)
Line
Count
Source
39
62.7k
    SERIALIZE_METHODS(COutPoint, obj) { READWRITE(obj.hash, obj.n); }
void COutPoint::SerializationOps<DataStream, COutPoint const, ActionSerialize>(COutPoint const&, DataStream&, ActionSerialize)
Line
Count
Source
39
449
    SERIALIZE_METHODS(COutPoint, obj) { READWRITE(obj.hash, obj.n); }
void COutPoint::SerializationOps<ParamsStream<HashWriter&, TransactionSerParams>, COutPoint const, ActionSerialize>(COutPoint const&, ParamsStream<HashWriter&, TransactionSerParams>&, ActionSerialize)
Line
Count
Source
39
6.02M
    SERIALIZE_METHODS(COutPoint, obj) { READWRITE(obj.hash, obj.n); }
40
41
0
    void SetNull() { hash.SetNull(); n = NULL_INDEX; }
42
24.6M
    bool IsNull() const { return (hash.IsNull() && n == NULL_INDEX); }
  Branch (42:35): [True: 17.9M, False: 6.75M]
  Branch (42:52): [True: 17.9M, False: 0]
43
44
    friend bool operator<(const COutPoint& a, const COutPoint& b)
45
20.7M
    {
46
20.7M
        return std::tie(a.hash, a.n) < std::tie(b.hash, b.n);
47
20.7M
    }
48
49
    friend bool operator==(const COutPoint& a, const COutPoint& b)
50
15.2M
    {
51
15.2M
        return (a.hash == b.hash && a.n == b.n);
  Branch (51:17): [True: 7.24M, False: 7.95M]
  Branch (51:37): [True: 7.20M, False: 38.9k]
52
15.2M
    }
53
54
    friend bool operator!=(const COutPoint& a, const COutPoint& b)
55
0
    {
56
0
        return !(a == b);
57
0
    }
58
59
    std::string ToString() const;
60
};
61
62
/** An input of a transaction.  It contains the location of the previous
63
 * transaction's output that it claims and a signature that matches the
64
 * output's public key.
65
 */
66
class CTxIn
67
{
68
public:
69
    COutPoint prevout;
70
    CScript scriptSig;
71
    uint32_t nSequence;
72
    CScriptWitness scriptWitness; //!< Only serialized through CTransaction
73
74
    /**
75
     * Setting nSequence to this value for every input in a transaction
76
     * disables nLockTime/IsFinalTx().
77
     * It fails OP_CHECKLOCKTIMEVERIFY/CheckLockTime() for any input that has
78
     * it set (BIP 65).
79
     * It has SEQUENCE_LOCKTIME_DISABLE_FLAG set (BIP 68/112).
80
     */
81
    static const uint32_t SEQUENCE_FINAL = 0xffffffff;
82
    /**
83
     * This is the maximum sequence number that enables both nLockTime and
84
     * OP_CHECKLOCKTIMEVERIFY (BIP 65).
85
     * It has SEQUENCE_LOCKTIME_DISABLE_FLAG set (BIP 68/112).
86
     */
87
    static const uint32_t MAX_SEQUENCE_NONFINAL{SEQUENCE_FINAL - 1};
88
89
    // Below flags apply in the context of BIP 68. BIP 68 requires the tx
90
    // version to be set to 2, or higher.
91
    /**
92
     * If this flag is set, CTxIn::nSequence is NOT interpreted as a
93
     * relative lock-time.
94
     * It skips SequenceLocks() for any input that has it set (BIP 68).
95
     * It fails OP_CHECKSEQUENCEVERIFY/CheckSequence() for any input that has
96
     * it set (BIP 112).
97
     */
98
    static const uint32_t SEQUENCE_LOCKTIME_DISABLE_FLAG = (1U << 31);
99
100
    /**
101
     * If CTxIn::nSequence encodes a relative lock-time and this flag
102
     * is set, the relative lock-time has units of 512 seconds,
103
     * otherwise it specifies blocks with a granularity of 1. */
104
    static const uint32_t SEQUENCE_LOCKTIME_TYPE_FLAG = (1 << 22);
105
106
    /**
107
     * If CTxIn::nSequence encodes a relative lock-time, this mask is
108
     * applied to extract that lock-time from the sequence field. */
109
    static const uint32_t SEQUENCE_LOCKTIME_MASK = 0x0000ffff;
110
111
    /**
112
     * In order to use the same number of bits to encode roughly the
113
     * same wall-clock duration, and because blocks are naturally
114
     * limited to occur every 600s on average, the minimum granularity
115
     * for time-based relative lock-time is fixed at 512 seconds.
116
     * Converting from CTxIn::nSequence to seconds is performed by
117
     * multiplying by 512 = 2^9, or equivalently shifting up by
118
     * 9 bits. */
119
    static const int SEQUENCE_LOCKTIME_GRANULARITY = 9;
120
121
    CTxIn()
122
3.09M
    {
123
3.09M
        nSequence = SEQUENCE_FINAL;
124
3.09M
    }
125
126
    explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=SEQUENCE_FINAL);
127
    CTxIn(Txid hashPrevTx, uint32_t nOut, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=SEQUENCE_FINAL);
128
129
27.0M
    SERIALIZE_METHODS(CTxIn, obj) { READWRITE(obj.prevout, obj.scriptSig, obj.nSequence); }
void CTxIn::SerializationOps<ParamsStream<SizeComputer&, TransactionSerParams>, CTxIn const, ActionSerialize>(CTxIn const&, ParamsStream<SizeComputer&, TransactionSerParams>&, ActionSerialize)
Line
Count
Source
129
15.5M
    SERIALIZE_METHODS(CTxIn, obj) { READWRITE(obj.prevout, obj.scriptSig, obj.nSequence); }
void CTxIn::SerializationOps<ParamsStream<VectorWriter&, TransactionSerParams>, CTxIn const, ActionSerialize>(CTxIn const&, ParamsStream<VectorWriter&, TransactionSerParams>&, ActionSerialize)
Line
Count
Source
129
10.2k
    SERIALIZE_METHODS(CTxIn, obj) { READWRITE(obj.prevout, obj.scriptSig, obj.nSequence); }
void CTxIn::SerializationOps<ParamsStream<DataStream&, TransactionSerParams>, CTxIn, ActionUnserialize>(CTxIn&, ParamsStream<DataStream&, TransactionSerParams>&, ActionUnserialize)
Line
Count
Source
129
2.95M
    SERIALIZE_METHODS(CTxIn, obj) { READWRITE(obj.prevout, obj.scriptSig, obj.nSequence); }
void CTxIn::SerializationOps<ParamsStream<SpanReader&, TransactionSerParams>, CTxIn, ActionUnserialize>(CTxIn&, ParamsStream<SpanReader&, TransactionSerParams>&, ActionUnserialize)
Line
Count
Source
129
66.5k
    SERIALIZE_METHODS(CTxIn, obj) { READWRITE(obj.prevout, obj.scriptSig, obj.nSequence); }
void CTxIn::SerializationOps<ParamsStream<BufferedWriter<AutoFile>&, TransactionSerParams>, CTxIn const, ActionSerialize>(CTxIn const&, ParamsStream<BufferedWriter<AutoFile>&, TransactionSerParams>&, ActionSerialize)
Line
Count
Source
129
2.34M
    SERIALIZE_METHODS(CTxIn, obj) { READWRITE(obj.prevout, obj.scriptSig, obj.nSequence); }
Unexecuted instantiation: void CTxIn::SerializationOps<ParamsStream<AutoFile&, TransactionSerParams>, CTxIn, ActionUnserialize>(CTxIn&, ParamsStream<AutoFile&, TransactionSerParams>&, ActionUnserialize)
void CTxIn::SerializationOps<ParamsStream<AutoFile&, TransactionSerParams>, CTxIn const, ActionSerialize>(CTxIn const&, ParamsStream<AutoFile&, TransactionSerParams>&, ActionSerialize)
Line
Count
Source
129
29.1k
    SERIALIZE_METHODS(CTxIn, obj) { READWRITE(obj.prevout, obj.scriptSig, obj.nSequence); }
Unexecuted instantiation: void CTxIn::SerializationOps<ParamsStream<DataStream&, TransactionSerParams>, CTxIn const, ActionSerialize>(CTxIn const&, ParamsStream<DataStream&, TransactionSerParams>&, ActionSerialize)
Unexecuted instantiation: void CTxIn::SerializationOps<ParamsStream<BufferedFile&, TransactionSerParams>, CTxIn, ActionUnserialize>(CTxIn&, ParamsStream<BufferedFile&, TransactionSerParams>&, ActionUnserialize)
void CTxIn::SerializationOps<ParamsStream<HashWriter&, TransactionSerParams>, CTxIn const, ActionSerialize>(CTxIn const&, ParamsStream<HashWriter&, TransactionSerParams>&, ActionSerialize)
Line
Count
Source
129
6.02M
    SERIALIZE_METHODS(CTxIn, obj) { READWRITE(obj.prevout, obj.scriptSig, obj.nSequence); }
130
131
    friend bool operator==(const CTxIn& a, const CTxIn& b)
132
0
    {
133
0
        return (a.prevout   == b.prevout &&
  Branch (133:17): [True: 0, False: 0]
134
0
                a.scriptSig == b.scriptSig &&
  Branch (134:17): [True: 0, False: 0]
135
0
                a.nSequence == b.nSequence);
  Branch (135:17): [True: 0, False: 0]
136
0
    }
137
138
    friend bool operator!=(const CTxIn& a, const CTxIn& b)
139
0
    {
140
0
        return !(a == b);
141
0
    }
142
143
    std::string ToString() const;
144
};
145
146
/** An output of a transaction.  It contains the public key that the next input
147
 * must be able to sign with to claim it.
148
 */
149
class CTxOut
150
{
151
public:
152
    CAmount nValue;
153
    CScript scriptPubKey;
154
155
    CTxOut()
156
31.8M
    {
157
31.8M
        SetNull();
158
31.8M
    }
159
160
    CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn);
161
162
47.5M
    SERIALIZE_METHODS(CTxOut, obj) { READWRITE(obj.nValue, obj.scriptPubKey); }
void CTxOut::SerializationOps<ParamsStream<SizeComputer&, TransactionSerParams>, CTxOut const, ActionSerialize>(CTxOut const&, ParamsStream<SizeComputer&, TransactionSerParams>&, ActionSerialize)
Line
Count
Source
162
26.5M
    SERIALIZE_METHODS(CTxOut, obj) { READWRITE(obj.nValue, obj.scriptPubKey); }
void CTxOut::SerializationOps<ParamsStream<VectorWriter&, TransactionSerParams>, CTxOut const, ActionSerialize>(CTxOut const&, ParamsStream<VectorWriter&, TransactionSerParams>&, ActionSerialize)
Line
Count
Source
162
17.1k
    SERIALIZE_METHODS(CTxOut, obj) { READWRITE(obj.nValue, obj.scriptPubKey); }
void CTxOut::SerializationOps<ParamsStream<DataStream&, TransactionSerParams>, CTxOut, ActionUnserialize>(CTxOut&, ParamsStream<DataStream&, TransactionSerParams>&, ActionUnserialize)
Line
Count
Source
162
5.18M
    SERIALIZE_METHODS(CTxOut, obj) { READWRITE(obj.nValue, obj.scriptPubKey); }
void CTxOut::SerializationOps<ParamsStream<SpanReader&, TransactionSerParams>, CTxOut, ActionUnserialize>(CTxOut&, ParamsStream<SpanReader&, TransactionSerParams>&, ActionUnserialize)
Line
Count
Source
162
85.0k
    SERIALIZE_METHODS(CTxOut, obj) { READWRITE(obj.nValue, obj.scriptPubKey); }
void CTxOut::SerializationOps<ParamsStream<BufferedWriter<AutoFile>&, TransactionSerParams>, CTxOut const, ActionSerialize>(CTxOut const&, ParamsStream<BufferedWriter<AutoFile>&, TransactionSerParams>&, ActionSerialize)
Line
Count
Source
162
4.58M
    SERIALIZE_METHODS(CTxOut, obj) { READWRITE(obj.nValue, obj.scriptPubKey); }
Unexecuted instantiation: void CTxOut::SerializationOps<ParamsStream<AutoFile&, TransactionSerParams>, CTxOut, ActionUnserialize>(CTxOut&, ParamsStream<AutoFile&, TransactionSerParams>&, ActionUnserialize)
void CTxOut::SerializationOps<ParamsStream<AutoFile&, TransactionSerParams>, CTxOut const, ActionSerialize>(CTxOut const&, ParamsStream<AutoFile&, TransactionSerParams>&, ActionSerialize)
Line
Count
Source
162
30.4k
    SERIALIZE_METHODS(CTxOut, obj) { READWRITE(obj.nValue, obj.scriptPubKey); }
Unexecuted instantiation: void CTxOut::SerializationOps<ParamsStream<DataStream&, TransactionSerParams>, CTxOut const, ActionSerialize>(CTxOut const&, ParamsStream<DataStream&, TransactionSerParams>&, ActionSerialize)
Unexecuted instantiation: void CTxOut::SerializationOps<DataStream, CTxOut const, ActionSerialize>(CTxOut const&, DataStream&, ActionSerialize)
void CTxOut::SerializationOps<SizeComputer, CTxOut const, ActionSerialize>(CTxOut const&, SizeComputer&, ActionSerialize)
Line
Count
Source
162
521k
    SERIALIZE_METHODS(CTxOut, obj) { READWRITE(obj.nValue, obj.scriptPubKey); }
Unexecuted instantiation: void CTxOut::SerializationOps<ParamsStream<BufferedFile&, TransactionSerParams>, CTxOut, ActionUnserialize>(CTxOut&, ParamsStream<BufferedFile&, TransactionSerParams>&, ActionUnserialize)
void CTxOut::SerializationOps<HashWriter, CTxOut const, ActionSerialize>(CTxOut const&, HashWriter&, ActionSerialize)
Line
Count
Source
162
67.1k
    SERIALIZE_METHODS(CTxOut, obj) { READWRITE(obj.nValue, obj.scriptPubKey); }
Unexecuted instantiation: void CTxOut::SerializationOps<DataStream, CTxOut, ActionUnserialize>(CTxOut&, DataStream&, ActionUnserialize)
void CTxOut::SerializationOps<ParamsStream<HashWriter&, TransactionSerParams>, CTxOut const, ActionSerialize>(CTxOut const&, ParamsStream<HashWriter&, TransactionSerParams>&, ActionSerialize)
Line
Count
Source
162
10.5M
    SERIALIZE_METHODS(CTxOut, obj) { READWRITE(obj.nValue, obj.scriptPubKey); }
163
164
    void SetNull()
165
32.2M
    {
166
32.2M
        nValue = -1;
167
32.2M
        scriptPubKey.clear();
168
32.2M
    }
169
170
    bool IsNull() const
171
20.1M
    {
172
20.1M
        return (nValue == -1);
173
20.1M
    }
174
175
    friend bool operator==(const CTxOut& a, const CTxOut& b)
176
60.9k
    {
177
60.9k
        return (a.nValue       == b.nValue &&
  Branch (177:17): [True: 60.9k, False: 0]
178
60.9k
                a.scriptPubKey == b.scriptPubKey);
  Branch (178:17): [True: 60.9k, False: 0]
179
60.9k
    }
180
181
    friend bool operator!=(const CTxOut& a, const CTxOut& b)
182
15.4k
    {
183
15.4k
        return !(a == b);
184
15.4k
    }
185
186
    std::string ToString() const;
187
};
188
189
struct CMutableTransaction;
190
191
struct TransactionSerParams {
192
    const bool allow_witness;
193
    SER_PARAMS_OPFUNC
194
};
195
static constexpr TransactionSerParams TX_WITH_WITNESS{.allow_witness = true};
196
static constexpr TransactionSerParams TX_NO_WITNESS{.allow_witness = false};
197
198
/**
199
 * Basic transaction serialization format:
200
 * - uint32_t version
201
 * - std::vector<CTxIn> vin
202
 * - std::vector<CTxOut> vout
203
 * - uint32_t nLockTime
204
 *
205
 * Extended transaction serialization format:
206
 * - uint32_t version
207
 * - unsigned char dummy = 0x00
208
 * - unsigned char flags (!= 0)
209
 * - std::vector<CTxIn> vin
210
 * - std::vector<CTxOut> vout
211
 * - if (flags & 1):
212
 *   - CScriptWitness scriptWitness; (deserialized into CTxIn)
213
 * - uint32_t nLockTime
214
 */
215
template<typename Stream, typename TxType>
216
void UnserializeTransaction(TxType& tx, Stream& s, const TransactionSerParams& params)
217
2.92M
{
218
2.92M
    const bool fAllowWitness = params.allow_witness;
219
220
2.92M
    s >> tx.version;
221
2.92M
    unsigned char flags = 0;
222
2.92M
    tx.vin.clear();
223
2.92M
    tx.vout.clear();
224
    /* Try to read the vin. In case the dummy is there, this will be read as an empty vector. */
225
2.92M
    s >> tx.vin;
226
2.92M
    if (tx.vin.size() == 0 && fAllowWitness) {
  Branch (226:9): [True: 2.79M, False: 67.2k]
  Branch (226:31): [True: 2.79M, False: 0]
  Branch (226:9): [True: 50.7k, False: 13.0k]
  Branch (226:31): [True: 50.7k, False: 0]
  Branch (226:9): [True: 0, False: 0]
  Branch (226:31): [True: 0, False: 0]
  Branch (226:9): [True: 0, False: 0]
  Branch (226:31): [True: 0, False: 0]
227
        /* We read a dummy or an empty vin. */
228
2.84M
        s >> flags;
229
2.84M
        if (flags != 0) {
  Branch (229:13): [True: 2.79M, False: 189]
  Branch (229:13): [True: 50.7k, False: 0]
  Branch (229:13): [True: 0, False: 0]
  Branch (229:13): [True: 0, False: 0]
230
2.84M
            s >> tx.vin;
231
2.84M
            s >> tx.vout;
232
2.84M
        }
233
2.84M
    } else {
234
        /* We read a non-empty vin. Assume a normal vout follows. */
235
80.2k
        s >> tx.vout;
236
80.2k
    }
237
2.92M
    if ((flags & 1) && fAllowWitness) {
  Branch (237:9): [True: 2.79M, False: 67.4k]
  Branch (237:24): [True: 2.79M, False: 0]
  Branch (237:9): [True: 50.7k, False: 13.0k]
  Branch (237:24): [True: 50.7k, False: 0]
  Branch (237:9): [True: 0, False: 0]
  Branch (237:24): [True: 0, False: 0]
  Branch (237:9): [True: 0, False: 0]
  Branch (237:24): [True: 0, False: 0]
238
        /* The witness flag is present, and we support witnesses. */
239
2.84M
        flags ^= 1;
240
5.78M
        for (size_t i = 0; i < tx.vin.size(); i++) {
  Branch (240:28): [True: 2.88M, False: 2.79M]
  Branch (240:28): [True: 53.1k, False: 50.7k]
  Branch (240:28): [True: 0, False: 0]
  Branch (240:28): [True: 0, False: 0]
241
2.93M
            s >> tx.vin[i].scriptWitness.stack;
242
2.93M
        }
243
2.84M
        if (!tx.HasWitness()) {
  Branch (243:13): [True: 4.34k, False: 2.79M]
  Branch (243:13): [True: 0, False: 50.7k]
  Branch (243:13): [True: 0, False: 0]
  Branch (243:13): [True: 0, False: 0]
244
            /* It's illegal to encode witnesses when all witness stacks are empty. */
245
4.34k
            throw std::ios_base::failure("Superfluous witness record");
246
4.34k
        }
247
2.84M
    }
248
2.92M
    if (flags) {
  Branch (248:9): [True: 11, False: 2.85M]
  Branch (248:9): [True: 0, False: 63.7k]
  Branch (248:9): [True: 0, False: 0]
  Branch (248:9): [True: 0, False: 0]
249
        /* Unknown flag in the serialization */
250
11
        throw std::ios_base::failure("Unknown transaction optional data");
251
11
    }
252
2.92M
    s >> tx.nLockTime;
253
2.92M
}
void UnserializeTransaction<ParamsStream<DataStream&, TransactionSerParams>, CMutableTransaction>(CMutableTransaction&, ParamsStream<DataStream&, TransactionSerParams>&, TransactionSerParams const&)
Line
Count
Source
217
2.86M
{
218
2.86M
    const bool fAllowWitness = params.allow_witness;
219
220
2.86M
    s >> tx.version;
221
2.86M
    unsigned char flags = 0;
222
2.86M
    tx.vin.clear();
223
2.86M
    tx.vout.clear();
224
    /* Try to read the vin. In case the dummy is there, this will be read as an empty vector. */
225
2.86M
    s >> tx.vin;
226
2.86M
    if (tx.vin.size() == 0 && fAllowWitness) {
  Branch (226:9): [True: 2.79M, False: 67.2k]
  Branch (226:31): [True: 2.79M, False: 0]
227
        /* We read a dummy or an empty vin. */
228
2.79M
        s >> flags;
229
2.79M
        if (flags != 0) {
  Branch (229:13): [True: 2.79M, False: 189]
230
2.79M
            s >> tx.vin;
231
2.79M
            s >> tx.vout;
232
2.79M
        }
233
2.79M
    } else {
234
        /* We read a non-empty vin. Assume a normal vout follows. */
235
67.2k
        s >> tx.vout;
236
67.2k
    }
237
2.86M
    if ((flags & 1) && fAllowWitness) {
  Branch (237:9): [True: 2.79M, False: 67.4k]
  Branch (237:24): [True: 2.79M, False: 0]
238
        /* The witness flag is present, and we support witnesses. */
239
2.79M
        flags ^= 1;
240
5.67M
        for (size_t i = 0; i < tx.vin.size(); i++) {
  Branch (240:28): [True: 2.88M, False: 2.79M]
241
2.88M
            s >> tx.vin[i].scriptWitness.stack;
242
2.88M
        }
243
2.79M
        if (!tx.HasWitness()) {
  Branch (243:13): [True: 4.34k, False: 2.79M]
244
            /* It's illegal to encode witnesses when all witness stacks are empty. */
245
4.34k
            throw std::ios_base::failure("Superfluous witness record");
246
4.34k
        }
247
2.79M
    }
248
2.85M
    if (flags) {
  Branch (248:9): [True: 11, False: 2.85M]
249
        /* Unknown flag in the serialization */
250
11
        throw std::ios_base::failure("Unknown transaction optional data");
251
11
    }
252
2.85M
    s >> tx.nLockTime;
253
2.85M
}
void UnserializeTransaction<ParamsStream<SpanReader&, TransactionSerParams>, CMutableTransaction>(CMutableTransaction&, ParamsStream<SpanReader&, TransactionSerParams>&, TransactionSerParams const&)
Line
Count
Source
217
63.7k
{
218
63.7k
    const bool fAllowWitness = params.allow_witness;
219
220
63.7k
    s >> tx.version;
221
63.7k
    unsigned char flags = 0;
222
63.7k
    tx.vin.clear();
223
63.7k
    tx.vout.clear();
224
    /* Try to read the vin. In case the dummy is there, this will be read as an empty vector. */
225
63.7k
    s >> tx.vin;
226
63.7k
    if (tx.vin.size() == 0 && fAllowWitness) {
  Branch (226:9): [True: 50.7k, False: 13.0k]
  Branch (226:31): [True: 50.7k, False: 0]
227
        /* We read a dummy or an empty vin. */
228
50.7k
        s >> flags;
229
50.7k
        if (flags != 0) {
  Branch (229:13): [True: 50.7k, False: 0]
230
50.7k
            s >> tx.vin;
231
50.7k
            s >> tx.vout;
232
50.7k
        }
233
50.7k
    } else {
234
        /* We read a non-empty vin. Assume a normal vout follows. */
235
13.0k
        s >> tx.vout;
236
13.0k
    }
237
63.7k
    if ((flags & 1) && fAllowWitness) {
  Branch (237:9): [True: 50.7k, False: 13.0k]
  Branch (237:24): [True: 50.7k, False: 0]
238
        /* The witness flag is present, and we support witnesses. */
239
50.7k
        flags ^= 1;
240
103k
        for (size_t i = 0; i < tx.vin.size(); i++) {
  Branch (240:28): [True: 53.1k, False: 50.7k]
241
53.1k
            s >> tx.vin[i].scriptWitness.stack;
242
53.1k
        }
243
50.7k
        if (!tx.HasWitness()) {
  Branch (243:13): [True: 0, False: 50.7k]
244
            /* It's illegal to encode witnesses when all witness stacks are empty. */
245
0
            throw std::ios_base::failure("Superfluous witness record");
246
0
        }
247
50.7k
    }
248
63.7k
    if (flags) {
  Branch (248:9): [True: 0, False: 63.7k]
249
        /* Unknown flag in the serialization */
250
0
        throw std::ios_base::failure("Unknown transaction optional data");
251
0
    }
252
63.7k
    s >> tx.nLockTime;
253
63.7k
}
Unexecuted instantiation: void UnserializeTransaction<ParamsStream<AutoFile&, TransactionSerParams>, CMutableTransaction>(CMutableTransaction&, ParamsStream<AutoFile&, TransactionSerParams>&, TransactionSerParams const&)
Unexecuted instantiation: void UnserializeTransaction<ParamsStream<BufferedFile&, TransactionSerParams>, CMutableTransaction>(CMutableTransaction&, ParamsStream<BufferedFile&, TransactionSerParams>&, TransactionSerParams const&)
254
255
template<typename Stream, typename TxType>
256
void SerializeTransaction(const TxType& tx, Stream& s, const TransactionSerParams& params)
257
23.1M
{
258
23.1M
    const bool fAllowWitness = params.allow_witness;
259
260
23.1M
    s << tx.version;
261
23.1M
    unsigned char flags = 0;
262
    // Consistency check
263
23.1M
    if (fAllowWitness) {
  Branch (263:9): [True: 5.73M, False: 9.17M]
  Branch (263:9): [True: 5.29k, False: 4.38k]
  Branch (263:9): [True: 2.33M, False: 0]
  Branch (263:9): [True: 27.4k, False: 0]
  Branch (263:9): [True: 0, False: 0]
  Branch (263:9): [True: 0, False: 0]
  Branch (263:9): [True: 0, False: 0]
  Branch (263:9): [True: 0, False: 0]
  Branch (263:9): [True: 2.84M, False: 2.98M]
264
        /* Check whether witnesses need to be serialized. */
265
10.9M
        if (tx.HasWitness()) {
  Branch (265:13): [True: 5.56M, False: 169k]
  Branch (265:13): [True: 5.21k, False: 82]
  Branch (265:13): [True: 2.31M, False: 16.8k]
  Branch (265:13): [True: 27.1k, False: 288]
  Branch (265:13): [True: 0, False: 0]
  Branch (265:13): [True: 0, False: 0]
  Branch (265:13): [True: 0, False: 0]
  Branch (265:13): [True: 0, False: 0]
  Branch (265:13): [True: 2.84M, False: 0]
266
10.7M
            flags |= 1;
267
10.7M
        }
268
10.9M
    }
269
23.1M
    if (flags) {
  Branch (269:9): [True: 5.56M, False: 9.34M]
  Branch (269:9): [True: 5.21k, False: 4.46k]
  Branch (269:9): [True: 2.31M, False: 16.8k]
  Branch (269:9): [True: 27.1k, False: 288]
  Branch (269:9): [True: 0, False: 0]
  Branch (269:9): [True: 0, False: 0]
  Branch (269:9): [True: 0, False: 0]
  Branch (269:9): [True: 0, False: 0]
  Branch (269:9): [True: 2.84M, False: 2.98M]
270
        /* Use extended format in case witnesses are to be serialized. */
271
10.7M
        std::vector<CTxIn> vinDummy;
272
10.7M
        s << vinDummy;
273
10.7M
        s << flags;
274
10.7M
    }
275
23.1M
    s << tx.vin;
276
23.1M
    s << tx.vout;
277
23.1M
    if (flags & 1) {
  Branch (277:9): [True: 5.56M, False: 9.34M]
  Branch (277:9): [True: 5.21k, False: 4.46k]
  Branch (277:9): [True: 2.31M, False: 16.8k]
  Branch (277:9): [True: 27.1k, False: 288]
  Branch (277:9): [True: 0, False: 0]
  Branch (277:9): [True: 0, False: 0]
  Branch (277:9): [True: 0, False: 0]
  Branch (277:9): [True: 0, False: 0]
  Branch (277:9): [True: 2.84M, False: 2.98M]
278
21.8M
        for (size_t i = 0; i < tx.vin.size(); i++) {
  Branch (278:28): [True: 5.77M, False: 5.56M]
  Branch (278:28): [True: 5.51k, False: 5.21k]
  Branch (278:28): [True: 2.32M, False: 2.31M]
  Branch (278:28): [True: 28.8k, False: 27.1k]
  Branch (278:28): [True: 0, False: 0]
  Branch (278:28): [True: 0, False: 0]
  Branch (278:28): [True: 0, False: 0]
  Branch (278:28): [True: 0, False: 0]
  Branch (278:28): [True: 2.93M, False: 2.84M]
279
11.0M
            s << tx.vin[i].scriptWitness.stack;
280
11.0M
        }
281
10.7M
    }
282
23.1M
    s << tx.nLockTime;
283
23.1M
}
void SerializeTransaction<ParamsStream<SizeComputer&, TransactionSerParams>, CTransaction>(CTransaction const&, ParamsStream<SizeComputer&, TransactionSerParams>&, TransactionSerParams const&)
Line
Count
Source
257
14.9M
{
258
14.9M
    const bool fAllowWitness = params.allow_witness;
259
260
14.9M
    s << tx.version;
261
14.9M
    unsigned char flags = 0;
262
    // Consistency check
263
14.9M
    if (fAllowWitness) {
  Branch (263:9): [True: 5.73M, False: 9.17M]
264
        /* Check whether witnesses need to be serialized. */
265
5.73M
        if (tx.HasWitness()) {
  Branch (265:13): [True: 5.56M, False: 169k]
266
5.56M
            flags |= 1;
267
5.56M
        }
268
5.73M
    }
269
14.9M
    if (flags) {
  Branch (269:9): [True: 5.56M, False: 9.34M]
270
        /* Use extended format in case witnesses are to be serialized. */
271
5.56M
        std::vector<CTxIn> vinDummy;
272
5.56M
        s << vinDummy;
273
5.56M
        s << flags;
274
5.56M
    }
275
14.9M
    s << tx.vin;
276
14.9M
    s << tx.vout;
277
14.9M
    if (flags & 1) {
  Branch (277:9): [True: 5.56M, False: 9.34M]
278
11.3M
        for (size_t i = 0; i < tx.vin.size(); i++) {
  Branch (278:28): [True: 5.77M, False: 5.56M]
279
5.77M
            s << tx.vin[i].scriptWitness.stack;
280
5.77M
        }
281
5.56M
    }
282
14.9M
    s << tx.nLockTime;
283
14.9M
}
void SerializeTransaction<ParamsStream<VectorWriter&, TransactionSerParams>, CTransaction>(CTransaction const&, ParamsStream<VectorWriter&, TransactionSerParams>&, TransactionSerParams const&)
Line
Count
Source
257
9.67k
{
258
9.67k
    const bool fAllowWitness = params.allow_witness;
259
260
9.67k
    s << tx.version;
261
9.67k
    unsigned char flags = 0;
262
    // Consistency check
263
9.67k
    if (fAllowWitness) {
  Branch (263:9): [True: 5.29k, False: 4.38k]
264
        /* Check whether witnesses need to be serialized. */
265
5.29k
        if (tx.HasWitness()) {
  Branch (265:13): [True: 5.21k, False: 82]
266
5.21k
            flags |= 1;
267
5.21k
        }
268
5.29k
    }
269
9.67k
    if (flags) {
  Branch (269:9): [True: 5.21k, False: 4.46k]
270
        /* Use extended format in case witnesses are to be serialized. */
271
5.21k
        std::vector<CTxIn> vinDummy;
272
5.21k
        s << vinDummy;
273
5.21k
        s << flags;
274
5.21k
    }
275
9.67k
    s << tx.vin;
276
9.67k
    s << tx.vout;
277
9.67k
    if (flags & 1) {
  Branch (277:9): [True: 5.21k, False: 4.46k]
278
10.7k
        for (size_t i = 0; i < tx.vin.size(); i++) {
  Branch (278:28): [True: 5.51k, False: 5.21k]
279
5.51k
            s << tx.vin[i].scriptWitness.stack;
280
5.51k
        }
281
5.21k
    }
282
9.67k
    s << tx.nLockTime;
283
9.67k
}
void SerializeTransaction<ParamsStream<BufferedWriter<AutoFile>&, TransactionSerParams>, CTransaction>(CTransaction const&, ParamsStream<BufferedWriter<AutoFile>&, TransactionSerParams>&, TransactionSerParams const&)
Line
Count
Source
257
2.33M
{
258
2.33M
    const bool fAllowWitness = params.allow_witness;
259
260
2.33M
    s << tx.version;
261
2.33M
    unsigned char flags = 0;
262
    // Consistency check
263
2.33M
    if (fAllowWitness) {
  Branch (263:9): [True: 2.33M, False: 0]
264
        /* Check whether witnesses need to be serialized. */
265
2.33M
        if (tx.HasWitness()) {
  Branch (265:13): [True: 2.31M, False: 16.8k]
266
2.31M
            flags |= 1;
267
2.31M
        }
268
2.33M
    }
269
2.33M
    if (flags) {
  Branch (269:9): [True: 2.31M, False: 16.8k]
270
        /* Use extended format in case witnesses are to be serialized. */
271
2.31M
        std::vector<CTxIn> vinDummy;
272
2.31M
        s << vinDummy;
273
2.31M
        s << flags;
274
2.31M
    }
275
2.33M
    s << tx.vin;
276
2.33M
    s << tx.vout;
277
2.33M
    if (flags & 1) {
  Branch (277:9): [True: 2.31M, False: 16.8k]
278
4.64M
        for (size_t i = 0; i < tx.vin.size(); i++) {
  Branch (278:28): [True: 2.32M, False: 2.31M]
279
2.32M
            s << tx.vin[i].scriptWitness.stack;
280
2.32M
        }
281
2.31M
    }
282
2.33M
    s << tx.nLockTime;
283
2.33M
}
void SerializeTransaction<ParamsStream<AutoFile&, TransactionSerParams>, CTransaction>(CTransaction const&, ParamsStream<AutoFile&, TransactionSerParams>&, TransactionSerParams const&)
Line
Count
Source
257
27.4k
{
258
27.4k
    const bool fAllowWitness = params.allow_witness;
259
260
27.4k
    s << tx.version;
261
27.4k
    unsigned char flags = 0;
262
    // Consistency check
263
27.4k
    if (fAllowWitness) {
  Branch (263:9): [True: 27.4k, False: 0]
264
        /* Check whether witnesses need to be serialized. */
265
27.4k
        if (tx.HasWitness()) {
  Branch (265:13): [True: 27.1k, False: 288]
266
27.1k
            flags |= 1;
267
27.1k
        }
268
27.4k
    }
269
27.4k
    if (flags) {
  Branch (269:9): [True: 27.1k, False: 288]
270
        /* Use extended format in case witnesses are to be serialized. */
271
27.1k
        std::vector<CTxIn> vinDummy;
272
27.1k
        s << vinDummy;
273
27.1k
        s << flags;
274
27.1k
    }
275
27.4k
    s << tx.vin;
276
27.4k
    s << tx.vout;
277
27.4k
    if (flags & 1) {
  Branch (277:9): [True: 27.1k, False: 288]
278
55.9k
        for (size_t i = 0; i < tx.vin.size(); i++) {
  Branch (278:28): [True: 28.8k, False: 27.1k]
279
28.8k
            s << tx.vin[i].scriptWitness.stack;
280
28.8k
        }
281
27.1k
    }
282
27.4k
    s << tx.nLockTime;
283
27.4k
}
Unexecuted instantiation: void SerializeTransaction<ParamsStream<DataStream&, TransactionSerParams>, CTransaction>(CTransaction const&, ParamsStream<DataStream&, TransactionSerParams>&, TransactionSerParams const&)
Unexecuted instantiation: void SerializeTransaction<ParamsStream<SizeComputer&, TransactionSerParams>, CMutableTransaction>(CMutableTransaction const&, ParamsStream<SizeComputer&, TransactionSerParams>&, TransactionSerParams const&)
Unexecuted instantiation: void SerializeTransaction<ParamsStream<DataStream&, TransactionSerParams>, CMutableTransaction>(CMutableTransaction const&, ParamsStream<DataStream&, TransactionSerParams>&, TransactionSerParams const&)
Unexecuted instantiation: void SerializeTransaction<ParamsStream<HashWriter&, TransactionSerParams>, CMutableTransaction>(CMutableTransaction const&, ParamsStream<HashWriter&, TransactionSerParams>&, TransactionSerParams const&)
void SerializeTransaction<ParamsStream<HashWriter&, TransactionSerParams>, CTransaction>(CTransaction const&, ParamsStream<HashWriter&, TransactionSerParams>&, TransactionSerParams const&)
Line
Count
Source
257
5.82M
{
258
5.82M
    const bool fAllowWitness = params.allow_witness;
259
260
5.82M
    s << tx.version;
261
5.82M
    unsigned char flags = 0;
262
    // Consistency check
263
5.82M
    if (fAllowWitness) {
  Branch (263:9): [True: 2.84M, False: 2.98M]
264
        /* Check whether witnesses need to be serialized. */
265
2.84M
        if (tx.HasWitness()) {
  Branch (265:13): [True: 2.84M, False: 0]
266
2.84M
            flags |= 1;
267
2.84M
        }
268
2.84M
    }
269
5.82M
    if (flags) {
  Branch (269:9): [True: 2.84M, False: 2.98M]
270
        /* Use extended format in case witnesses are to be serialized. */
271
2.84M
        std::vector<CTxIn> vinDummy;
272
2.84M
        s << vinDummy;
273
2.84M
        s << flags;
274
2.84M
    }
275
5.82M
    s << tx.vin;
276
5.82M
    s << tx.vout;
277
5.82M
    if (flags & 1) {
  Branch (277:9): [True: 2.84M, False: 2.98M]
278
5.77M
        for (size_t i = 0; i < tx.vin.size(); i++) {
  Branch (278:28): [True: 2.93M, False: 2.84M]
279
2.93M
            s << tx.vin[i].scriptWitness.stack;
280
2.93M
        }
281
2.84M
    }
282
5.82M
    s << tx.nLockTime;
283
5.82M
}
284
285
template<typename TxType>
286
inline CAmount CalculateOutputValue(const TxType& tx)
287
0
{
288
0
    return std::accumulate(tx.vout.cbegin(), tx.vout.cend(), CAmount{0}, [](CAmount sum, const auto& txout) { return sum + txout.nValue; });
289
0
}
290
291
292
/** The basic transaction that is broadcasted on the network and contained in
293
 * blocks.  A transaction can contain multiple inputs and outputs.
294
 */
295
class CTransaction
296
{
297
public:
298
    // Default transaction version.
299
    static const uint32_t CURRENT_VERSION{2};
300
301
    // The local variables are made const to prevent unintended modification
302
    // without updating the cached hash value. However, CTransaction is not
303
    // actually immutable; deserialization and assignment are implemented,
304
    // and bypass the constness. This is safe, as they update the entire
305
    // structure, including the hash.
306
    const std::vector<CTxIn> vin;
307
    const std::vector<CTxOut> vout;
308
    const uint32_t version;
309
    const uint32_t nLockTime;
310
311
private:
312
    /** Memory only. */
313
    const bool m_has_witness;
314
    const Txid hash;
315
    const Wtxid m_witness_hash;
316
317
    Txid ComputeHash() const;
318
    Wtxid ComputeWitnessHash() const;
319
320
    bool ComputeHasWitness() const;
321
322
public:
323
    /** Convert a CMutableTransaction into a CTransaction. */
324
    explicit CTransaction(const CMutableTransaction& tx);
325
    explicit CTransaction(CMutableTransaction&& tx);
326
327
    template <typename Stream>
328
23.1M
    inline void Serialize(Stream& s) const {
329
23.1M
        SerializeTransaction(*this, s, s.template GetParams<TransactionSerParams>());
330
23.1M
    }
void CTransaction::Serialize<ParamsStream<SizeComputer&, TransactionSerParams> >(ParamsStream<SizeComputer&, TransactionSerParams>&) const
Line
Count
Source
328
14.9M
    inline void Serialize(Stream& s) const {
329
14.9M
        SerializeTransaction(*this, s, s.template GetParams<TransactionSerParams>());
330
14.9M
    }
void CTransaction::Serialize<ParamsStream<VectorWriter&, TransactionSerParams> >(ParamsStream<VectorWriter&, TransactionSerParams>&) const
Line
Count
Source
328
9.67k
    inline void Serialize(Stream& s) const {
329
9.67k
        SerializeTransaction(*this, s, s.template GetParams<TransactionSerParams>());
330
9.67k
    }
void CTransaction::Serialize<ParamsStream<BufferedWriter<AutoFile>&, TransactionSerParams> >(ParamsStream<BufferedWriter<AutoFile>&, TransactionSerParams>&) const
Line
Count
Source
328
2.33M
    inline void Serialize(Stream& s) const {
329
2.33M
        SerializeTransaction(*this, s, s.template GetParams<TransactionSerParams>());
330
2.33M
    }
void CTransaction::Serialize<ParamsStream<AutoFile&, TransactionSerParams> >(ParamsStream<AutoFile&, TransactionSerParams>&) const
Line
Count
Source
328
27.4k
    inline void Serialize(Stream& s) const {
329
27.4k
        SerializeTransaction(*this, s, s.template GetParams<TransactionSerParams>());
330
27.4k
    }
Unexecuted instantiation: void CTransaction::Serialize<ParamsStream<DataStream&, TransactionSerParams> >(ParamsStream<DataStream&, TransactionSerParams>&) const
void CTransaction::Serialize<ParamsStream<HashWriter&, TransactionSerParams> >(ParamsStream<HashWriter&, TransactionSerParams>&) const
Line
Count
Source
328
5.82M
    inline void Serialize(Stream& s) const {
329
5.82M
        SerializeTransaction(*this, s, s.template GetParams<TransactionSerParams>());
330
5.82M
    }
331
332
    /** This deserializing constructor is provided instead of an Unserialize method.
333
     *  Unserialize is not possible, since it would require overwriting const fields. */
334
    template <typename Stream>
335
    CTransaction(deserialize_type, const TransactionSerParams& params, Stream& s) : CTransaction(CMutableTransaction(deserialize, params, s)) {}
336
    template <typename Stream>
337
2.92M
    CTransaction(deserialize_type, Stream& s) : CTransaction(CMutableTransaction(deserialize, s)) {}
CTransaction::CTransaction<ParamsStream<DataStream&, TransactionSerParams> >(deserialize_type, ParamsStream<DataStream&, TransactionSerParams>&)
Line
Count
Source
337
2.86M
    CTransaction(deserialize_type, Stream& s) : CTransaction(CMutableTransaction(deserialize, s)) {}
CTransaction::CTransaction<ParamsStream<SpanReader&, TransactionSerParams> >(deserialize_type, ParamsStream<SpanReader&, TransactionSerParams>&)
Line
Count
Source
337
63.7k
    CTransaction(deserialize_type, Stream& s) : CTransaction(CMutableTransaction(deserialize, s)) {}
Unexecuted instantiation: CTransaction::CTransaction<ParamsStream<AutoFile&, TransactionSerParams> >(deserialize_type, ParamsStream<AutoFile&, TransactionSerParams>&)
Unexecuted instantiation: CTransaction::CTransaction<ParamsStream<BufferedFile&, TransactionSerParams> >(deserialize_type, ParamsStream<BufferedFile&, TransactionSerParams>&)
338
339
0
    bool IsNull() const {
340
0
        return vin.empty() && vout.empty();
  Branch (340:16): [True: 0, False: 0]
  Branch (340:31): [True: 0, False: 0]
341
0
    }
342
343
240M
    const Txid& GetHash() const LIFETIMEBOUND { return hash; }
344
13.9M
    const Wtxid& GetWitnessHash() const LIFETIMEBOUND { return m_witness_hash; };
345
346
    // Return sum of txouts.
347
    CAmount GetValueOut() const;
348
349
    /**
350
     * Get the total transaction size in bytes, including witness data.
351
     * "Total Size" defined in BIP141 and BIP144.
352
     * @return Total transaction size in bytes
353
     */
354
    unsigned int GetTotalSize() const;
355
356
    bool IsCoinBase() const
357
24.2M
    {
358
24.2M
        return (vin.size() == 1 && vin[0].prevout.IsNull());
  Branch (358:17): [True: 23.9M, False: 302k]
  Branch (358:36): [True: 17.9M, False: 6.01M]
359
24.2M
    }
360
361
    friend bool operator==(const CTransaction& a, const CTransaction& b)
362
0
    {
363
0
        return a.hash == b.hash;
364
0
    }
365
366
    friend bool operator!=(const CTransaction& a, const CTransaction& b)
367
370
    {
368
370
        return a.hash != b.hash;
369
370
    }
370
371
    std::string ToString() const;
372
373
16.9M
    bool HasWitness() const { return m_has_witness; }
374
};
375
376
/** A mutable version of CTransaction. */
377
struct CMutableTransaction
378
{
379
    std::vector<CTxIn> vin;
380
    std::vector<CTxOut> vout;
381
    uint32_t version;
382
    uint32_t nLockTime;
383
384
    explicit CMutableTransaction();
385
    explicit CMutableTransaction(const CTransaction& tx);
386
387
    template <typename Stream>
388
0
    inline void Serialize(Stream& s) const {
389
0
        SerializeTransaction(*this, s, s.template GetParams<TransactionSerParams>());
390
0
    }
Unexecuted instantiation: void CMutableTransaction::Serialize<ParamsStream<SizeComputer&, TransactionSerParams> >(ParamsStream<SizeComputer&, TransactionSerParams>&) const
Unexecuted instantiation: void CMutableTransaction::Serialize<ParamsStream<DataStream&, TransactionSerParams> >(ParamsStream<DataStream&, TransactionSerParams>&) const
Unexecuted instantiation: void CMutableTransaction::Serialize<ParamsStream<HashWriter&, TransactionSerParams> >(ParamsStream<HashWriter&, TransactionSerParams>&) const
391
392
    template <typename Stream>
393
2.92M
    inline void Unserialize(Stream& s) {
394
2.92M
        UnserializeTransaction(*this, s, s.template GetParams<TransactionSerParams>());
395
2.92M
    }
void CMutableTransaction::Unserialize<ParamsStream<DataStream&, TransactionSerParams> >(ParamsStream<DataStream&, TransactionSerParams>&)
Line
Count
Source
393
2.86M
    inline void Unserialize(Stream& s) {
394
2.86M
        UnserializeTransaction(*this, s, s.template GetParams<TransactionSerParams>());
395
2.86M
    }
void CMutableTransaction::Unserialize<ParamsStream<SpanReader&, TransactionSerParams> >(ParamsStream<SpanReader&, TransactionSerParams>&)
Line
Count
Source
393
63.7k
    inline void Unserialize(Stream& s) {
394
63.7k
        UnserializeTransaction(*this, s, s.template GetParams<TransactionSerParams>());
395
63.7k
    }
Unexecuted instantiation: void CMutableTransaction::Unserialize<ParamsStream<AutoFile&, TransactionSerParams> >(ParamsStream<AutoFile&, TransactionSerParams>&)
Unexecuted instantiation: void CMutableTransaction::Unserialize<ParamsStream<BufferedFile&, TransactionSerParams> >(ParamsStream<BufferedFile&, TransactionSerParams>&)
396
397
    template <typename Stream>
398
    CMutableTransaction(deserialize_type, const TransactionSerParams& params, Stream& s) {
399
        UnserializeTransaction(*this, s, params);
400
    }
401
402
    template <typename Stream>
403
2.92M
    CMutableTransaction(deserialize_type, Stream& s) {
404
2.92M
        Unserialize(s);
405
2.92M
    }
CMutableTransaction::CMutableTransaction<ParamsStream<DataStream&, TransactionSerParams> >(deserialize_type, ParamsStream<DataStream&, TransactionSerParams>&)
Line
Count
Source
403
2.86M
    CMutableTransaction(deserialize_type, Stream& s) {
404
2.86M
        Unserialize(s);
405
2.86M
    }
CMutableTransaction::CMutableTransaction<ParamsStream<SpanReader&, TransactionSerParams> >(deserialize_type, ParamsStream<SpanReader&, TransactionSerParams>&)
Line
Count
Source
403
63.7k
    CMutableTransaction(deserialize_type, Stream& s) {
404
63.7k
        Unserialize(s);
405
63.7k
    }
Unexecuted instantiation: CMutableTransaction::CMutableTransaction<ParamsStream<AutoFile&, TransactionSerParams> >(deserialize_type, ParamsStream<AutoFile&, TransactionSerParams>&)
Unexecuted instantiation: CMutableTransaction::CMutableTransaction<ParamsStream<BufferedFile&, TransactionSerParams> >(deserialize_type, ParamsStream<BufferedFile&, TransactionSerParams>&)
406
407
    /** Compute the hash of this CMutableTransaction. This is computed on the
408
     * fly, as opposed to GetHash() in CTransaction, which uses a cached result.
409
     */
410
    Txid GetHash() const;
411
412
    bool HasWitness() const
413
2.84M
    {
414
2.86M
        for (size_t i = 0; i < vin.size(); i++) {
  Branch (414:28): [True: 2.85M, False: 4.34k]
415
2.85M
            if (!vin[i].scriptWitness.IsNull()) {
  Branch (415:17): [True: 2.84M, False: 16.5k]
416
2.84M
                return true;
417
2.84M
            }
418
2.85M
        }
419
4.34k
        return false;
420
2.84M
    }
421
};
422
423
typedef std::shared_ptr<const CTransaction> CTransactionRef;
424
66.5k
template <typename Tx> static inline CTransactionRef MakeTransactionRef(Tx&& txIn) { return std::make_shared<const CTransaction>(std::forward<Tx>(txIn)); }
Unexecuted instantiation: miner.cpp:std::shared_ptr<CTransaction const> MakeTransactionRef<CMutableTransaction&>(CMutableTransaction&)
Unexecuted instantiation: miner.cpp:std::shared_ptr<CTransaction const> MakeTransactionRef<CMutableTransaction>(CMutableTransaction&&)
Unexecuted instantiation: mempool.cpp:std::shared_ptr<CTransaction const> MakeTransactionRef<CMutableTransaction>(CMutableTransaction&&)
Unexecuted instantiation: mining.cpp:std::shared_ptr<CTransaction const> MakeTransactionRef<CMutableTransaction>(CMutableTransaction&&)
Unexecuted instantiation: validation.cpp:std::shared_ptr<CTransaction const> MakeTransactionRef<CMutableTransaction>(CMutableTransaction&&)
Unexecuted instantiation: spend.cpp:std::shared_ptr<CTransaction const> MakeTransactionRef<CMutableTransaction>(CMutableTransaction&&)
Unexecuted instantiation: wallet.cpp:std::shared_ptr<CTransaction const> MakeTransactionRef<CTransaction const&>(CTransaction const&)
Unexecuted instantiation: feebumper.cpp:std::shared_ptr<CTransaction const> MakeTransactionRef<CMutableTransaction>(CMutableTransaction&&)
Unexecuted instantiation: backup.cpp:std::shared_ptr<CTransaction const> MakeTransactionRef<CMutableTransaction&>(CMutableTransaction&)
chainparams.cpp:std::shared_ptr<CTransaction const> MakeTransactionRef<CMutableTransaction>(CMutableTransaction&&)
Line
Count
Source
424
66.5k
template <typename Tx> static inline CTransactionRef MakeTransactionRef(Tx&& txIn) { return std::make_shared<const CTransaction>(std::forward<Tx>(txIn)); }
425
426
/** A generic txid reference (txid or wtxid). */
427
class GenTxid
428
{
429
    bool m_is_wtxid;
430
    uint256 m_hash;
431
2.92M
    GenTxid(bool is_wtxid, const uint256& hash) : m_is_wtxid(is_wtxid), m_hash(hash) {}
432
433
public:
434
1.40M
    static GenTxid Txid(const uint256& hash) { return GenTxid{false, hash}; }
435
1.51M
    static GenTxid Wtxid(const uint256& hash) { return GenTxid{true, hash}; }
436
6.27M
    bool IsWtxid() const { return m_is_wtxid; }
437
6.89M
    const uint256& GetHash() const LIFETIMEBOUND { return m_hash; }
438
0
    friend bool operator==(const GenTxid& a, const GenTxid& b) { return a.m_is_wtxid == b.m_is_wtxid && a.m_hash == b.m_hash; }
439
0
    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); }
440
};
441
442
#endif // BITCOIN_PRIMITIVES_TRANSACTION_H