• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

libbitcoin / libbitcoin-system / 24465120547

15 Apr 2026 04:09PM UTC coverage: 75.853% (+0.001%) from 75.852%
24465120547

push

github

web-flow
Merge pull request #1816 from evoskuil/master

Consensus: treat tx w/superfluous witness as invalid serialization.

5 of 6 new or added lines in 1 file covered. (83.33%)

16737 of 22065 relevant lines covered (75.85%)

2499163.52 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

77.78
/src/chain/transaction.cpp
1
/**
2
 * Copyright (c) 2011-2026 libbitcoin developers (see AUTHORS)
3
 *
4
 * This file is part of libbitcoin.
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU Affero General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU Affero General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Affero General Public License
17
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 */
19
#include <bitcoin/system/chain/transaction.hpp>
20

21
#include <algorithm>
22
#include <iterator>
23
#include <numeric>
24
#include <utility>
25
#include <bitcoin/system/chain/context.hpp>
26
#include <bitcoin/system/chain/enums/coverage.hpp>
27
#include <bitcoin/system/chain/enums/magic_numbers.hpp>
28
#include <bitcoin/system/chain/header.hpp>
29
#include <bitcoin/system/chain/input.hpp>
30
#include <bitcoin/system/chain/output.hpp>
31
#include <bitcoin/system/chain/script.hpp>
32
#include <bitcoin/system/data/data.hpp>
33
#include <bitcoin/system/define.hpp>
34
#include <bitcoin/system/error/error.hpp>
35
#include <bitcoin/system/hash/hash.hpp>
36
#include <bitcoin/system/machine/machine.hpp>
37
#include <bitcoin/system/math/math.hpp>
38
#include <bitcoin/system/stream/stream.hpp>
39

