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

libbitcoin / libbitcoin-system / 14919053675

09 May 2025 12:53AM UTC coverage: 82.702% (-0.04%) from 82.739%
14919053675

push

github

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

Stub in taproot program version handling, rename enum values.

8 of 14 new or added lines in 5 files covered. (57.14%)

10284 of 12435 relevant lines covered (82.7%)

3874704.15 hits per line

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

73.5
/src/chain/transaction.cpp
1
/**
2
 * Copyright (c) 2011-2025 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 <type_traits>
25
#include <utility>
26
#include <vector>
27
#include <bitcoin/system/chain/context.hpp>
28
#include <bitcoin/system/chain/enums/coverage.hpp>
29
#include <bitcoin/system/chain/enums/magic_numbers.hpp>
30
#include <bitcoin/system/chain/header.hpp>
31
#include <bitcoin/system/chain/input.hpp>
32
#include <bitcoin/system/chain/output.hpp>
33
#include <bitcoin/system/chain/script.hpp>
34
#include <bitcoin/system/data/data.hpp>
35
#include <bitcoin/system/define.hpp>
36
#include <bitcoin/system/error/error.hpp>
37
#include <bitcoin/system/hash/hash.hpp>
38
#include <bitcoin/system/machine/machine.hpp>
39
#include <bitcoin/system/math/math.hpp>
40
#include <bitcoin/system/stream/stream.hpp>
41

42
namespace libbitcoin {
43
namespace system {
44
namespace chain {
45

46
BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)
47

48
// Constructors.
49
// ----------------------------------------------------------------------------
50

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

59
transaction::transaction(uint32_t version, chain::inputs&& inputs,
905✔
60
    chain::outputs&& outputs, uint32_t locktime) NOEXCEPT
905✔
61
  : transaction(version, to_shareds(std::move(inputs)),
905✔
62
      to_shareds(std::move(outputs)), locktime)
2,715✔
63
{
64
}
905✔
65

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

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

79
transaction::transaction(stream::in::fast&& stream, bool witness) NOEXCEPT
41✔
80
  : transaction(read::bytes::fast(stream), witness)
41✔
81
{
82
}
41✔
83

84
transaction::transaction(stream::in::fast& stream, bool witness) NOEXCEPT
2✔
85
  : transaction(read::bytes::fast(stream), witness)
2✔
86
{
87
}
2✔
88

89
transaction::transaction(std::istream&& stream, bool witness) NOEXCEPT
×
90
  : transaction(read::bytes::istream(stream), witness)
×
91
{
92
}
×
93

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

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

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

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

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

129
bool transaction::operator==(const transaction& other) const NOEXCEPT
60✔
130
{
131
    // Compares input/output elements, not pointers, cache not compared.
132
    return (version_ == other.version_)
60✔
133
        && (locktime_ == other.locktime_)
58✔
134
        && ((inputs_ == other.inputs_) || 
84✔
135
            deep_equal(*inputs_, *other.inputs_))
26✔
136
        && ((outputs_ == other.outputs_) ||
144✔
137
            deep_equal(*outputs_, *other.outputs_));
26✔
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
204✔
151
{
152
    auto& allocator = source.get_allocator();
204✔
153
    auto ins = to_non_const_raw_ptr(inputs_);
204✔
154
    auto count = source.read_size(max_block_size);
204✔
155
    ins->reserve(count);
204✔
156
    for (size_t in = 0; in < count; ++in)
453✔
157
        ins->emplace_back(CREATE(input, allocator, source));
249✔
158

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

165
    if (segregated_)
204✔
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 = 0; 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 = 0; 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
            for (auto& input: *inputs_)
35✔
185
                to_non_const_raw_ptr(input)->set_witness(source);
20✔
186
        }
187
        else
188
        {
189
            // Default witness is populated on input construct.
190
            for (size_t in = 0; in < inputs_->size(); ++in)
2✔
191
                witness::skip(source, true);
1✔
192
        }
193
    }
194
    else
195
    {
196
        auto outs = to_non_const_raw_ptr(outputs_);
188✔
197
        count = source.read_size(max_block_size);
188✔
198
        outs->reserve(count);
188✔
199
        for (size_t out = 0; out < count; ++out)
437✔
200
            outs->emplace_back(CREATE(output, allocator, source));
249✔
201
    }
202

203
    locktime_ = source.read_4_bytes_little_endian();
204✔
204
    size_ = serialized_size(*inputs_, *outputs_, segregated_);
204✔
205
    valid_ = source;
204✔
206
}
204✔
207
BC_POP_WARNING()
208

209
// Serialization.
210
// ----------------------------------------------------------------------------
211

212
// Transactions with empty witnesses always use old serialization (bip144).
213
// If no inputs are witness programs then witness hash is tx hash (bip141).
214
data_chunk transaction::to_data(bool witness) const NOEXCEPT
10✔
215
{
216
    witness &= segregated_;
10✔
217

218
    data_chunk data(serialized_size(witness));
10✔
219
    stream::out::fast ostream(data);
10✔
220
    write::bytes::fast out(ostream);
10✔
221
    to_data(out, witness);
10✔
222
    return data;
20✔
223
}
10✔
224

225
void transaction::to_data(std::ostream& stream, bool witness) const NOEXCEPT
1✔
226
{
227
    witness &= segregated_;
1✔
228

229
    write::bytes::ostream out(stream);
1✔
230
    to_data(out, witness);
1✔
231
}
1✔
232

233
void transaction::to_data(writer& sink, bool witness) const NOEXCEPT
966✔
234
{
235
    witness &= segregated_;
966✔
236

237
    sink.write_4_bytes_little_endian(version_);
966✔
238

239
    if (witness)
966✔
240
    {
241
        sink.write_byte(witness_marker);
2✔
242
        sink.write_byte(witness_enabled);
2✔
243
    }
244

245
    sink.write_variable(inputs_->size());
966✔
246
    for (const auto& input: *inputs_)
2,352✔
247
        input->to_data(sink);
1,386✔
248

249
    sink.write_variable(outputs_->size());
966✔
250
    for (const auto& output: *outputs_)
2,634✔
251
        output->to_data(sink);
1,668✔
252

253
    if (witness)
966✔
254
        for (auto& input: *inputs_)
5✔
255
            input->witness().to_data(sink, true);
3✔
256

257
    sink.write_4_bytes_little_endian(locktime_);
966✔
258
}
966✔
259

260
// static/private
261
transaction::sizes transaction::serialized_size(const input_cptrs& inputs,
1,131✔
262
    const output_cptrs& outputs, bool segregated) NOEXCEPT
263
{
264
    sizes size{ zero, zero };
1,131✔
265

266
    std::for_each(inputs.begin(), inputs.end(), [&](const auto& in) NOEXCEPT
2,314✔
267
    {
268
        size.nominal = ceilinged_add(size.nominal, in->nominal_size());
1,183✔
269
        if (segregated)
1,183✔
270
            size.witnessed = ceilinged_add(size.witnessed, in->witnessed_size());
64✔
271
    });
1,183✔
272

273
    const auto outs = [](size_t total, const auto& output) NOEXCEPT
394✔
274
    {
275
        return ceilinged_add(total, output->serialized_size());
394✔
276
    };
277

278
    constexpr auto base_const_size = sizeof(version_) + sizeof(locktime_);
1,131✔
279
    constexpr auto witness_const_size = sizeof(witness_marker) +
1,131✔
280
        sizeof(witness_enabled);
281

282
    const auto base_size =
1,131✔
283
        ceilinged_add(ceilinged_add(ceilinged_add(base_const_size,
1,131✔
284
            variable_size(inputs.size())), variable_size(outputs.size())),
285
            std::accumulate(outputs.begin(), outputs.end(), zero, outs));
286

287
    const auto nominal_size = ceilinged_add(base_size, size.nominal);
1,131✔
288

289
    // For non-segregated transactions, witnessed_size is nominal_size.
290
    const auto witnessed_size = segregated ? ceilinged_add(ceilinged_add(
1,131✔
291
        base_size, witness_const_size), size.witnessed) : nominal_size;
292

293
    // For non-segregated transactions, values are the same.
294
    return { nominal_size, witnessed_size };
1,131✔
295
}
296

297
size_t transaction::serialized_size(bool witness) const NOEXCEPT
613✔
298
{
299
    witness &= segregated_;
613✔
300

301
    return witness ? size_.witnessed : size_.nominal;
613✔
302
}
303

304
// Properties.
305
// ----------------------------------------------------------------------------
306

307
bool transaction::is_valid() const NOEXCEPT
777✔
308
{
309
    return valid_;
777✔
310
}
311

312
size_t transaction::spends() const NOEXCEPT
×
313
{
314
    return is_coinbase() ? zero : inputs_->size();
×
315
}
316

317
size_t transaction::inputs() const NOEXCEPT
1,569✔
318
{
319
    return inputs_->size();
1,569✔
320
}
321

322
size_t transaction::outputs() const NOEXCEPT
1✔
323
{
324
    return outputs_->size();
1✔
325
}
326

327
uint32_t transaction::version() const NOEXCEPT
6✔
328
{
329
    return version_;
4✔
330
}
331

332
uint32_t transaction::locktime() const NOEXCEPT
13✔
333
{
334
    return locktime_;
4✔
335
}
336

337
const inputs_cptr& transaction::inputs_ptr() const NOEXCEPT
2,446✔
338
{
339
    return inputs_;
2,446✔
340
}
341

342
const outputs_cptr& transaction::outputs_ptr() const NOEXCEPT
62✔
343
{
344
    return outputs_;
62✔
345
}
346

347
uint64_t transaction::fee() const NOEXCEPT
4✔
348
{
349
    // Underflow returns zero (and is_overspent() will be true).
350
    // This is value of prevouts spent by inputs minus that claimed by outputs.
351
    return floored_subtract(value(), claim());
4✔
352
}
353

354
void transaction::set_nominal_hash(const hash_digest& hash) const NOEXCEPT
20✔
355
{
356
    nominal_hash_ = hash;
20✔
357
}
1✔
358

359
void transaction::set_witness_hash(const hash_digest& hash) const NOEXCEPT
2✔
360
{
361
    witness_hash_ = hash;
2✔
362
}
1✔
363

364
const hash_digest& transaction::get_hash(bool witness) const NOEXCEPT
26✔
365
{
366
    if (witness)
26✔
367
    {
368
        if (!witness_hash_) set_witness_hash(hash(witness));
4✔
369
        return *witness_hash_;
3✔
370
    }
371
    else
372
    {
373
        if (!nominal_hash_) set_nominal_hash(hash(witness));
42✔
374
        return *nominal_hash_;
23✔
375
    }
376
}
377

378
hash_digest transaction::hash(bool witness) const NOEXCEPT
934✔
379
{
380
    if (segregated_)
934✔
381
    {
382
        if (witness)
23✔
383
        {
384
            // Witness coinbase tx hash is assumed to be null_hash (bip141).
385
            if (witness_hash_) return *witness_hash_;
×
386
            if (is_coinbase()) return null_hash;
×
387
        }
388
        else
389
        {
390
            if (nominal_hash_) return *nominal_hash_;
23✔
391
        }
392
    }
393
    else
394
    {
395
        if (nominal_hash_) return *nominal_hash_;
911✔
396
    }
397

398
    hash_digest digest{};
927✔
399
    stream::out::fast stream{ digest };
927✔
400
    hash::sha256x2::fast sink{ stream };
927✔
401
    to_data(sink, witness);
927✔
402
    sink.flush();
927✔
403
    return digest;
927✔
404
}
927✔
405

406
// static
407
hash_digest transaction::desegregated_hash(size_t witnessed,
×
408
    size_t unwitnessed, const uint8_t* data) NOEXCEPT
409
{
410
    if (is_null(data))
×
411
        return null_hash;
×
412

413
    constexpr auto preamble = sizeof(uint32_t) + two * sizeof(uint8_t);
×
414
    const auto puts = floored_subtract(unwitnessed, two * sizeof(uint32_t));
×
415
    const auto locktime = floored_subtract(witnessed, sizeof(uint32_t));
×
416

417
    hash_digest digest{};
×
418
    stream::out::fast stream{ digest };
×
419
    hash::sha256x2::fast sink{ stream };
×
420
    sink.write_bytes(data, sizeof(uint32_t));
×
421
    sink.write_bytes(std::next(data, preamble), puts);
×
422
    sink.write_bytes(std::next(data, locktime), sizeof(uint32_t));
×
423
    sink.flush();
×
424
    return digest;
×
425
}
×
426

427
// Methods.
428
// ----------------------------------------------------------------------------
429

430
bool transaction::is_dusty(uint64_t minimum_output_value) const NOEXCEPT
6✔
431
{
432
    const auto dusty = [=](const auto& output) NOEXCEPT
9✔
433
    {
434
        return output->is_dust(minimum_output_value);
9✔
435
    };
6✔
436

437
    return std::any_of(outputs_->begin(), outputs_->end(), dusty);
6✔
438
}
439

440
size_t transaction::signature_operations(bool bip16, bool bip141) const NOEXCEPT
1✔
441
{
442
    // Includes BIP16 p2sh additional sigops, max_size_t if prevout invalid.
443
    const auto in = [=](size_t total, const auto& input) NOEXCEPT
×
444
    {
445
        return ceilinged_add(total, input->signature_operations(bip16, bip141));
×
446
    };
1✔
447

448
    const auto out = [=](size_t total, const auto& output) NOEXCEPT
×
449
    {
450
        return ceilinged_add(total, output->signature_operations(bip141));
×
451
    };
1✔
452

453
    // Overflow returns max_size_t.
454
    return ceilinged_add(
1✔
455
        std::accumulate(inputs_->begin(), inputs_->end(), zero, in),
456
        std::accumulate(outputs_->begin(), outputs_->end(), zero, out));
1✔
457
}
458

459
// private
460
chain::points transaction::points() const NOEXCEPT
4✔
461
{
462
    chain::points out(inputs_->size());
4✔
463

464
    const auto point = [](const auto& input) NOEXCEPT
8✔
465
    {
466
        return input->point();
8✔
467
    };
468

469
    std::transform(inputs_->begin(), inputs_->end(), out.begin(), point);
4✔
470
    return out;
4✔
471
}
472

473
// Signatures (public)
474
// ----------------------------------------------------------------------------
475

476
// signature_hash exposed for op_check_multisig caching.
477
hash_digest transaction::signature_hash(const input_iterator& input,
41✔
478
    const script& sub, uint64_t value, uint8_t sighash_flags,
479
    script_version version, bool bip143) const NOEXCEPT
480
{
481
    // There is no rational interpretation of a signature hash for a coinbase.
482
    BC_ASSERT(!is_coinbase());
41✔
483

484
    switch (version)
41✔
485
    {
486
        case script_version::unversioned:
12✔
487
            return unversioned_signature_hash(input, sub, sighash_flags);
12✔
488
        case script_version::segwit:
29✔
489
            return version_0_signature_hash(input, sub, value, sighash_flags,
29✔
490
                bip143);
29✔
491

492
        // TODO: taproot.
NEW
493
        case script_version::taproot:
×
NEW
494
            return {};
×
495

496
        case script_version::reserved:
×
497
        default:
×
498
            return {};
×
499
    }
500
}
501

502
// This is not used internal to the library.
503
bool transaction::check_signature(const ec_signature& signature,
2✔
504
    const data_slice& public_key, const script& sub, uint32_t index,
505
    uint64_t value, uint8_t sighash_flags, script_version version,
506
    bool bip143) const NOEXCEPT
507
{
508
    if ((index >= inputs_->size()) || signature.empty() || public_key.empty())
2✔
509
        return false;
510

511
    const auto sighash = signature_hash(input_at(index), sub, value,
2✔
512
        sighash_flags, version, bip143);
513

514
    // Validate the EC signature.
515
    return verify_signature(public_key, sighash, signature);
2✔
516
}
517

518
// This is not used internal to the library.
519
bool transaction::create_endorsement(endorsement& out, const ec_secret& secret,
2✔
520
    const script& sub, uint32_t index, uint64_t value, uint8_t sighash_flags,
521
    script_version version, bool bip143) const NOEXCEPT
522
{
523
    if (index >= inputs_->size())
2✔
524
        return false;
525

526
    out.reserve(max_endorsement_size);
2✔
527
    const auto sighash = signature_hash(input_at(index), sub, value,
2✔
528
        sighash_flags, version, bip143);
529

530
    // Create the EC signature and encode as DER.
531
    ec_signature signature;
2✔
532
    if (!sign(signature, secret, sighash) || !encode_signature(out, signature))
2✔
533
        return false;
×
534

535
    // Add the sighash type to the end of the DER signature -> endorsement.
536
    out.push_back(sighash_flags);
2✔
537
    ////out.shrink_to_fit();
538
    return true;
2✔
539
}
540

541
// Guard (context free).
542
// ----------------------------------------------------------------------------
543

544
bool transaction::is_coinbase() const NOEXCEPT
80✔
545
{
546
    return is_one(inputs_->size()) && inputs_->front()->point().is_null();
80✔
547
}
548

549
bool transaction::is_internal_double_spend() const NOEXCEPT
4✔
550
{
551
    // TODO: optimize (see block.is_internal_double_spend).
552
    return !is_distinct(points());
4✔
553
}
554

555
// TODO: a pool (non-coinbase) tx must fit into a block (with a coinbase).
556
bool transaction::is_oversized() const NOEXCEPT
×
557
{
558
    return serialized_size(false) > max_block_size;
×
559
}
560

561
// Guard (contextual).
562
// ----------------------------------------------------------------------------
563

564
// static/private
565
bool transaction::segregated(const chain::inputs& inputs) NOEXCEPT
1✔
566
{
567
    const auto witnessed = [](const auto& input) NOEXCEPT
2✔
568
    {
569
        return !input.witness().stack().empty();
1✔
570
    };
571

572
    return std::any_of(inputs.begin(), inputs.end(), witnessed);
1✔
573
}
574

575
// static/private
576
bool transaction::segregated(const input_cptrs& inputs) NOEXCEPT
905✔
577
{
578
    const auto witnessed = [](const auto& input) NOEXCEPT
908✔
579
    {
580
        return !input->witness().stack().empty();
908✔
581
    };
582

583
    return std::any_of(inputs.begin(), inputs.end(), witnessed);
905✔
584
}
585

586
bool transaction::is_segregated() const NOEXCEPT
4✔
587
{
588
    return segregated_;
4✔
589
}
590

591
size_t transaction::weight() const NOEXCEPT
×
592
{
593
    // Block weight is 3 * base size * + 1 * total size (bip141).
594
    return ceilinged_add(
×
595
        ceilinged_multiply(base_size_contribution, serialized_size(false)),
596
        ceilinged_multiply(total_size_contribution, serialized_size(true)));
×
597
}
598

599
bool transaction::is_overweight() const NOEXCEPT
×
600
{
601
    return weight() > max_block_weight;
×
602
}
603

604
//*****************************************************************************
605
// CONSENSUS: Legacy sigops are counted in coinbase scripts despite the fact
606
// that coinbase input scripts are never executed. There is no need to exclude
607
// p2sh coinbase sigops since there is never a script to count.
608
//*****************************************************************************
609
bool transaction::is_signature_operations_limit(bool bip16,
×
610
    bool bip141) const NOEXCEPT
611
{
612
    const auto limit = bip141 ? max_fast_sigops : max_block_sigops;
×
613
    return signature_operations(bip16, bip141) > limit;
×
614
}
615

616
// Check (context free).
617
// ----------------------------------------------------------------------------
618

619
bool transaction::is_empty() const NOEXCEPT
9✔
620
{
621
    return inputs_->empty() || outputs_->empty();
9✔
622
}
623

624
bool transaction::is_null_non_coinbase() const NOEXCEPT
7✔
625
{
626
    BC_ASSERT(!is_coinbase());
7✔
627

628
    const auto invalid = [](const auto& input) NOEXCEPT
9✔
629
    {
630
        return input->point().is_null();
9✔
631
    };
632

633
    // True if not coinbase but has null previous_output(s).
634
    return std::any_of(inputs_->begin(), inputs_->end(), invalid);
7✔
635
}
636

637
bool transaction::is_invalid_coinbase_size() const NOEXCEPT
9✔
638
{
639
    BC_ASSERT(is_coinbase());
9✔
640

641
    // True if coinbase and has invalid input[0] script size.
642
    const auto script_size = inputs_->front()->script().serialized_size(false);
9✔
643
    return script_size < min_coinbase_size || script_size > max_coinbase_size;
9✔
644
}
645

646
// Accept (contextual).
647
// ----------------------------------------------------------------------------
648

649
bool transaction::is_absolute_locked(size_t height, uint32_t timestamp,
5✔
650
    uint32_t median_time_past, bool bip113) const NOEXCEPT
651
{
652
    // BIP113: comparing the locktime against the median of the past 11 block
653
    // timestamps, rather than the timestamp of the block including the tx.
654
    const auto time = bip113 ? median_time_past : timestamp;
5✔
655

656
    const auto finalized = [](const auto& input) NOEXCEPT
2✔
657
    {
658
        return input->is_final();
2✔
659
    };
660

661
    const auto height_time = locktime_ < locktime_threshold ? height : time;
5✔
662

663
    return !(is_zero(locktime_) || locktime_ < height_time ||
8✔
664
        std::all_of(inputs_->begin(), inputs_->end(), finalized));
3✔
665
}
666

667
bool transaction::is_missing_prevouts() const NOEXCEPT
3✔
668
{
669
    BC_ASSERT(!is_coinbase());
3✔
670

671
    // Null or invalid prevout indicates not found.
672
    const auto missing = [](const auto& input) NOEXCEPT
2✔
673
    {
674
        return !input->prevout;
675
    };
676

677
    return std::any_of(inputs_->begin(), inputs_->end(), missing);
3✔
678
}
679

680
uint64_t transaction::claim() const NOEXCEPT
8✔
681
{
682
    // Overflow returns max_uint64.
683
    const auto sum = [](uint64_t total, const auto& output) NOEXCEPT
8✔
684
    {
685
        return ceilinged_add(total, output->value());
8✔
686
    };
687

688
    // The amount claimed by outputs.
689
    return std::accumulate(outputs_->begin(), outputs_->end(), 0_u64, sum);
8✔
690
}
691

692
uint64_t transaction::value() const NOEXCEPT
9✔
693
{
694
    // Overflow, not populated, and coinbase (default) return max_uint64.
695
    const auto sum = [](uint64_t total, const auto& input) NOEXCEPT
7✔
696
    {
697
        const auto value = input->prevout ? input->prevout->value() : max_uint64;
7✔
698
        return ceilinged_add(total, value);
7✔
699
    };
700

701
    // The amount of prevouts (referenced by inputs).
702
    return std::accumulate(inputs_->begin(), inputs_->end(), 0_u64, sum);
9✔
703
}
704

705
bool transaction::is_overspent() const NOEXCEPT
2✔
706
{
707
    BC_ASSERT(!is_coinbase());
2✔
708

709
    return claim() > value();
2✔
710
}
711

712
constexpr bool is_non_coinbase_mature(size_t tx_height, size_t height) NOEXCEPT
2✔
713
{
714
    return tx_height <= height;
2✔
715
}
716

717
// static
718
//*****************************************************************************
719
// CONSENSUS: Coinbase output matures at 100 blocks depth.
720
// CONSENSUS: Genesis coinbase is forever immature (exception).
721
//*****************************************************************************
722
bool transaction::is_coinbase_mature(size_t coinbase_height,
3✔
723
    size_t height) NOEXCEPT
724
{
725
    return !is_zero(coinbase_height) &&
5✔
726
        ceilinged_add(coinbase_height, coinbase_maturity) <= height;
3✔
727
}
728

729
bool transaction::is_immature(size_t height) const NOEXCEPT
6✔
730
{
731
    BC_ASSERT(!is_coinbase());
6✔
732

733
    // Spends internal to a block are handled by block validation.
734
    const auto mature = [=](const auto& input) NOEXCEPT
5✔
735
    {
736
        return input->metadata.coinbase ?
5✔
737
            is_coinbase_mature(input->metadata.height, height) :
3✔
738
            is_non_coinbase_mature(input->metadata.height, height);
2✔
739
    };
6✔
740

741
    return !std::all_of(inputs_->begin(), inputs_->end(), mature);
6✔
742
}
743

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

755
bool transaction::is_internally_locked(const input& in) const NOEXCEPT
×
756
{
757
    // BIP68: not applied to the sequence of the input of a coinbase.
758
    BC_ASSERT(!is_coinbase());
×
759

760
    // BIP68: applied to txs with a version greater than or equal to two.
761
    if (version_ < relative_locktime_min_version)
×
762
        return false;
763

764
    // Internal spends have no relative height/mtp (own metadata vs. itself).
765
    return in.is_relative_locked(in.metadata.height,
×
766
        in.metadata.median_time_past);
×
767
}
768

769
bool transaction::is_relative_locked(size_t height,
4✔
770
    uint32_t median_time_past) const NOEXCEPT
771
{
772
    // BIP68: not applied to the sequence of the input of a coinbase.
773
    BC_ASSERT(!is_coinbase());
4✔
774

775
    // BIP68: applied to txs with a version greater than or equal to two.
776
    if (version_ < relative_locktime_min_version)
4✔
777
        return false;
778

779
    // BIP68: references to median time past are as defined by bip113.
780
    const auto locked = [=](const auto& input) NOEXCEPT
2✔
781
    {
782
        return input->is_relative_locked(height, median_time_past);
2✔
783
    };
2✔
784

785
    return std::any_of(inputs_->begin(), inputs_->end(), locked);
2✔
786
}
787

788
// Spends internal to a block are handled by block validation.
789
bool transaction::is_unconfirmed_spend(size_t height) const NOEXCEPT
×
790
{
791
    BC_ASSERT(!is_coinbase());
×
792

793
    // Zero is either genesis or not found.
794
    // Test maturity first to obtain proper error code.
795
    // Spends internal to a block are handled by block validation.
796
    const auto unconfirmed = [=](const auto& input) NOEXCEPT
×
797
    {
798
        const auto prevout_height = input->metadata.height;
×
799
        return is_zero(prevout_height) && !(height > prevout_height);
×
800
    };
×
801

802
    return std::any_of(inputs_->begin(), inputs_->end(), unconfirmed);
×
803
}
804

805
bool transaction::is_confirmed_double_spend(size_t height) const NOEXCEPT
4✔
806
{
807
    BC_ASSERT(!is_coinbase());
4✔
808

809
    // Spends internal to a block are handled by block validation.
810
    const auto spent = [=](const auto& input) NOEXCEPT
3✔
811
    {
812
        return input->metadata.spent && height > input->metadata.height;
3✔
813
    };
4✔
814

815
    return std::any_of(inputs_->begin(), inputs_->end(), spent);
4✔
816
}
817

818
// Guards (for tx pool without compact blocks).
819
// ----------------------------------------------------------------------------
820

821
// Pools do not have coinbases.
822
// Redundant with block is_internal_double_spend check.
823
// Redundant with block max_block_size check.
824
code transaction::guard_check() const NOEXCEPT
×
825
{
826
    if (is_coinbase())
×
827
        return error::coinbase_transaction;
×
828
    if (is_internal_double_spend())
×
829
        return error::transaction_internal_double_spend;
×
830
    if (is_oversized())
×
831
        return error::transaction_size_limit;
×
832

833
    return error::transaction_success;
×
834
}
835

836
// Redundant with block max_block_weight accept.
837
code transaction::guard_check(const context& ctx) const NOEXCEPT
×
838
{
839
    const auto bip141 = ctx.is_enabled(flags::bip141_rule);
×
840

841
     if (!bip141 && is_segregated())
×
842
        return error::unexpected_witness_transaction;
×
843
     if (bip141 && is_overweight())
×
844
        return error::transaction_weight_limit;
×
845

846
    return error::transaction_success;
×
847
}
848

849
// Redundant with block max_block_sigops accept.
850
code transaction::guard_accept(const context& ctx) const NOEXCEPT
×
851
{
852
    const auto bip16 = ctx.is_enabled(flags::bip16_rule);
×
853
    const auto bip141 = ctx.is_enabled(flags::bip141_rule);
×
854

855
    if (is_missing_prevouts())
×
856
        return error::missing_previous_output;
×
857
    if (is_signature_operations_limit(bip16, bip141))
×
858
        return error::transaction_sigop_limit;
×
859

860
    return error::transaction_success;
×
861
}
862

863
// Validation.
864
// ----------------------------------------------------------------------------
865

866
// DO invoke on coinbase.
867
code transaction::check() const NOEXCEPT
5✔
868
{
869
    const auto coinbase = is_coinbase();
5✔
870

871
    if (is_empty())
5✔
872
        return error::empty_transaction;
×
873
    if (coinbase && is_invalid_coinbase_size())
5✔
874
        return error::invalid_coinbase_script_size;
×
875
    if (!coinbase && is_null_non_coinbase())
5✔
876
        return error::previous_output_null;
×
877

878
    return error::transaction_success;
5✔
879
}
880

881
// forks
882
// height
883
// timestamp
884
// median_time_past
885

886
// DO invoke on coinbase.
887
code transaction::check(const context& ctx) const NOEXCEPT
×
888
{
889
    const auto bip113 = ctx.is_enabled(bip113_rule);
×
890

891
    if (is_absolute_locked(ctx.height, ctx.timestamp, ctx.median_time_past, bip113))
×
892
        return error::absolute_time_locked;
×
893

894
    return error::transaction_success;
×
895
}
896

897
// Do not need to invoke on coinbase.
898
// This assumes that prevout caching is completed on all inputs.
899
code transaction::accept(const context&) const NOEXCEPT
×
900
{
901
    ////BC_ASSERT(!is_coinbase());
902

903
    if (is_coinbase())
×
904
        return error::transaction_success;
×
905
    if (is_missing_prevouts())
×
906
        return error::missing_previous_output;
×
907
    if (is_overspent())
×
908
        return error::spend_exceeds_value;
×
909

910
    return error::transaction_success;
×
911
}
912

913
// forks
914
// height
915
// median_time_past
916

917
// Do not need to invoke on coinbase.
918
// Node performs these checks through database query.
919
// This assumes that prevout and metadata caching are completed on all inputs.
920
code transaction::confirm(const context& ctx) const NOEXCEPT
×
921
{
922
    ////BC_ASSERT(!is_coinbase());
923
    const auto bip68 = ctx.is_enabled(bip68_rule);
×
924

925
    if (is_coinbase())
×
926
        return error::transaction_success;
×
927
    if (bip68 && is_relative_locked(ctx.height, ctx.median_time_past))
×
928
        return error::relative_time_locked;
×
929
    if (is_immature(ctx.height))
×
930
        return error::coinbase_maturity;
×
931
    if (is_unconfirmed_spend(ctx.height))
×
932
        return error::unconfirmed_spend;
×
933
    if (is_confirmed_double_spend(ctx.height))
×
934
        return error::confirmed_double_spend;
×
935

936
    return error::transaction_success;
×
937
}
938

939
// Delegated.
940
// ----------------------------------------------------------------------------
941

942
code transaction::connect_input(const context& ctx,
4✔
943
    const input_iterator& it) const NOEXCEPT
944
{
945
    using namespace machine;
4✔
946

947
    // TODO: evaluate performance tradeoff.
948
    if ((*it)->is_roller())
4✔
949
    {
950
        // Evaluate rolling scripts with linear search but constant erase.
951
        return interpreter<linked_stack>::connect(ctx, *this, it);
×
952
    }
953

954
    // Evaluate non-rolling scripts with constant search but linear erase.
955
    return interpreter<contiguous_stack>::connect(ctx, *this, it);
4✔
956
}
957

958
// Connect (contextual).
959
// ----------------------------------------------------------------------------
960
// TODO: accumulate sigops from each connect result and add coinbase.
961
// TODO: return in override with out parameter. more impactful with segwit.
962

963
// forks
964

965
// Do not need to invoke on coinbase.
966
// This assumes that prevout caching is completed on all inputs.
967
code transaction::connect(const context& ctx) const NOEXCEPT
2✔
968
{
969
    ////BC_ASSERT(!is_coinbase());
970

971
    if (is_coinbase())
2✔
972
        return error::transaction_success;
×
973

974
    initialize_sighash_cache();
2✔
975

976
    for (auto in = inputs_->begin(); in != inputs_->end(); ++in)
6✔
977
        if (const auto ec = connect_input(ctx, in))
4✔
978
            return ec;
×
979

980
    return error::transaction_success;
2✔
981
}
982

983
BC_POP_WARNING()
984

985
// JSON value convertors.
986
// ----------------------------------------------------------------------------
987

988
namespace json = boost::json;
989

990
// boost/json will soon have NOEXCEPT: github.com/boostorg/json/pull/636
991
BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)
992

993
transaction tag_invoke(json::value_to_tag<transaction>,
2✔
994
    const json::value& value) NOEXCEPT
995
{
996
    return
2✔
997
    {
998
        value.at("version").to_number<uint32_t>(),
2✔
999
        json::value_to<chain::inputs>(value.at("inputs")),
2✔
1000
        json::value_to<chain::outputs>(value.at("outputs")),
4✔
1001
        value.at("locktime").to_number<uint32_t>()
4✔
1002
    };
4✔
1003
}
1004

1005
void tag_invoke(json::value_from_tag, json::value& value,
4✔
1006
    const transaction& tx) NOEXCEPT
1007
{
1008
    value =
4✔
1009
    {
1010
        { "version", tx.version() },
1011
        { "inputs", *tx.inputs_ptr() },
1012
        { "outputs", *tx.outputs_ptr() },
1013
        { "locktime", tx.locktime() }
1014
    };
4✔
1015
}
4✔
1016

1017
BC_POP_WARNING()
1018

1019
transaction::cptr tag_invoke(json::value_to_tag<transaction::cptr>,
×
1020
    const json::value& value) NOEXCEPT
1021
{
1022
    return to_shared(tag_invoke(json::value_to_tag<transaction>{}, value));
×
1023
}
1024

1025
// Shared pointer overload is required for navigation.
1026
BC_PUSH_WARNING(SMART_PTR_NOT_NEEDED)
1027
BC_PUSH_WARNING(NO_VALUE_OR_CONST_REF_SHARED_PTR)
1028

1029
void tag_invoke(json::value_from_tag tag, json::value& value,
2✔
1030
    const transaction::cptr& tx) NOEXCEPT
1031
{
1032
    tag_invoke(tag, value, *tx);
2✔
1033
}
2✔
1034

1035
BC_POP_WARNING()
1036
BC_POP_WARNING()
1037

1038
} // namespace chain
1039
} // namespace system
1040
} // 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