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

libbitcoin / libbitcoin-system / 18823651969

26 Oct 2025 09:01PM UTC coverage: 80.946% (+0.04%) from 80.903%
18823651969

push

github

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

Simplify and optimize JSON annotation defines.

104 of 136 new or added lines in 16 files covered. (76.47%)

1 existing line in 1 file now uncovered.

10591 of 13084 relevant lines covered (80.95%)

3619070.67 hits per line

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

76.11
/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 <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,
905✔
58
    chain::outputs&& outputs, uint32_t locktime) NOEXCEPT
905✔
59
  : transaction(version, to_shareds(std::move(inputs)),
905✔
60
      to_shareds(std::move(outputs)), locktime)
2,715✔
61
{
62
}
905✔
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,
905✔
72
    const outputs_cptr& outputs, uint32_t locktime) NOEXCEPT
905✔
73
  : transaction(version, inputs, outputs, locktime, segregated(*inputs), true)
905✔
74
{
75
}
905✔
76

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

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

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

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

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

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

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

124
// Operators.
125
// ----------------------------------------------------------------------------
126

127
bool transaction::operator==(const transaction& other) const NOEXCEPT
60✔
128
{
129
    // Compares input/output elements, not pointers, cache not compared.
130
    return (version_ == other.version_)
60✔
131
        && (locktime_ == other.locktime_)
58✔
132
        && ((inputs_ == other.inputs_) || 
84✔
133
            deep_equal(*inputs_, *other.inputs_))
26✔
134
        && ((outputs_ == other.outputs_) ||
144✔
135
            deep_equal(*outputs_, *other.outputs_));
26✔
136
}
137

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

143
// Deserialization.
144
// ----------------------------------------------------------------------------
145

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

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

163
    if (segregated_)
204✔
164
    {
165
        // Skip over the peeked witness flag.
166
        source.skip_byte();
16✔
167

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

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

179
        // Read or skip witnesses as specified.
180
        if (witness)
16✔
181
        {
182
            for (auto& input: *inputs_)
35✔
183
                to_non_const_raw_ptr(input)->set_witness(source);
20✔
184
        }
185
        else
186
        {
187
            // Default witness is populated on input construct.
188
            for (size_t in = 0; in < inputs_->size(); ++in)
2✔
189
                witness::skip(source, true);
1✔
190
        }
191
    }
192
    else
193
    {
194
        auto outs = to_non_const_raw_ptr(outputs_);
188✔
195
        count = source.read_size(max_block_size);
188✔
196
        outs->reserve(count);
188✔
197
        for (size_t out = 0; out < count; ++out)
437✔
198
            outs->emplace_back(CREATE(output, allocator, source));
249✔
199
    }
200

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

207
// Serialization.
208
// ----------------------------------------------------------------------------
209

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

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

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

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

231
void transaction::to_data(writer& sink, bool witness) const NOEXCEPT
965✔
232
{
233
    witness &= segregated_;
965✔
234

235
    sink.write_4_bytes_little_endian(version_);
965✔
236

237
    if (witness)
965✔
238
    {
239
        sink.write_byte(witness_marker);
2✔
240
        sink.write_byte(witness_enabled);
2✔
241
    }
242

243
    sink.write_variable(inputs_->size());
965✔
244
    for (const auto& input: *inputs_)
2,350✔
245
        input->to_data(sink);
1,385✔
246

247
    sink.write_variable(outputs_->size());
965✔
248
    for (const auto& output: *outputs_)
2,632✔
249
        output->to_data(sink);
1,667✔
250

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

255
    sink.write_4_bytes_little_endian(locktime_);
965✔
256
}
965✔
257

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

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

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

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

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

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

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

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

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

299
    return witness ? size_.witnessed : size_.nominal;
613✔
300
}
301

302
// Properties.
303
// ----------------------------------------------------------------------------
304

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

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

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

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

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

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

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

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

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

352
// Methods.
353
// ----------------------------------------------------------------------------
354

355
bool transaction::is_dusty(uint64_t minimum_output_value) const NOEXCEPT
6✔
356
{
357
    const auto dusty = [=](const auto& output) NOEXCEPT
9✔
358
    {
359
        return output->is_dust(minimum_output_value);
9✔
360
    };
6✔
361

362
    return std::any_of(outputs_->begin(), outputs_->end(), dusty);
6✔
363
}
364

365
size_t transaction::signature_operations(bool bip16, bool bip141) const NOEXCEPT
1✔
366
{
367
    // Overflow returns max_size_t.
368
    const auto in = [=](size_t total, const auto& input) NOEXCEPT
×
369
    {
370
        const auto add = input->signature_operations(bip16, bip141);
×
371
        return ceilinged_add(total, add);
×
372
    };
1✔
373

374
    // Overflow returns max_size_t.
375
    const auto out = [=](size_t total, const auto& output) NOEXCEPT
×
376
    {
377
        const auto add = output->signature_operations(bip141);
×
378
        return ceilinged_add(total, add);
×
379
    };
1✔
380

381
    // Overflow returns max_size_t.
382
    return ceilinged_add(
1✔
383
        std::accumulate(inputs_->begin(), inputs_->end(), zero, in),
384
        std::accumulate(outputs_->begin(), outputs_->end(), zero, out));
1✔
385
}
386

387
// private
388
chain::points transaction::points() const NOEXCEPT
4✔
389
{
390
    chain::points out(inputs_->size());
4✔
391

392
    const auto point = [](const auto& input) NOEXCEPT
8✔
393
    {
394
        return input->point();
8✔
395
    };
396

397
    std::transform(inputs_->begin(), inputs_->end(), out.begin(), point);
4✔
398
    return out;
4✔
399
}
400

401
// Signatures (public).
402
// ----------------------------------------------------------------------------
403

404
transaction::input_iterator transaction::input_at(
4✔
405
    uint32_t index) const NOEXCEPT
406
{
407
    // Guarded by check_signature and create_endorsement.
408
    BC_ASSERT_MSG(index < inputs_->size(), "invalid input index");
4✔
409

410
    return std::next(inputs_->begin(), index);
4✔
411
}
412

413
// This is not used internal to the library.
414
bool transaction::check_signature(const ec_signature& signature,
2✔
415
    const data_slice& public_key, const script& subscript, uint32_t index,
416
    uint64_t value, uint8_t sighash_flags, script_version version,
417
    uint32_t flags) const NOEXCEPT
418
{
419
    if ((index >= inputs_->size()) || signature.empty() || public_key.empty())
2✔
420
        return false;
421

422
    hash_digest sighash{};
2✔
423
    const hash_cptr unused{};
2✔
424
    if (!signature_hash(sighash, input_at(index), subscript, value,
2✔
425
        unused, version, sighash_flags, flags))
426
        return false;
427

428
    // Validate the ECDSA signature.
429
    return ecdsa::verify_signature(public_key, sighash, signature);
2✔
430
}
431

432
// This is not used internal to the library.
433
bool transaction::create_endorsement(endorsement& out, const ec_secret& secret,
2✔
434
    const script& subscript, uint32_t index, uint64_t value,
435
    uint8_t sighash_flags, script_version version,
436
    uint32_t flags) const NOEXCEPT
437
{
438
    if (index >= inputs_->size())
2✔
439
        return false;
440

441
    hash_digest sighash{};
2✔
442
    const hash_cptr unused{};
2✔
443
    out.reserve(max_endorsement_size);
2✔
444
    if (!signature_hash(sighash, input_at(index), subscript, value, unused,
2✔
445
        version, sighash_flags, flags))
446
        return false;
447

448
    // Create the ECDSA signature and encode as DER.
449
    ec_signature signature;
2✔
450
    if (!ecdsa::sign(signature, secret, sighash) ||
4✔
451
        !ecdsa::encode_signature(out, signature))
2✔
452
        return false;
×
453

454
    // Add the sighash type to the end of the DER signature -> endorsement.
455
    out.push_back(sighash_flags);
2✔
456
    ////out.shrink_to_fit();
457
    return true;
2✔
458
}
459

460
// Signature hashing (common).
461
// ----------------------------------------------------------------------------
462

463
uint32_t transaction::input_index(const input_iterator& input) const NOEXCEPT
25✔
464
{
465
    return possible_narrow_and_sign_cast<uint32_t>(
25✔
466
        std::distance(inputs_->begin(), input));
25✔
467
}
468

469
//*****************************************************************************
470
// CONSENSUS: if index exceeds outputs in signature hash, return one_hash.
471
// Related Bug: bitcointalk.org/index.php?topic=260595
472
// Exploit: joncave.co.uk/2014/08/bitcoin-sighash-single/
473
//*****************************************************************************
474
bool transaction::output_overflow(size_t input) const NOEXCEPT
21✔
475
{
476
    return input >= outputs_->size();
21✔
477
}
478

479
// There are three versions of signature hashing and verification.
480
// Version: (unversioned) original, (v0) bip143/segwit, (v1) bip341/taproot.
481
bool transaction::signature_hash(hash_digest& out, const input_iterator& input,
41✔
482
    const script& subscript, uint64_t value, const hash_cptr& tapleaf,
483
    script_version version, uint8_t sighash_flags, uint32_t flags) const NOEXCEPT
484
{
485
    // There is no rational interpretation of a signature hash for a coinbase.
486
    BC_ASSERT(!is_coinbase());
41✔
487

488
    // bip143: the method of signature hashing is changed for v0 scripts.
489
    // bip342: the method of signature hashing is changed for v1 scripts.
490
    const auto bip143 = script::is_enabled(flags, flags::bip143_rule);
41✔
491
    const auto bip342 = script::is_enabled(flags, flags::bip342_rule);
41✔
492

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

499
    // This is where the connection between bip341 and bip342 is made. If a
500
    // version 2 program (taproot) extracted by bip341 but bip342 (tapscript)
501
    // is not active then drop down to unversioned signature hashing. 
502
    if (bip342 && version == script_version::taproot)
19✔
503
        return version1_sighash(out, input, subscript, value, tapleaf,
×
504
            sighash_flags);
×
505

506
    // Given above forks are documented to activate together, this distinction
507
    // is moot, however these are distinct BIPs and therefore must be either be
508
    // differentiated as such in code, or the BIP distiction would be ignored.
509
    return unversioned_sighash(out, input, subscript, sighash_flags);
19✔
510
}
511

512
// Guard (context free).
513
// ----------------------------------------------------------------------------
514

515
bool transaction::is_coinbase() const NOEXCEPT
80✔
516
{
517
    return is_one(inputs_->size()) && inputs_->front()->point().is_null();
80✔
518
}
519

520
bool transaction::is_internal_double_spend() const NOEXCEPT
4✔
521
{
522
    // TODO: optimize (see block.is_internal_double_spend).
523
    return !is_distinct(points());
4✔
524
}
525

526
// TODO: a pool (non-coinbase) tx must fit into a block (with a coinbase).
527
bool transaction::is_oversized() const NOEXCEPT
×
528
{
529
    return serialized_size(false) > max_block_size;
×
530
}
531

532
// Guard (contextual).
533
// ----------------------------------------------------------------------------
534

535
// static/private
536
bool transaction::segregated(const chain::inputs& inputs) NOEXCEPT
1✔
537
{
538
    const auto witnessed = [](const auto& input) NOEXCEPT
2✔
539
    {
540
        return !input.witness().stack().empty();
1✔
541
    };
542

543
    return std::any_of(inputs.begin(), inputs.end(), witnessed);
1✔
544
}
545

546
// static/private
547
bool transaction::segregated(const input_cptrs& inputs) NOEXCEPT
905✔
548
{
549
    const auto witnessed = [](const auto& input) NOEXCEPT
908✔
550
    {
551
        return !input->witness().stack().empty();
908✔
552
    };
553

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

557
bool transaction::is_segregated() const NOEXCEPT
4✔
558
{
559
    return segregated_;
4✔
560
}
561

562
size_t transaction::weight() const NOEXCEPT
×
563
{
564
    // Block weight is 3 * base size * + 1 * total size [bip141].
565
    return ceilinged_add(
×
566
        ceilinged_multiply(base_size_contribution, serialized_size(false)),
567
        ceilinged_multiply(total_size_contribution, serialized_size(true)));
×
568
}
569

570
bool transaction::is_overweight() const NOEXCEPT
×
571
{
572
    return weight() > max_block_weight;
×
573
}
574

575
//*****************************************************************************
576
// CONSENSUS: Legacy sigops are counted in coinbase scripts despite the fact
577
// that coinbase input scripts are never executed. There is no need to exclude
578
// p2sh coinbase sigops since there is never a script to count.
579
//*****************************************************************************
580
bool transaction::is_signature_operations_limited(bool bip16,
×
581
    bool bip141) const NOEXCEPT
582
{
583
    const auto limit = bip141 ? max_fast_sigops : max_block_sigops;
×
584
    return signature_operations(bip16, bip141) > limit;
×
585
}
586

587
// Check (context free).
588
// ----------------------------------------------------------------------------
589

590
bool transaction::is_empty() const NOEXCEPT
9✔
591
{
592
    return inputs_->empty() || outputs_->empty();
9✔
593
}
594

595
bool transaction::is_null_non_coinbase() const NOEXCEPT
7✔
596
{
597
    BC_ASSERT(!is_coinbase());
7✔
598

599
    const auto invalid = [](const auto& input) NOEXCEPT
9✔
600
    {
601
        return input->point().is_null();
9✔
602
    };
603

604
    // True if not coinbase but has null previous_output(s).
605
    return std::any_of(inputs_->begin(), inputs_->end(), invalid);
7✔
606
}
607

608
bool transaction::is_invalid_coinbase_size() const NOEXCEPT
9✔
609
{
610
    BC_ASSERT(is_coinbase());
9✔
611

612
    // True if coinbase and has invalid input[0] script size.
613
    const auto script_size = inputs_->front()->script().serialized_size(false);
9✔
614
    return script_size < min_coinbase_size || script_size > max_coinbase_size;
9✔
615
}
616

617
// Accept (contextual).
618
// ----------------------------------------------------------------------------
619

620
bool transaction::is_absolute_locked(size_t height, uint32_t timestamp,
5✔
621
    uint32_t median_time_past, bool bip113) const NOEXCEPT
622
{
623
    // BIP113: comparing the locktime against the median of the past 11 block
624
    // timestamps, rather than the timestamp of the block including the tx.
625
    const auto time = bip113 ? median_time_past : timestamp;
5✔
626

627
    const auto finalized = [](const auto& input) NOEXCEPT
2✔
628
    {
629
        return input->is_final();
2✔
630
    };
631

632
    const auto height_time = locktime_ < locktime_threshold ? height : time;
5✔
633

634
    return !(is_zero(locktime_) || locktime_ < height_time ||
8✔
635
        std::all_of(inputs_->begin(), inputs_->end(), finalized));
3✔
636
}
637

638
bool transaction::is_missing_prevouts() const NOEXCEPT
3✔
639
{
640
    BC_ASSERT(!is_coinbase());
3✔
641

642
    // Null or invalid prevout indicates not found.
643
    const auto missing = [](const auto& input) NOEXCEPT
2✔
644
    {
645
        return !input->prevout;
646
    };
647

648
    return std::any_of(inputs_->begin(), inputs_->end(), missing);
3✔
649
}
650

651
uint64_t transaction::claim() const NOEXCEPT
8✔
652
{
653
    // Overflow returns max_uint64.
654
    const auto sum = [](uint64_t total, const auto& output) NOEXCEPT
8✔
655
    {
656
        return ceilinged_add(total, output->value());
8✔
657
    };
658

659
    // The amount claimed by outputs.
660
    return std::accumulate(outputs_->begin(), outputs_->end(), 0_u64, sum);
8✔
661
}
662

663
uint64_t transaction::value() const NOEXCEPT
9✔
664
{
665
    // Overflow, not populated, and coinbase (default) return max_uint64.
666
    const auto sum = [](uint64_t total, const auto& input) NOEXCEPT
7✔
667
    {
668
        const auto value = input->prevout ? input->prevout->value() : max_uint64;
7✔
669
        return ceilinged_add(total, value);
7✔
670
    };
671

672
    // The amount of prevouts (referenced by inputs).
673
    return std::accumulate(inputs_->begin(), inputs_->end(), 0_u64, sum);
9✔
674
}
675

676
bool transaction::is_overspent() const NOEXCEPT
2✔
677
{
678
    BC_ASSERT(!is_coinbase());
2✔
679

680
    return claim() > value();
2✔
681
}
682

683
constexpr bool is_non_coinbase_mature(size_t tx_height, size_t height) NOEXCEPT
2✔
684
{
685
    return tx_height <= height;
2✔
686
}
687

688
// static
689
//*****************************************************************************
690
// CONSENSUS: Coinbase output matures at 100 blocks depth.
691
// CONSENSUS: Genesis coinbase is forever immature (exception).
692
//*****************************************************************************
693
bool transaction::is_coinbase_mature(size_t coinbase_height,
3✔
694
    size_t height) NOEXCEPT
695
{
696
    return !is_zero(coinbase_height) &&
5✔
697
        ceilinged_add(coinbase_height, coinbase_maturity) <= height;
3✔
698
}
699

700
bool transaction::is_immature(size_t height) const NOEXCEPT
6✔
701
{
702
    BC_ASSERT(!is_coinbase());
6✔
703

704
    // Spends internal to a block are handled by block validation.
705
    const auto mature = [=](const auto& input) NOEXCEPT
5✔
706
    {
707
        return input->metadata.coinbase ?
5✔
708
            is_coinbase_mature(input->metadata.height, height) :
3✔
709
            is_non_coinbase_mature(input->metadata.height, height);
2✔
710
    };
6✔
711

712
    return !std::all_of(inputs_->begin(), inputs_->end(), mature);
6✔
713
}
714

715
// static
716
bool transaction::is_relative_locktime_applied(bool coinbase, uint32_t version,
×
717
    uint32_t sequence) NOEXCEPT
718
{
719
    // BIP68: not applied to the sequence of the input of a coinbase.
720
    // BIP68: if bit 31 is set then no consensus meaning is applied.
721
    // BIP68: applied to txs with a version greater than or equal to two.
722
    return !coinbase && input::is_relative_locktime_applied(sequence) &&
×
723
        (version >= relative_locktime_min_version);
×
724
}
725

726
bool transaction::is_internally_locked(const input& in) const NOEXCEPT
×
727
{
728
    // BIP68: not applied to the sequence of the input of a coinbase.
729
    BC_ASSERT(!is_coinbase());
×
730

731
    // BIP68: applied to txs with a version greater than or equal to two.
732
    if (version_ < relative_locktime_min_version)
×
733
        return false;
734

735
    // Internal spends have no relative height/mtp (own metadata vs. itself).
736
    return in.is_relative_locked(in.metadata.height,
×
737
        in.metadata.median_time_past);
×
738
}
739

740
bool transaction::is_relative_locked(size_t height,
4✔
741
    uint32_t median_time_past) const NOEXCEPT
742
{
743
    // BIP68: not applied to the sequence of the input of a coinbase.
744
    BC_ASSERT(!is_coinbase());
4✔
745

746
    // BIP68: applied to txs with a version greater than or equal to two.
747
    if (version_ < relative_locktime_min_version)
4✔
748
        return false;
749

750
    // BIP68: references to median time past are as defined by bip113.
751
    const auto locked = [=](const auto& input) NOEXCEPT
2✔
752
    {
753
        return input->is_relative_locked(height, median_time_past);
2✔
754
    };
2✔
755

756
    return std::any_of(inputs_->begin(), inputs_->end(), locked);
2✔
757
}
758

759
// Spends internal to a block are handled by block validation.
760
bool transaction::is_unconfirmed_spend(size_t height) const NOEXCEPT
×
761
{
762
    BC_ASSERT(!is_coinbase());
×
763

764
    // Zero is either genesis or not found.
765
    // Test maturity first to obtain proper error code.
766
    // Spends internal to a block are handled by block validation.
767
    const auto unconfirmed = [=](const auto& input) NOEXCEPT
×
768
    {
769
        const auto prevout_height = input->metadata.height;
×
770
        return is_zero(prevout_height) && !(height > prevout_height);
×
771
    };
×
772

773
    return std::any_of(inputs_->begin(), inputs_->end(), unconfirmed);
×
774
}
775

776
bool transaction::is_confirmed_double_spend(size_t height) const NOEXCEPT
4✔
777
{
778
    BC_ASSERT(!is_coinbase());
4✔
779

780
    // Spends internal to a block are handled by block validation.
781
    const auto spent = [=](const auto& input) NOEXCEPT
3✔
782
    {
783
        return input->metadata.spent && height > input->metadata.height;
3✔
784
    };
4✔
785

786
    return std::any_of(inputs_->begin(), inputs_->end(), spent);
4✔
787
}
788

789
// Guards (for tx pool without compact blocks).
790
// ----------------------------------------------------------------------------
791

792
// Pools do not have coinbases.
793
// Redundant with block is_internal_double_spend check.
794
// Redundant with block max_block_size check.
795
code transaction::guard_check() const NOEXCEPT
×
796
{
797
    if (is_coinbase())
×
798
        return error::coinbase_transaction;
×
799
    if (is_internal_double_spend())
×
800
        return error::transaction_internal_double_spend;
×
801
    if (is_oversized())
×
802
        return error::transaction_size_limit;
×
803

804
    return error::transaction_success;
×
805
}
806

807
// Redundant with block max_block_weight accept.
808
code transaction::guard_check(const context& ctx) const NOEXCEPT
×
809
{
810
    const auto bip141 = ctx.is_enabled(flags::bip141_rule);
×
811

812
     if (!bip141 && is_segregated())
×
813
        return error::unexpected_witness_transaction;
×
814
     if (bip141 && is_overweight())
×
815
        return error::transaction_weight_limit;
×
816

817
    return error::transaction_success;
×
818
}
819

820
// Redundant with block max_block_sigops accept.
821
code transaction::guard_accept(const context& ctx) const NOEXCEPT
×
822
{
823
    const auto bip16 = ctx.is_enabled(flags::bip16_rule);
×
824
    const auto bip141 = ctx.is_enabled(flags::bip141_rule);
×
825

826
    if (is_missing_prevouts())
×
827
        return error::missing_previous_output;
×
828
    if (is_signature_operations_limited(bip16, bip141))
×
829
        return error::transaction_sigop_limit;
×
830

831
    return error::transaction_success;
×
832
}
833

834
// Validation.
835
// ----------------------------------------------------------------------------
836

837
// DO invoke on coinbase.
838
code transaction::check() const NOEXCEPT
5✔
839
{
840
    const auto coinbase = is_coinbase();
5✔
841

842
    if (is_empty())
5✔
843
        return error::empty_transaction;
×
844
    if (coinbase && is_invalid_coinbase_size())
5✔
845
        return error::invalid_coinbase_script_size;
×
846
    if (!coinbase && is_null_non_coinbase())
5✔
847
        return error::previous_output_null;
×
848

849
    return error::transaction_success;
5✔
850
}
851

852
// forks
853
// height
854
// timestamp
855
// median_time_past
856

857
// DO invoke on coinbase.
858
code transaction::check(const context& ctx) const NOEXCEPT
×
859
{
860
    const auto bip113 = ctx.is_enabled(bip113_rule);
×
861

862
    if (is_absolute_locked(ctx.height, ctx.timestamp, ctx.median_time_past, bip113))
×
863
        return error::absolute_time_locked;
×
864

865
    return error::transaction_success;
×
866
}
867

868
// Do not need to invoke on coinbase.
869
// This assumes that prevout caching is completed on all inputs.
870
code transaction::accept(const context&) const NOEXCEPT
×
871
{
872
    ////BC_ASSERT(!is_coinbase());
873

874
    if (is_coinbase())
×
875
        return error::transaction_success;
×
876
    if (is_missing_prevouts())
×
877
        return error::missing_previous_output;
×
878
    if (is_overspent())
×
879
        return error::spend_exceeds_value;
×
880

881
    return error::transaction_success;
×
882
}
883

884
// forks
885
// height
886
// median_time_past
887

888
// Do not need to invoke on coinbase.
889
// Node performs these checks through database query.
890
// This assumes that prevout and metadata caching are completed on all inputs.
891
code transaction::confirm(const context& ctx) const NOEXCEPT
×
892
{
893
    ////BC_ASSERT(!is_coinbase());
894
    const auto bip68 = ctx.is_enabled(bip68_rule);
×
895

896
    if (is_coinbase())
×
897
        return error::transaction_success;
×
898
    if (bip68 && is_relative_locked(ctx.height, ctx.median_time_past))
×
899
        return error::relative_time_locked;
×
900
    if (is_immature(ctx.height))
×
901
        return error::coinbase_maturity;
×
902
    if (is_unconfirmed_spend(ctx.height))
×
903
        return error::unconfirmed_spend;
×
904
    if (is_confirmed_double_spend(ctx.height))
×
905
        return error::confirmed_double_spend;
×
906

907
    return error::transaction_success;
×
908
}
909

910
// Delegated.
911
// ----------------------------------------------------------------------------
912

913
code transaction::connect_input(const context& ctx,
4✔
914
    const input_iterator& it) const NOEXCEPT
915
{
916
    using namespace machine;
4✔
917

918
    // TODO: evaluate performance tradeoff.
919
    if ((*it)->is_roller())
4✔
920
    {
921
        // Evaluate rolling scripts with linear search but constant erase.
922
        return interpreter<linked_stack>::connect(ctx, *this, it);
×
923
    }
924

925
    // Evaluate non-rolling scripts with constant search but linear erase.
926
    return interpreter<contiguous_stack>::connect(ctx, *this, it);
4✔
927
}
928

929
// Connect (contextual).
930
// ----------------------------------------------------------------------------
931
// TODO: accumulate sigops from each connect result and add coinbase.
932
// TODO: return in override with out parameter. more impactful with segwit.
933

934
// forks
935

936
code transaction::connect(const context& ctx) const NOEXCEPT
2✔
937
{
938
    ////BC_ASSERT(!is_coinbase());
939

940
    if (is_coinbase())
2✔
941
        return error::transaction_success;
×
942

943
    for (auto in = inputs_->begin(); in != inputs_->end(); ++in)
6✔
944
        if (const auto ec = connect_input(ctx, in))
4✔
945
            return ec;
×
946

947
    return error::transaction_success;
2✔
948
}
949

950
BC_POP_WARNING()
951

952
// JSON value convertors.
953
// ----------------------------------------------------------------------------
954

955
DEFINE_JSON_TO_TAG(transaction)
2✔
956
{
957
    return
2✔
958
    {
959
        value.at("version").to_number<uint32_t>(),
2✔
960
        value_to<inputs>(value.at("inputs")),
2✔
961
        value_to<outputs>(value.at("outputs")),
4✔
962
        value.at("locktime").to_number<uint32_t>()
4✔
963
    };
6✔
964
}
965

966
DEFINE_JSON_FROM_TAG(transaction)
4✔
967
{
968
    value =
12✔
969
    {
970
        { "version", instance.version() },
971
        { "inputs", value_from(*instance.inputs_ptr()) },
4✔
972
        { "outputs", value_from(*instance.outputs_ptr()) },
8✔
973
        { "locktime", instance.locktime() }
974
    };
4✔
975
}
4✔
976

NEW
977
DEFINE_JSON_TO_TAG(transaction::cptr)
×
978
{
NEW
979
    return to_shared(tag_invoke(to_tag<transaction>{}, value));
×
980
}
981

982
DEFINE_JSON_FROM_TAG(transaction::cptr)
2✔
983
{
984
    tag_invoke(from_tag{}, value, *instance);
2✔
985
}
2✔
986

987
} // namespace chain
988
} // namespace system
989
} // 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