40
namespace libbitcoin {
41
namespace system {
42
namespace chain {
43

44
BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)
45

46
// Constructors.
47
// ----------------------------------------------------------------------------
48

49
transaction::transaction() NOEXCEPT
21✔
50
  : transaction(0,
51
      to_shared<input_cptrs>(),
21✔
52
      to_shared<output_cptrs>(),
21✔
53
      0, false, false)
42✔
54
{
55
}
21✔
56

57
transaction::transaction(uint32_t version, chain::inputs&& inputs,
904✔
58
    chain::outputs&& outputs, uint32_t locktime) NOEXCEPT
904✔
59
  : transaction(version, to_shareds(std::move(inputs)),
904✔
60
      to_shareds(std::move(outputs)), locktime)
2,712✔
61
{
62
}
904✔
63

64
transaction::transaction(uint32_t version, const chain::inputs& inputs,
1✔
65
    const chain::outputs& outputs, uint32_t locktime) NOEXCEPT
1✔
66
  : transaction(version, to_shareds(inputs), to_shareds(outputs), locktime,
1✔
67
      segregated(inputs), true)
3✔
68
{
69
}
1✔
70

71
transaction::transaction(uint32_t version, const inputs_cptr& inputs,
904✔
72
    const outputs_cptr& outputs, uint32_t locktime) NOEXCEPT
904✔
73
  : transaction(version, inputs, outputs, locktime, segregated(*inputs), true)
904✔
74
{
75
}
904✔
76

77
transaction::transaction(const data_slice& data, bool witness) NOEXCEPT
41✔
78
  : transaction(stream::in::fast(data), witness)
41✔
79
{
80
}
41✔
81

82
//protected
83
transaction::transaction(stream::in::fast&& stream, bool witness) NOEXCEPT
41✔
84
  : transaction(read::bytes::fast(stream), witness)
41✔
85
{
86
}
41✔
87

88
transaction::transaction(stream::in::fast& stream, bool witness) NOEXCEPT
2✔
89
  : transaction(read::bytes::fast(stream), witness)
2✔
90
{
91
}
2✔
92

93
transaction::transaction(std::istream& stream, bool witness) NOEXCEPT
4✔
94
  : transaction(read::bytes::istream(stream), witness)
4✔
95
{
96
}
4✔
97

98
// protected
99
transaction::transaction(reader&& source, bool witness) NOEXCEPT
47✔
100
  : transaction(source, witness)
47✔
101
{
102
}
47✔
103

104
transaction::transaction(reader& source, bool witness) NOEXCEPT
212✔
105
  : version_(source.read_4_bytes_little_endian()),
424✔
106
    inputs_(CREATE(input_cptrs, source.get_allocator())),
212✔
107
    outputs_(CREATE(output_cptrs, source.get_allocator()))
424✔
108
{
109
    assign_data(source, witness);
212✔
110
}
212✔
111

112
// protected
113
transaction::transaction(uint32_t version,
926✔
114
    const chain::inputs_cptr& inputs, const chain::outputs_cptr& outputs,
115
    uint32_t locktime, bool segregated, bool valid) NOEXCEPT
926✔
116
  : version_(version),
926✔
117
    inputs_(inputs ? inputs : to_shared<input_cptrs>()),
1,852✔
118
    outputs_(outputs ? outputs : to_shared<output_cptrs>()),
926✔
119
    locktime_(locktime),
926✔
120
    segregated_(segregated),
926✔
121
    valid_(valid),
926✔
122
    size_(serialized_size(*inputs, *outputs, segregated))
1,852✔
123
{
124
}
926✔
125

126
// Operators.
127
// ----------------------------------------------------------------------------
128

129
bool transaction::operator==(const transaction& other) const NOEXCEPT
63✔
130
{
131
    // Compares input/output elements, not pointers, cache not compared.
132
    return (version_ == other.version_)
63✔
133
        && (locktime_ == other.locktime_)
61✔
134
        && ((inputs_ == other.inputs_) || 
90✔
135
            deep_equal(*inputs_, *other.inputs_))
29✔
136
        && ((outputs_ == other.outputs_) ||
153✔
137
            deep_equal(*outputs_, *other.outputs_));
29✔
138
}
139

140
bool transaction::operator!=(const transaction& other) const NOEXCEPT
2✔
141
{
142
    return !(*this == other);
2✔
143
}
144

145
// Deserialization.
146
// ----------------------------------------------------------------------------
147

148
// private
149
BC_PUSH_WARNING(NO_UNGUARDED_POINTERS)
150
void transaction::assign_data(reader& source, bool witness) NOEXCEPT
212✔
151
{
152
    auto& allocator = source.get_allocator();
212✔
153
    auto ins = to_non_const_raw_ptr(inputs_);
212✔
154
    auto count = source.read_size(max_block_size);
212✔
155
    ins->reserve(count);
212✔
156
    for (size_t in{}; in < count; ++in)
469✔
157
        ins->emplace_back(CREATE(input, allocator, source));
257✔
158

159
    // Expensive repeated recomputation, so cache segregated state.
160
    // Detect witness as no inputs (marker) and expected flag [bip144].
161
    segregated_ = 
212✔
162
        inputs_->size() == witness_marker &&
228✔
163
        source.peek_byte() == witness_enabled;
16✔
164

165
    if (segregated_)
212✔
166
    {
167
        // Skip over the peeked witness flag.
168
        source.skip_byte();
16✔
169

170
        count = source.read_size(max_block_size);
16✔
171
        ins->reserve(count);
16✔
172
        for (size_t in{}; in < count; ++in)
37✔
173
            ins->emplace_back(CREATE(input, allocator, source));
21✔
174

175
        auto outs = to_non_const_raw_ptr(outputs_);
16✔
176
        count = source.read_size(max_block_size);
16✔
177
        outs->reserve(count);
16✔
178
        for (size_t out{}; out < count; ++out)
41✔
179
            outs->emplace_back(CREATE(output, allocator, source));
25✔
180

181
        // Read or skip witnesses as specified.
182
        if (witness)
16✔
183
        {
184
            auto superfluous{ true };
15✔
185
            for (auto& input: *inputs_)
35✔
186
                if (to_non_const_raw_ptr(input)->set_witness(source))
20✔
187
                    superfluous = false;
17✔
188

189
            // Transaction is non-segregated if all witnesses are empty.
190
            // Validatable, but treat superfluous as invalid serialization.
191
            if (superfluous)
15✔
NEW
192
                source.invalidate();
×
193
        }
194
        else
195
        {
196
            // Transaction is read as non-segregated (witnesses skipped).
197
            segregated_ = false;
1✔
198

199
            // Default witness is populated on input construct.
200
            for (size_t in{}; in < inputs_->size(); ++in)
2✔
201
                witness::skip(source, true);
1✔
202
        }
203
    }
204
    else
205
    {
206
        auto outs = to_non_const_raw_ptr(outputs_);
196✔
207
        count = source.read_size(max_block_size);
196✔
208
        outs->reserve(count);
196✔
209
        for (size_t out{}; out < count; ++out)
453✔
210
            outs->emplace_back(CREATE(output, allocator, source));
257✔
211
    }
212

213
    locktime_ = source.read_4_bytes_little_endian();
212✔
214
    size_ = serialized_size(*inputs_, *outputs_, segregated_);
212✔
215
    valid_ = source;
212✔
216
}
212✔
217
BC_POP_WARNING()
218

219
// Serialization.
220
// ----------------------------------------------------------------------------
221

222
// Transactions with empty witnesses always use old serialization [bip144].
223
// If no inputs are witness programs then witness hash is tx hash [bip141].
224
data_chunk transaction::to_data(bool witness) const NOEXCEPT
10✔
225
{
226
    witness &= segregated_;
10✔
227

228
    data_chunk data(serialized_size(witness));
10✔
229
    stream::out::fast ostream(data);
10✔
230
    write::bytes::fast out(ostream);
10✔
231
    to_data(out, witness);
10✔
232
    return data;
20✔
233
}
10✔
234

235
void transaction::to_data(std::ostream& stream, bool witness) const NOEXCEPT
1✔
236
{
237
    witness &= segregated_;
1✔
238

239
    write::bytes::ostream out(stream);
1✔
240
    to_data(out, witness);
1✔
241
}
1✔
242

243
void transaction::to_data(writer& sink, bool witness) const NOEXCEPT
1,016✔
244
{
245
    witness &= segregated_;
1,016✔
246

247
    sink.write_4_bytes_little_endian(version_);
1,016✔
248

249
    if (witness)
1,016✔
250
    {
251
        sink.write_byte(witness_marker);
5✔
252
        sink.write_byte(witness_enabled);
5✔
253
    }
254

255
    sink.write_variable(inputs_->size());
1,016✔
256
    for (const auto& input: *inputs_)
2,461✔
257
        input->to_data(sink);
1,445✔
258

259
    sink.write_variable(outputs_->size());
1,016✔
260
    for (const auto& output: *outputs_)
2,743✔
261
        output->to_data(sink);
1,727✔
262

263
    if (witness)
1,016✔
264
        for (auto& input: *inputs_)
14✔
265
            input->witness().to_data(sink, true);
9✔
266

267
    sink.write_4_bytes_little_endian(locktime_);
1,016✔
268
}
1,016✔
269

270
// static/private
271
transaction::sizes transaction::serialized_size(const input_cptrs& inputs,
1,138✔
272
    const output_cptrs& outputs, bool segregated) NOEXCEPT
273
{
274
    sizes size{ zero, zero };
1,138✔
275

276
    std::for_each(inputs.begin(), inputs.end(), [&](const auto& in) NOEXCEPT
2,328✔
277
    {
278
        size.nominal = ceilinged_add(size.nominal, in->nominal_size());
1,190✔
279
        if (segregated)
1,190✔
280
            size.witnessed = ceilinged_add(size.witnessed, in->witnessed_size());
62✔
281
    });
1,190✔
282

283
    const auto outs = [](size_t total, const auto& output) NOEXCEPT
402✔
284
    {
285
        return ceilinged_add(total, output->serialized_size());
402✔
286
    };
287

288
    constexpr auto base_const_size = sizeof(version_) + sizeof(locktime_);
1,138✔
289
    constexpr auto witness_const_size = sizeof(witness_marker) +
1,138✔
290
        sizeof(witness_enabled);
291

292
    const auto base_size =
1,138✔
293
        ceilinged_add(ceilinged_add(ceilinged_add(base_const_size,
1,138✔
294
            variable_size(inputs.size())), variable_size(outputs.size())),
295
            std::accumulate(outputs.begin(), outputs.end(), zero, outs));
296

297
    const auto nominal_size = ceilinged_add(base_size, size.nominal);
1,138✔
298

299
    // For non-segregated transactions, witnessed_size is nominal_size.
300
    const auto witnessed_size = segregated ? ceilinged_add(ceilinged_add(
1,138✔
301
        base_size, witness_const_size), size.witnessed) : nominal_size;
302

303
    // For non-segregated transactions, values are the same.
304
    return { nominal_size, witnessed_size };
1,138✔
305
}
306

307
size_t transaction::serialized_size(bool witness) const NOEXCEPT
636✔
308
{
309
    witness &= segregated_;
636✔
310

311
    return witness ? size_.witnessed : size_.nominal;
636✔
312
}
313

314
// Properties.
315
// ----------------------------------------------------------------------------
316

317
bool transaction::is_valid() const NOEXCEPT
777✔
318
{
319
    return valid_;
777✔
320
}
321

322
size_t transaction::spends() const NOEXCEPT
×
323
{
324
    return is_coinbase() ? zero : inputs_->size();
×
325
}
326

327
size_t transaction::inputs() const NOEXCEPT
1,569✔
328
{
329
    return inputs_->size();
1,569✔
330
}
331

332
size_t transaction::outputs() const NOEXCEPT
1✔
333
{
334
    return outputs_->size();
1✔
335
}
336

337
uint32_t transaction::version() const NOEXCEPT
7✔
338
{
339
    return version_;
7✔
340
}
341

342
uint32_t transaction::locktime() const NOEXCEPT
14✔
343
{
344
    return locktime_;
14✔
345
}
346

347
const inputs_cptr& transaction::inputs_ptr() const NOEXCEPT
2,451✔
348
{
349
    return inputs_;
2,451✔
350
}
351

352
const outputs_cptr& transaction::outputs_ptr() const NOEXCEPT
67✔
353
{
354
    return outputs_;
67✔
355
}
356

357
uint64_t transaction::fee() const NOEXCEPT
4✔
358
{
359
    // Underflow returns zero (and is_overspent() will be true).
360
    // The value of prevouts referenced by inputs minus that spent by outputs.
361
    return floored_subtract(value(), spend());
4✔
362
}
363

364
// Methods.
365
// ----------------------------------------------------------------------------
366

367
bool transaction::is_dusty(uint64_t minimum_output_value) const NOEXCEPT
6✔
368
{
369
    const auto dusty = [=](const auto& output) NOEXCEPT
9✔
370
    {
371
        return output->is_dust(minimum_output_value);
9✔
372
    };
6✔
373

374
    return std::any_of(outputs_->begin(), outputs_->end(), dusty);
6✔
375
}
376

377
size_t transaction::signature_operations(bool bip16, bool bip141) const NOEXCEPT
1✔
378
{
379
    // Overflow returns max_size_t.
380
    const auto in = [=](size_t total, const auto& input) NOEXCEPT
×
381
    {
382
        const auto add = input->signature_operations(bip16, bip141);
×
383
        return ceilinged_add(total, add);
×
384
    };
1✔
385

386
    // Overflow returns max_size_t.
387
    const auto out = [=](size_t total, const auto& output) NOEXCEPT
×
388
    {
389
        const auto add = output->signature_operations(bip141);
×
390
        return ceilinged_add(total, add);
×
391
    };
1✔
392

393
    // Overflow returns max_size_t.
394
    return ceilinged_add(
1✔
395
        std::accumulate(inputs_->begin(), inputs_->end(), zero, in),
396
        std::accumulate(outputs_->begin(), outputs_->end(), zero, out));
1✔
397
}
398

399
// private
400
chain::points transaction::points() const NOEXCEPT
4✔
401
{
402
    chain::points out(inputs_->size());
4✔
403

404
    const auto point = [](const auto& input) NOEXCEPT
8✔
405
    {
406
        return input->point();
8✔
407
    };
408

409
    std::transform(inputs_->begin(), inputs_->end(), out.begin(), point);
4✔
410
    return out;
4✔
411
}
412

413
// Signatures (public).
414
// ----------------------------------------------------------------------------
415

416
transaction::input_iterator transaction::input_at(
4✔
417
    uint32_t index) const NOEXCEPT
418
{
419
    // Guarded by check_signature and create_endorsement.
420
    BC_ASSERT_MSG(index < inputs_->size(), "invalid input index");
4✔
421

422
    return std::next(inputs_->begin(), index);
4✔
423
}
424

425
// This is not used internal to the library.
426
bool transaction::check_signature(const ec_signature& signature,
2✔
427
    const data_slice& public_key, const script& subscript, uint32_t index,
428
    uint64_t value, uint8_t sighash_flags, script_version version,
429
    uint32_t flags) const NOEXCEPT
430
{
431
    if ((index >= inputs_->size()) || signature.empty() || public_key.empty())
2✔
432
        return false;
433

434
    hash_digest sighash{};
2✔
435
    const hash_cptr unused{};
2✔
436
    if (!signature_hash(sighash, input_at(index), subscript, value,
2✔
437
        unused, version, sighash_flags, flags))
438
        return false;
439

440
    // Validate the ECDSA signature.
441
    return ecdsa::verify_signature(public_key, sighash, signature);
2✔
442
}
443

444
// This is not used internal to the library.
445
bool transaction::create_endorsement(endorsement& out, const ec_secret& secret,
2✔
446
    const script& subscript, uint32_t index, uint64_t value,
447
    uint8_t sighash_flags, script_version version,
448
    uint32_t flags) const NOEXCEPT
449
{
450
    if (index >= inputs_->size())
2✔
451
        return false;
452

453
    hash_digest sighash{};
2✔
454
    const hash_cptr unused{};
2✔
455
    out.reserve(max_endorsement_size);
2✔
456
    if (!signature_hash(sighash, input_at(index), subscript, value, unused,
2✔
457
        version, sighash_flags, flags))
458
        return false;
459

460
    // Create the ECDSA signature and encode as DER.
461
    ec_signature signature;
2✔
462
    if (!ecdsa::sign(signature, secret, sighash) ||
4✔
463
        !ecdsa::encode_signature(out, signature))
2✔
464
        return false;
×
465

466
    // Add the sighash type to the end of the DER signature -> endorsement.
467
    out.push_back(sighash_flags);
2✔
468
    ////out.shrink_to_fit();
469
    return true;
2✔
470
}
471

472
// Signature hashing (common).
473
// ----------------------------------------------------------------------------
474

475
uint32_t transaction::input_index(const input_iterator& input) const NOEXCEPT
25✔
476
{
477
    return possible_narrow_and_sign_cast<uint32_t>(
25✔
478
        std::distance(inputs_->begin(), input));
25✔
479
}
480

481
//*****************************************************************************
482
// CONSENSUS: if index exceeds outputs in signature hash, return one_hash.
483
// Related Bug: bitcointalk.org/index.php?topic=260595
484
// Exploit: joncave.co.uk/2014/08/bitcoin-sighash-single/
485
//*****************************************************************************
486
bool transaction::output_overflow(size_t input) const NOEXCEPT
21✔
487
{
488
    return input >= outputs_->size();
21✔
489
}
490

491
// There are three versions of signature hashing and verification.
492
// Version: (unversioned) original, (v0) bip143/segwit, (v1) bip341/taproot.
493
bool transaction::signature_hash(hash_digest& out, const input_iterator& input,
41✔
494
    const script& subscript, uint64_t value, const hash_cptr& tapleaf,
495
    script_version version, uint8_t sighash_flags, uint32_t flags) const NOEXCEPT
496
{
497
    // There is no rational interpretation of a signature hash for a coinbase.
498
    BC_ASSERT(!is_coinbase());
41✔
499

500
    // bip143: the method of signature hashing is changed for v0 scripts.
501
    // bip342: the method of signature hashing is changed for v1 scripts.
502
    const auto bip143 = script::is_enabled(flags, flags::bip143_rule);
41✔
503
    const auto bip342 = script::is_enabled(flags, flags::bip342_rule);
41✔
504

505
    // This is where the connection between bip141 and bip143 is made. If a
506
    // versioned 1 program (segwit) extracted by bip141 but bip143 (segwit
507
    // hashing) is not active, then drop down to unversioned signature hashing.
508
    if (bip143 && version == script_version::segwit)
41✔
509
        return version0_sighash(out, input, subscript, value, sighash_flags);
22✔
510

511
    // This is where the connection between bip341 and bip342 is made. If a
512
    // version 2 program (taproot) extracted by bip341 but bip342 (tapscript)
513
    // is not active then drop down to unversioned signature hashing. 
514
    if (bip342 && version == script_version::taproot)
19✔
515
        return version1_sighash(out, input, subscript, value, tapleaf,
×
516
            sighash_flags);
×
517

518
    // Given above forks are documented to activate together, this distinction
519
    // is moot, however these are distinct BIPs and therefore must be either be
520
    // differentiated as such in code, or the BIP distiction would be ignored.
521
    return unversioned_sighash(out, input, subscript, sighash_flags);
19✔
522
}
523

524
// Guard (context free).
525
// ----------------------------------------------------------------------------
526

527
bool transaction::is_coinbase() const NOEXCEPT
81✔
528
{
529
    return is_one(inputs_->size()) && inputs_->front()->point().is_null();
81✔
530
}
531

532
bool transaction::is_internal_double_spend() const NOEXCEPT
4✔
533
{
534
    // TODO: optimize (see block.is_internal_double_spend).
535
    return !is_distinct(points());
4✔
536
}
537

538
// TODO: a pool (non-coinbase) tx must fit into a block (with a coinbase).
539
bool transaction::is_oversized() const NOEXCEPT
×
540
{
541
    return serialized_size(false) > max_block_size;
×
542
}
543

544
// Guard (contextual).
545
// ----------------------------------------------------------------------------
546

547
// static/private
548
bool transaction::segregated(const chain::inputs& inputs) NOEXCEPT
1✔
549
{
550
    const auto witnessed = [](const auto& input) NOEXCEPT
2✔
551
    {
552
        return !input.witness().stack().empty();
1✔
553
    };
554

555
    return std::any_of(inputs.begin(), inputs.end(), witnessed);
1✔
556
}
557

558
// static/private
559
bool transaction::segregated(const input_cptrs& inputs) NOEXCEPT
904✔
560
{
561
    const auto witnessed = [](const auto& input) NOEXCEPT
907✔
562
    {
563
        return !input->witness().stack().empty();
907✔
564
    };
565

566
    return std::any_of(inputs.begin(), inputs.end(), witnessed);
904✔
567
}
568

569
bool transaction::is_segregated() const NOEXCEPT
4✔
570
{
571
    // Cache, implies no non-empty witness.
572
    return segregated_;
4✔
573
}
574

575
size_t transaction::weight() const NOEXCEPT
2✔
576
{
577
    // Transaction weight is 3 * base size * + 1 * total size [bip141].
578
    return ceilinged_add(
2✔
579
        ceilinged_multiply(base_size_contribution, serialized_size(false)),
580
        ceilinged_multiply(total_size_contribution, serialized_size(true)));
2✔
581
}
582

583
size_t transaction::virtual_size() const NOEXCEPT
1✔
584
{
585
    constexpr auto scale = base_size_contribution + total_size_contribution;
1✔
586
    return ceilinged_divide(weight(), scale);
1✔
587
}
588

589
bool transaction::is_overweight() const NOEXCEPT
×
590
{
591
    return weight() > max_block_weight;
×
592
}
593

594
//*****************************************************************************
595
// CONSENSUS: Legacy sigops are counted in coinbase scripts despite the fact
596
// that coinbase input scripts are never executed. There is no need to exclude
597
// p2sh coinbase sigops since there is never a script to count.
598
//*****************************************************************************
599
bool transaction::is_signature_operations_limited(bool bip16,
×
600
    bool bip141) const NOEXCEPT
601
{
602
    const auto limit = bip141 ? max_fast_sigops : max_block_sigops;
×
603
    return signature_operations(bip16, bip141) > limit;
×
604
}
605

606
// Check (context free).
607
// ----------------------------------------------------------------------------
608

609
bool transaction::is_empty() const NOEXCEPT
9✔
610
{
611
    return inputs_->empty() || outputs_->empty();
9✔
612
}
613

614
bool transaction::is_null_non_coinbase() const NOEXCEPT
7✔
615
{
616
    BC_ASSERT(!is_coinbase());
7✔
617

618
    const auto invalid = [](const auto& input) NOEXCEPT
9✔
619
    {
620
        return input->point().is_null();
9✔
621
    };
622

623
    // True if not coinbase but has null previous_output(s).
624
    return std::any_of(inputs_->begin(), inputs_->end(), invalid);
7✔
625
}
626

627
bool transaction::is_invalid_coinbase_size() const NOEXCEPT
9✔
628
{
629
    BC_ASSERT(is_coinbase());
9✔
630

631
    // True if coinbase and has invalid input[0] script size.
632
    const auto script_size = inputs_->front()->script().serialized_size(false);
9✔
633
    return script_size < min_coinbase_size || script_size > max_coinbase_size;
9✔
634
}
635

636
// Accept (contextual).
637
// ----------------------------------------------------------------------------
638

639
bool transaction::is_absolute_locked(size_t height, uint32_t timestamp,
5✔
640
    uint32_t median_time_past, bool bip113) const NOEXCEPT
641
{
642
    // BIP113: comparing the locktime against the median of the past 11 block
643
    // timestamps, rather than the timestamp of the block including the tx.
644
    const auto time = bip113 ? median_time_past : timestamp;
5✔
645

646
    const auto finalized = [](const auto& input) NOEXCEPT
2✔
647
    {
648
        return input->is_final();
2✔
649
    };
650

651
    const auto height_time = locktime_ < locktime_threshold ? height : time;
5✔
652

653
    return !(is_zero(locktime_) || locktime_ < height_time ||
5✔
654
        std::all_of(inputs_->begin(), inputs_->end(), finalized));
3✔
655
}
656

657
bool transaction::is_missing_prevouts() const NOEXCEPT
3✔
658
{
659
    BC_ASSERT(!is_coinbase());
3✔
660

661
    // Null or invalid prevout indicates not found.
662
    const auto missing = [](const auto& input) NOEXCEPT
2✔
663
    {
664
        return !input->prevout;
665
    };
666

667
    return std::any_of(inputs_->begin(), inputs_->end(), missing);
3✔
668
}
669

670
// The value() is the sum of own inputs.
671
uint64_t transaction::value() const NOEXCEPT
9✔
672
{
673
    // Overflow returns max_uint64. Not populated/coinbase return zero.
674
    const auto sum = [](uint64_t total, const auto& input) NOEXCEPT
7✔
675
    {
676
        const auto value = input->prevout ? input->prevout->value() : zero;
7✔
677
        return ceilinged_add(total, value);
7✔
678
    };
679

680
    // The amount referenced by inputs.
681
    return std::accumulate(inputs_->begin(), inputs_->end(), 0_u64, sum);
9✔
682
}
683

684
// The spend() is the sum of own outputs.
685
uint64_t transaction::spend() const NOEXCEPT
8✔
686
{
687
    // Overflow returns max_uint64.
688
    const auto sum = [](uint64_t total, const auto& output) NOEXCEPT
8✔
689
    {
690
        return ceilinged_add(total, output->value());
8✔
691
    };
692

693
    // The amount spent by outputs.
694
    return std::accumulate(outputs_->begin(), outputs_->end(), 0_u64, sum);
8✔
695
}
696

697
// Overspent is invalid (spend exceeds value), while underspent is the fee().
698
bool transaction::is_overspent() const NOEXCEPT
2✔
699
{
700
    BC_ASSERT(!is_coinbase());
2✔
701

702
    return spend() > value();
2✔
703
}
704

705
constexpr bool is_non_coinbase_immature(size_t prevout_height,
2✔
706
    size_t height) NOEXCEPT
707
{
708
    return height < prevout_height;
2✔
709
}
710

711
// static
712
//*****************************************************************************
713
// CONSENSUS: Coinbase output matures at 100 blocks depth.
714
// CONSENSUS: Genesis coinbase is forever immature (exception).
715
//*****************************************************************************
716
bool transaction::is_coinbase_immature(size_t coinbase_height,
3✔
717
    size_t height) NOEXCEPT
718
{
719
    return is_zero(coinbase_height) || (height < ceilinged_add(coinbase_height,
5✔
720
        coinbase_maturity));
3✔
721
}
722

723
bool transaction::is_immature(size_t height) const NOEXCEPT
6✔
724
{
725
    BC_ASSERT(!is_coinbase());
6✔
726

727
    // Spends internal to a block are handled by block validation.
728
    const auto immature = [=](const auto& input) NOEXCEPT
5✔
729
    {
730
        const auto prevout_height = input->metadata.prevout_height;
5✔
731
        return input->metadata.coinbase ?
5✔
732
            is_coinbase_immature(prevout_height, height) :
3✔
733
            is_non_coinbase_immature(prevout_height, height);
2✔
734
    };
6✔
735

736
    return std::any_of(inputs_->begin(), inputs_->end(), immature);
6✔
737
}
738

739
// static
740
bool transaction::is_relative_locktime_applied(bool coinbase, uint32_t version,
×
741
    uint32_t sequence) NOEXCEPT
742
{
743
    // BIP68: not applied to the sequence of the input of a coinbase.
744
    // BIP68: if bit 31 is set then no consensus meaning is applied.
745
    // BIP68: applied to txs with a version greater than or equal to two.
746
    return !coinbase && input::is_relative_locktime_applied(sequence) &&
×
747
        (version >= relative_locktime_min_version);
×
748
}
749

750
bool transaction::is_internally_locked(const input& in) const NOEXCEPT
×
751
{
752
    // BIP68: not applied to the sequence of the input of a coinbase.
753
    BC_ASSERT(!is_coinbase());
×
754

755
    // BIP68: applied to txs with a version greater than or equal to two.
756
    if (version_ < relative_locktime_min_version)
×
757
        return false;
758

759
    // Internal spends have no relative height/mtp (own metadata vs. itself).
760
    return in.is_relative_locked(in.metadata.prevout_height,
×
761
        in.metadata.median_time_past);
×
762
}
763

764
bool transaction::is_relative_locked(size_t height,
4✔
765
    uint32_t median_time_past) const NOEXCEPT
766
{
767
    // BIP68: not applied to the sequence of the input of a coinbase.
768
    BC_ASSERT(!is_coinbase());
4✔
769

770
    // BIP68: applied to txs with a version greater than or equal to two.
771
    if (version_ < relative_locktime_min_version)
4✔
772
        return false;
773

774
    // BIP68: references to median time past are as defined by bip113.
775
    const auto locked = [=](const auto& input) NOEXCEPT
2✔
776
    {
777
        return input->is_relative_locked(height, median_time_past);
2✔
778
    };
2✔
779

780
    return std::any_of(inputs_->begin(), inputs_->end(), locked);
2✔
781
}
782

783
bool transaction::is_unconfirmed_spend(size_t height) const NOEXCEPT
×
784
{
785
    BC_ASSERT(!is_coinbase());
×
786

787
    const auto unconfirmed = [=](const auto& input) NOEXCEPT
×
788
    {
789
        // Spends internal to a block are handled by block validation.
790
        // The lack of equality check here prevents conflict with self.
791
        return height < input->metadata.prevout_height;
×
792
    };
×
793

794
    return std::any_of(inputs_->begin(), inputs_->end(), unconfirmed);
×
795
}
796

797
bool transaction::is_confirmed_double_spend(size_t height) const NOEXCEPT
3✔
798
{
799
    BC_ASSERT(!is_coinbase());
3✔
800

801
    const auto spent = [=](const auto& input) NOEXCEPT
3✔
802
    {
803
        // Spends internal to a block are handled by block validation.
804
        // The lack of equality check here prevents conflict with self.
805
        return height > input->metadata.spender_height;
3✔
806
    };
3✔
807

808
    return std::any_of(inputs_->begin(), inputs_->end(), spent);
3✔
809
}
810

811
// Guards (for tx pool without compact blocks).
812
// ----------------------------------------------------------------------------
813

814
// Pools do not have coinbases.
815
// Redundant with block is_internal_double_spend check.
816
// Redundant with block max_block_size check.
817
code transaction::check_guard() const NOEXCEPT
×
818
{
819
    if (is_coinbase())
×
820
        return error::coinbase_transaction;
×
821
    if (is_internal_double_spend())
×
822
        return error::transaction_internal_double_spend;
×
823
    if (is_oversized())
×
824
        return error::transaction_size_limit;
×
825

826
    return error::transaction_success;
×
827
}
828

829
// Redundant with block max_block_weight accept.
830
code transaction::check_guard(const context& ctx) const NOEXCEPT
×
831
{
832
    const auto bip141 = ctx.is_enabled(flags::bip141_rule);
×
833

834
     if (!bip141 && is_segregated())
×
835
        return error::unexpected_witness_transaction;
×
836
     if (bip141 && is_overweight())
×
837
        return error::transaction_weight_limit;
×
838

839
    return error::transaction_success;
×
840
}
841

842
// Redundant with block max_block_sigops accept.
843
code transaction::accept_guard(const context& ctx) const NOEXCEPT
×
844
{
845
    const auto bip16 = ctx.is_enabled(flags::bip16_rule);
×
846
    const auto bip141 = ctx.is_enabled(flags::bip141_rule);
×
847

848
    if (is_missing_prevouts())
×
849
        return error::missing_previous_output;
×
850
    if (is_signature_operations_limited(bip16, bip141))
×
851
        return error::transaction_sigop_limit;
×
852

853
    return error::transaction_success;
×
854
}
855

856
// Validation.
857
// ----------------------------------------------------------------------------
858

859
// DO invoke on coinbase.
860
code transaction::check() const NOEXCEPT
5✔
861
{
862
    const auto coinbase = is_coinbase();
5✔
863

864
    if (is_empty())
5✔
865
        return error::empty_transaction;
×
866
    if (coinbase && is_invalid_coinbase_size())
5✔
867
        return error::invalid_coinbase_script_size;
×
868
    if (!coinbase && is_null_non_coinbase())
5✔
869
        return error::previous_output_null;
×
870

871
    return error::transaction_success;
5✔
872
}
873

874
// forks
875
// height
876
// timestamp
877
// median_time_past
878

879
// DO invoke on coinbase.
880
code transaction::check(const context& ctx) const NOEXCEPT
×
881
{
882
    const auto bip113 = ctx.is_enabled(bip113_rule);
×
883

884
    if (is_absolute_locked(ctx.height, ctx.timestamp, ctx.median_time_past, bip113))
×
885
        return error::absolute_time_locked;
×
886

887
    return error::transaction_success;
×
888
}
889

890
// Do not need to invoke on coinbase.
891
// This assumes that prevout caching is completed on all inputs.
892
code transaction::accept(const context&) const NOEXCEPT
×
893
{
894
    ////BC_ASSERT(!is_coinbase());
895

896
    if (is_coinbase())
×
897
        return error::transaction_success;
×
898
    if (is_missing_prevouts())
×
899
        return error::missing_previous_output;
×
900
    if (is_overspent())
×
901
        return error::spend_exceeds_value;
×
902

903
    return error::transaction_success;
×
904
}
905

906
// forks
907
// height
908
// median_time_past
909

910
// Do not need to invoke on coinbase.
911
// Node performs these checks through database query.
912
// This assumes that prevout and metadata caching are completed on all inputs.
913
code transaction::confirm(const context& ctx) const NOEXCEPT
×
914
{
915
    ////BC_ASSERT(!is_coinbase());
916
    const auto bip68 = ctx.is_enabled(bip68_rule);
×
917

918
    if (is_coinbase())
×
919
        return error::transaction_success;
×
920
    if (bip68 && is_relative_locked(ctx.height, ctx.median_time_past))
×
921
        return error::relative_time_locked;
×
922
    if (is_immature(ctx.height))
×
923
        return error::coinbase_maturity;
×
924
    if (is_unconfirmed_spend(ctx.height))
×
925
        return error::unconfirmed_spend;
×
926
    if (is_confirmed_double_spend(ctx.height))
×
927
        return error::confirmed_double_spend;
×
928

929
    return error::transaction_success;
×
930
}
931

932
// Delegated.
933
// ----------------------------------------------------------------------------
934

935
code transaction::connect_input(const context& ctx,
4✔
936
    const input_iterator& it) const NOEXCEPT
937
{
938
    using namespace machine;
4✔
939

940
    // TODO: evaluate performance tradeoff.
941
    if ((*it)->is_roller())
4✔
942
    {
943
        // Evaluate rolling scripts with linear search but constant erase.
944
        return interpreter<linked_stack>::connect(ctx, *this, it);
×
945
    }
946

947
    // Evaluate non-rolling scripts with constant search but linear erase.
948
    return interpreter<contiguous_stack>::connect(ctx, *this, it);
4✔
949
}
950

951
// Connect (contextual).
952
// ----------------------------------------------------------------------------
953
// TODO: accumulate sigops from each connect result and add coinbase.
954
// TODO: return in override with out parameter. more impactful with segwit.
955

956
// forks
957

958
code transaction::connect(const context& ctx) const NOEXCEPT
2✔
959
{
960
    ////BC_ASSERT(!is_coinbase());
961

962
    if (is_coinbase())
2✔
963
        return error::transaction_success;
×
964

965
    for (auto in = inputs_->begin(); in != inputs_->end(); ++in)
6✔
966
        if (const auto ec = connect_input(ctx, in))
4✔
967
            return ec;
×
968

969
    return error::transaction_success;
2✔
970
}
971

972
BC_POP_WARNING()
973

974
} // namespace chain
975
} // namespace system
976
} // namespace libbitcoin
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc