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

libbitcoin / libbitcoin-system / 9310800761

31 May 2024 12:08AM UTC coverage: 82.732% (-0.01%) from 82.746%
9310800761

push

github

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

Performance optimizations, style, comments.

233 of 289 new or added lines in 11 files covered. (80.62%)

8 existing lines in 4 files now uncovered.

9812 of 11860 relevant lines covered (82.73%)

4808594.09 hits per line

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

47.38
/src/chain/block.cpp
1
/**
2
 * Copyright (c) 2011-2023 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/block.hpp>
20

21
#include <algorithm>
22
#include <functional>
23
#include <iterator>
24
#include <memory>
25
#include <numeric>
26
#include <set>
27
#include <type_traits>
28
#include <unordered_map>
29
#include <utility>
30
#include <bitcoin/system/chain/context.hpp>
31
#include <bitcoin/system/chain/enums/flags.hpp>
32
#include <bitcoin/system/chain/enums/magic_numbers.hpp>
33
#include <bitcoin/system/chain/enums/opcode.hpp>
34
#include <bitcoin/system/chain/point.hpp>
35
#include <bitcoin/system/chain/script.hpp>
36
#include <bitcoin/system/data/data.hpp>
37
#include <bitcoin/system/define.hpp>
38
#include <bitcoin/system/error/error.hpp>
39
#include <bitcoin/system/hash/hash.hpp>
40
#include <bitcoin/system/math/math.hpp>
41
#include <bitcoin/system/stream/stream.hpp>
42

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

47
BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)
48

49
// Constructors.
50
// ----------------------------------------------------------------------------
51

52
block::block() NOEXCEPT
59✔
53
  : block(to_shared<chain::header>(), to_shared<chain::transaction_cptrs>(),
59✔
54
      false)
177✔
55
{
56
}
59✔
57

58
block::block(chain::header&& header, chain::transactions&& txs) NOEXCEPT
11✔
59
  : block(to_shared(std::move(header)), to_shareds(std::move(txs)), true)
33✔
60
{
61
}
11✔
62

63
block::block(const chain::header& header,
30✔
64
    const chain::transactions& txs) NOEXCEPT
30✔
65
  : block(to_shared<chain::header>(header), to_shareds(txs), true)
90✔
66
{
67
}
30✔
68

69
block::block(const chain::header::cptr& header,
×
70
    const chain::transactions_cptr& txs) NOEXCEPT
×
71
  : block(header ? header : to_shared<chain::header>(),
×
72
      txs ? txs : to_shared<transaction_cptrs>(), true)
×
73
{
74
}
×
75

76
block::block(const data_slice& data, bool witness) NOEXCEPT
67✔
77
  : block(stream::in::copy(data), witness)
67✔
78
{
79
}
67✔
80

81
////block::block(stream::in::fast&& stream, bool witness) NOEXCEPT
82
////  : block(read::bytes::fast(stream), witness)
83
////{
84
////}
85

86
block::block(stream::in::fast& stream, bool witness) NOEXCEPT
1✔
87
  : block(read::bytes::fast(stream), witness)
1✔
88
{
89
}
1✔
90

91
block::block(std::istream&& stream, bool witness) NOEXCEPT
67✔
92
  : block(read::bytes::istream(stream), witness)
67✔
93
{
94
}
67✔
95

96
block::block(std::istream& stream, bool witness) NOEXCEPT
3✔
97
  : block(read::bytes::istream(stream), witness)
3✔
98
{
99
}
3✔
100

101
block::block(reader&& source, bool witness) NOEXCEPT
71✔
102
  : block(from_data(source, witness))
71✔
103
{
104
}
71✔
105

106
block::block(reader& source, bool witness) NOEXCEPT
1✔
107
  : block(from_data(source, witness))
1✔
108
{
109
}
1✔
110

111
// protected
112
block::block(const chain::header::cptr& header,
172✔
113
    const chain::transactions_cptr& txs, bool valid) NOEXCEPT
172✔
114
  : header_(header), txs_(txs), valid_(valid)
172✔
115
{
116
}
172✔
117

118
// Operators.
119
// ----------------------------------------------------------------------------
120

121
bool block::operator==(const block& other) const NOEXCEPT
28✔
122
{
123
    return (header_ == other.header_ || *header_ == *other.header_)
28✔
124
        && deep_equal(*txs_, *other.txs_);
35✔
125
}
126

127
bool block::operator!=(const block& other) const NOEXCEPT
5✔
128
{
129
    return !(*this == other);
5✔
130
}
131

132
// Deserialization.
133
// ----------------------------------------------------------------------------
134

135
// static/private
136
block block::from_data(reader& source, bool witness) NOEXCEPT
72✔
137
{
138
    const auto read_transactions = [witness](reader& source) NOEXCEPT
261✔
139
    {
140
        auto txs = to_shared<transaction_cptrs>();
72✔
141
        const auto capacity = source.read_size(max_block_size);
72✔
142
        txs->reserve(capacity);
72✔
143

144
        for (size_t tx = 0; tx < capacity; ++tx)
189✔
145
        {
146
            BC_PUSH_WARNING(NO_NEW_OR_DELETE)
147
            txs->emplace_back(new transaction{ source, witness });
117✔
148
            BC_POP_WARNING()
149
        }
150

151
        // This is a pointer copy (non-const to const).
152
        return txs;
72✔
153
    };
72✔
154

155
    return
72✔
156
    {
157
        to_shared<chain::header>(source),
72✔
158
        read_transactions(source),
144✔
159
        source
160
    };
144✔
161
}
162

163
// Serialization.
164
// ----------------------------------------------------------------------------
165

166
data_chunk block::to_data(bool witness) const NOEXCEPT
18✔
167
{
168
    data_chunk data(serialized_size(witness));
18✔
169
    stream::out::copy ostream(data);
18✔
170
    to_data(ostream, witness);
18✔
171
    return data;
36✔
172
}
18✔
173

174
void block::to_data(std::ostream& stream, bool witness) const NOEXCEPT
19✔
175
{
176
    write::bytes::ostream out(stream);
19✔
177
    to_data(out, witness);
19✔
178
}
19✔
179

180
void block::to_data(writer& sink, bool witness) const NOEXCEPT
20✔
181
{
182
    header_->to_data(sink);
20✔
183
    sink.write_variable(txs_->size());
20✔
184

185
    for (const auto& tx: *txs_)
46✔
186
        tx->to_data(sink, witness);
26✔
187
}
20✔
188

189
// Properties.
190
// ----------------------------------------------------------------------------
191

192
bool block::is_valid() const NOEXCEPT
32✔
193
{
194
    return valid_;
32✔
195
}
196

197
size_t block::transactions() const NOEXCEPT
×
198
{
199
    return txs_->size();
×
200
}
201

202
const chain::header& block::header() const NOEXCEPT
12✔
203
{
204
    return *header_;
2✔
205
}
206

207
const chain::header::cptr block::header_ptr() const NOEXCEPT
×
208
{
209
    return header_;
×
210
}
211

212
// Roll up inputs for concurrent prevout processing.
213
const inputs_cptr block::inputs_ptr() const NOEXCEPT
×
214
{
UNCOV
215
    const auto inputs = std::make_shared<input_cptrs>();
×
NEW
216
    const auto append_ins = [&inputs](const transaction::cptr& tx) NOEXCEPT
×
217
    {
218
        const auto& tx_ins = *tx->inputs_ptr();
×
219
        inputs->insert(inputs->end(), tx_ins.begin(), tx_ins.end());
×
220
    };
×
221

NEW
222
    std::for_each(txs_->begin(), txs_->end(), append_ins);
×
223
    return inputs;
×
224
}
225

226
// vector<transaction> is not exposed (because we don't have it).
227
// This would require a from_shared(txs_) conversion (expensive).
228
const transactions_cptr& block::transactions_ptr() const NOEXCEPT
85✔
229
{
230
    return txs_;
85✔
231
}
232

233
hashes block::transaction_hashes(bool witness) const NOEXCEPT
11✔
234
{
235
    const auto count = txs_->size();
11✔
236
    const auto size = is_odd(count) && count > one ? add1(count) : count;
11✔
237
    hashes out(size);
11✔
238

239
    // Extra allocation for odd count optimizes for merkle root.
240
    // Vector capacity is never reduced when resizing to smaller size.
241
    out.resize(count);
11✔
242

243
    const auto hash = [witness](const transaction::cptr& tx) NOEXCEPT
25✔
244
    {
245
        return tx->hash(witness);
14✔
246
    };
11✔
247

248
    std::transform(txs_->begin(), txs_->end(), out.begin(), hash);
11✔
249
    return out;
11✔
250
}
251

252
// computed
253
hash_digest block::hash() const NOEXCEPT
34✔
254
{
255
    return header_->hash();
34✔
256
}
257

258
// TODO: this is expensive.
259
size_t block::serialized_size(bool witness) const NOEXCEPT
19✔
260
{
261
    // Overflow returns max_size_t.
262
    const auto sum = [=](size_t total, const transaction::cptr& tx) NOEXCEPT
42✔
263
    {
264
        return ceilinged_add(total, tx->serialized_size(witness));
23✔
265
    };
19✔
266

267
    return header::serialized_size()
19✔
268
        + variable_size(txs_->size())
19✔
269
        + std::accumulate(txs_->begin(), txs_->end(), zero, sum);
19✔
270
}
271

272
// Connect.
273
// ----------------------------------------------------------------------------
274

275
bool block::is_empty() const NOEXCEPT
2✔
276
{
277
    return txs_->empty();
2✔
278
}
279

280
bool block::is_oversized() const NOEXCEPT
×
281
{
282
    return serialized_size(false) > max_block_size;
×
283
}
284

285
bool block::is_first_non_coinbase() const NOEXCEPT
×
286
{
287
    return !txs_->empty() && !txs_->front()->is_coinbase();
×
288
}
289

290
// True if there is another coinbase other than the first tx.
291
// No txs or coinbases returns false.
292
bool block::is_extra_coinbases() const NOEXCEPT
×
293
{
294
    if (txs_->empty())
×
295
        return false;
296

297
    const auto value = [](const transaction::cptr& tx) NOEXCEPT
×
298
    {
299
        return tx->is_coinbase();
×
300
    };
301

302
    return std::any_of(std::next(txs_->begin()), txs_->end(), value);
×
303
}
304

305
//*****************************************************************************
306
// CONSENSUS: This is only necessary because satoshi stores and queries as it
307
// validates, imposing an otherwise unnecessary partial transaction ordering.
308
//*****************************************************************************
309
bool block::is_forward_reference() const NOEXCEPT
5✔
310
{
311
    if (txs_->empty())
5✔
312
        return false;
313

314
    const auto sum_txs = sub1(txs_->size());
4✔
315
    unordered_set_of_constant_referenced_hashes hashes{ sum_txs };
4✔
316
    const auto spent = [&hashes](const input::cptr& input) NOEXCEPT
6✔
317
    {
318
        return hashes.find(std::ref(input->point().hash())) != hashes.end();
2✔
319
    };
4✔
320

321
    const auto spend = [&spent, &hashes](const transaction::cptr& tx) NOEXCEPT
19✔
322
    {
323
        const auto& ins = *tx->inputs_ptr();
5✔
324
        const auto forward = std::any_of(ins.begin(), ins.end(), spent);
5✔
325
        hashes.emplace(tx->get_hash(false));
5✔
326
        return forward;
5✔
327
    };
4✔
328

329
    return std::any_of(txs_->rbegin(), std::prev(txs_->rend()), spend);
4✔
330
}
331

332
// This also precludes the block merkle calculation DoS exploit by preventing
333
// duplicate txs, as a duplicate non-empty tx implies a duplicate point.
334
// bitcointalk.org/?topic=102395
335
bool block::is_internal_double_spend() const NOEXCEPT
3✔
336
{
337
    if (txs_->empty())
3✔
338
        return false;
339

340
    // Overflow returns max_size_t.
341
    const auto sum_ins = [](size_t total, const transaction::cptr& tx) NOEXCEPT
11✔
342
    {
343
        return ceilinged_add(total, tx->inputs());
9✔
344
    };
345

346
    const auto tx1 = std::next(txs_->begin());
2✔
347
    const auto spends_count = std::accumulate(tx1, txs_->end(), zero, sum_ins);
2✔
348
    unordered_set_of_constant_referenced_points points{ spends_count };
2✔
349
    const auto spent = [&points](const input::cptr& in) NOEXCEPT
9✔
350
    {
351
        return !points.emplace(in->point()).second;
7✔
352
    };
2✔
353

354
    const auto double_spent = [&spent](const transaction::cptr& tx) NOEXCEPT
16✔
355
    {
356
        const auto& ins = *tx->inputs_ptr();
7✔
357
        return std::any_of(ins.begin(), ins.end(), spent);
7✔
358
    };
2✔
359

360
    return std::any_of(tx1, txs_->end(), double_spent);
2✔
361
}
362

363
// private
364
hash_digest block::generate_merkle_root(bool witness) const NOEXCEPT
11✔
365
{
366
    return sha256::merkle_root(transaction_hashes(witness));
11✔
367
}
368

369
bool block::is_invalid_merkle_root() const NOEXCEPT
11✔
370
{
371
    return generate_merkle_root(false) != header_->merkle_root();
11✔
372
}
373

374
// Accept (contextual).
375
// ----------------------------------------------------------------------------
376

377
size_t block::weight() const NOEXCEPT
×
378
{
379
    // Block weight is 3 * nominal size * + 1 * witness size (bip141).
380
    return base_size_contribution * serialized_size(false) +
×
381
        total_size_contribution * serialized_size(true);
×
382
}
383

384
bool block::is_overweight() const NOEXCEPT
×
385
{
386
    return weight() > max_block_weight;
×
387
}
388

389
bool block::is_invalid_coinbase_script(size_t height) const NOEXCEPT
×
390
{
391
    if (txs_->empty() || txs_->front()->inputs_ptr()->empty())
×
392
        return false;
×
393

394
    const auto& script = txs_->front()->inputs_ptr()->front()->script();
×
395
    return !script::is_coinbase_pattern(script.ops(), height);
×
396
}
397

398
// TODO: add bip50 to chain_state with timestamp range activation.
399
// "Special short-term limits to avoid 10,000 BDB lock limit.
400
// Count of unique txids <= 4500 to prevent 10000 BDB lock exhaustion.
401
// header.timestamp > 1363039171 && header.timestamp < 1368576000."
402
bool block::is_hash_limit_exceeded() const NOEXCEPT
×
403
{
404
    if (txs_->empty())
×
405
        return false;
406

407
    // A set is used to collapse duplicates.
NEW
408
    unordered_set_of_constant_referenced_hashes hashes;
×
409

410
    // Just the coinbase tx hash, skip its null input hashes.
NEW
411
    hashes.emplace(txs_->front()->get_hash(false));
×
412

413
    for (auto tx = std::next(txs_->begin()); tx != txs_->end(); ++tx)
×
414
    {
415
        // Insert the transaction hash.
NEW
416
        hashes.emplace((*tx)->get_hash(false));
×
417
        const auto& inputs = *(*tx)->inputs_ptr();
×
418

419
        // Insert all input point hashes.
420
        for (const auto& input: inputs)
×
NEW
421
            hashes.emplace(input->point().hash());
×
422
    }
423

424
    return hashes.size() > hash_limit;
×
425
}
426

427
bool block::is_malleable() const NOEXCEPT
3✔
428
{
429
    return is_malleable64() || is_malleable32();
3✔
430
}
431

432
bool block::is_malleable32() const NOEXCEPT
12✔
433
{
434
    const auto unmalleated = txs_->size();
12✔
435
    for (auto mally = one; mally <= unmalleated; mally *= two)
23✔
436
        if (is_malleable32(unmalleated, mally))
17✔
437
            return true;
438

439
    return false;
440
}
441

442
bool block::is_malleated32() const NOEXCEPT
11✔
443
{
444
    return !is_zero(malleated32_size());
11✔
445
}
446

447
// protected
448
// The size of an actual malleation of this block, or zero.
449
size_t block::malleated32_size() const NOEXCEPT
11✔
450
{
451
    const auto malleated = txs_->size();
11✔
452
    for (auto mally = one; mally <= to_half(malleated); mally *= two)
23✔
453
        if (is_malleable32(malleated - mally, mally) &&
20✔
454
            is_malleated32(mally))
6✔
455
            return mally;
2✔
456

457
    return zero;
458
}
459

460
// protected
461
// True if the last width set of tx hashes repeats.
462
bool block::is_malleated32(size_t width) const NOEXCEPT
7✔
463
{
464
    const auto malleated = txs_->size();
7✔
465
    if (is_zero(width) || width > to_half(malleated))
7✔
466
        return false;
467

468
    auto mally = txs_->rbegin();
6✔
469
    auto legit = std::next(mally, width);
6✔
470
    while (!is_zero(width--))
9✔
471
        if ((*mally++)->hash(false) != (*legit++)->hash(false))
7✔
472
            return false;
473

474
    return true;
475
}
476

477
bool block::is_malleable64() const NOEXCEPT
12✔
478
{
479
    return is_malleable64(*txs_);
12✔
480
}
481

482
// static
483
// If all non-witness tx serializations are 64 bytes the id is malleable.
484
// This form of malleability does not imply current block instance is invalid.
485
bool block::is_malleable64(const transaction_cptrs& txs) NOEXCEPT
12✔
486
{
487
    const auto two_leaves = [](const transaction::cptr& tx) NOEXCEPT
27✔
488
    {
489
        return tx->serialized_size(false) == two * hash_size;
15✔
490
    };
491

492
    return !txs.empty() && std::all_of(txs.begin(), txs.end(), two_leaves);
12✔
493
}
494

495
bool block::is_segregated() const NOEXCEPT
×
496
{
497
    const auto segregated = [](const transaction::cptr& tx) NOEXCEPT
×
498
    {
499
        return tx->is_segregated();
×
500
    };
501

502
    return std::any_of(txs_->begin(), txs_->end(), segregated);
×
503
}
504

505
bool block::is_invalid_witness_commitment() const NOEXCEPT
×
506
{
507
    if (txs_->empty())
×
508
        return false;
509

510
    const auto& coinbase = *txs_->front();
×
511
    if (coinbase.inputs_ptr()->empty())
×
512
        return false;
513

514
    // If there is a valid commitment, return false (valid).
515
    // Last output of commitment pattern holds committed value (bip141).
516
    hash_digest reserved{}, committed{};
×
517
    if (coinbase.inputs_ptr()->front()->reserved_hash(reserved))
×
518
        for (const auto& output: views_reverse(*coinbase.outputs_ptr()))
×
519
            if (output->committed_hash(committed))
×
520
                if (committed == sha256::double_hash(
×
521
                    generate_merkle_root(true), reserved))
×
522
                    return false;
523
    
524
    // If no valid commitment, return true (invalid) if segregated.
525
    // If no block tx has witness data the commitment is optional (bip141).
526
    return is_segregated();
×
527
}
528

529
//*****************************************************************************
530
// CONSENSUS:
531
// bip42 compensates for C++ undefined behavior of a right shift of a number of
532
// bits greater or equal to the shifted integer width. Yet being undefined, the
533
// result of this operation may vary by compiler. The shift_right call below
534
// explicitly implements presumed pre-bip42 behavior (shift overflow modulo) by
535
// default, and specified bip42 behavior (shift overflow to zero) with bip42.
536
//*****************************************************************************
537
static uint64_t block_subsidy(size_t height, uint64_t subsidy_interval,
×
538
    uint64_t initial_block_subsidy_satoshi, bool bip42) NOEXCEPT
539
{
540
    // Guard: quotient domain cannot increase with positive integer divisor.
541
    const auto halves = possible_narrow_cast<size_t>(height / subsidy_interval);
×
542
    return shift_right(initial_block_subsidy_satoshi, halves, bip42);
×
543
}
544

545
// Prevouts required.
546

547
uint64_t block::fees() const NOEXCEPT
×
548
{
549
    // Overflow returns max_uint64.
550
    const auto value = [](uint64_t total, const transaction::cptr& tx) NOEXCEPT
×
551
    {
552
        return ceilinged_add(total, tx->fee());
×
553
    };
554

555
    return std::accumulate(txs_->begin(), txs_->end(), uint64_t{0}, value);
×
556
}
557

558
uint64_t block::claim() const NOEXCEPT
×
559
{
560
    return txs_->empty() ? zero : txs_->front()->value();
×
561
}
562

563
uint64_t block::reward(size_t height, uint64_t subsidy_interval,
×
564
    uint64_t initial_block_subsidy_satoshi, bool bip42) const NOEXCEPT
565
{
566
    // Overflow returns max_uint64.
567
    return ceilinged_add(fees(), block_subsidy(height, subsidy_interval,
×
568
        initial_block_subsidy_satoshi, bip42));
×
569
}
570

571
bool block::is_overspent(size_t height, uint64_t subsidy_interval,
×
572
    uint64_t initial_block_subsidy_satoshi, bool bip42) const NOEXCEPT
573
{
574
    return claim() > reward(height, subsidy_interval,
×
575
        initial_block_subsidy_satoshi, bip42);
×
576
}
577

578
size_t block::signature_operations(bool bip16, bool bip141) const NOEXCEPT
×
579
{
580
    // Overflow returns max_size_t.
581
    const auto value = [=](size_t total, const transaction::cptr& tx) NOEXCEPT
×
582
    {
583
        return ceilinged_add(total, tx->signature_operations(bip16, bip141));
×
584
    };
×
585

586
    return std::accumulate(txs_->begin(), txs_->end(), zero, value);
×
587
}
588

589
bool block::is_signature_operations_limited(bool bip16,
×
590
    bool bip141) const NOEXCEPT
591
{
592
    const auto limit = bip141 ? max_fast_sigops : max_block_sigops;
×
593
    return signature_operations(bip16, bip141) > limit;
×
594
}
595

596
//*****************************************************************************
597
// CONSENSUS:
598
// This check is excluded under two bip30 exception blocks and bip30_deactivate
599
// until bip30_reactivate. These conditions are rolled up into the bip30 flag.
600
//*****************************************************************************
601
bool block::is_unspent_coinbase_collision() const NOEXCEPT
×
602
{
603
    if (txs_->empty() || txs_->front()->inputs_ptr()->empty())
×
604
        return false;
×
605

606
    // May only commit duplicate coinbase that is already confirmed spent.
607
    // Metadata population defaults coinbase to spent (not a collision).
608
    return !txs_->front()->inputs_ptr()->front()->metadata.spent;
×
609
}
610

611
// Search is not ordered, forward references are caught by block.check.
612
void block::populate() const NOEXCEPT
×
613
{
NEW
614
    unordered_map_of_constant_referenced_points points{};
×
615
    uint32_t index{};
×
616

617
    // Populate outputs hash table.
618
    for (auto tx = txs_->begin(); tx != txs_->end(); ++tx, index = 0)
×
619
        for (const auto& out: *(*tx)->outputs_ptr())
×
NEW
620
            points.emplace(std::pair{ point{ (*tx)->get_hash(false),
×
621
                index++ }, out });
622

623
    // Populate input prevouts from hash table.
624
    for (auto tx = txs_->begin(); tx != txs_->end(); ++tx)
×
625
    {
626
        for (const auto& in: *(*tx)->inputs_ptr())
×
627
        {
NEW
628
            const auto point = points.find(std::cref(in->point()));
×
629
            if (point != points.end())
×
630
                in->prevout = point->second;
×
631
        }
632
    }
UNCOV
633
}
×
634

635
// Delegated.
636
// ----------------------------------------------------------------------------
637

638
// DO invoke on coinbase.
639
code block::check_transactions() const NOEXCEPT
×
640
{
641
    code ec;
×
642
    
643
    for (const auto& tx: *txs_)
×
644
        if ((ec = tx->check()))
×
645
            return ec;
×
646

647
    return error::block_success;
×
648
}
649

650
// DO invoke on coinbase.
651
code block::check_transactions(const context& ctx) const NOEXCEPT
×
652
{
653
    code ec;
×
654
    
655
    for (const auto& tx: *txs_)
×
656
        if ((ec = tx->check(ctx)))
×
657
            return ec;
×
658

659
    return error::block_success;
×
660
}
661

662
// Do NOT invoke on coinbase.
663
code block::accept_transactions(const context& ctx) const NOEXCEPT
×
664
{
665
    code ec;
×
666

667
    if (!is_empty())
×
668
        for (auto tx = std::next(txs_->begin()); tx != txs_->end(); ++tx)
×
669
            if ((ec = (*tx)->accept(ctx)))
×
670
                return ec;
×
671

672
    return error::block_success;
×
673
}
674

675
// Do NOT invoke on coinbase.
676
code block::connect_transactions(const context& ctx) const NOEXCEPT
×
677
{
678
    code ec;
×
679

680
    if (!is_empty())
×
681
        for (auto tx = std::next(txs_->begin()); tx != txs_->end(); ++tx)
×
682
            if ((ec = (*tx)->connect(ctx)))
×
683
                return ec;
×
684

685
    return error::block_success;
×
686
}
687

688
// Do NOT invoke on coinbase.
689
code block::confirm_transactions(const context& ctx) const NOEXCEPT
×
690
{
691
    code ec;
×
692

693
    if (!is_empty())
×
694
        for (auto tx = std::next(txs_->begin()); tx != txs_->end(); ++tx)
×
695
            if ((ec = (*tx)->confirm(ctx)))
×
696
                return ec;
×
697

698
    return error::block_success;
×
699
}
700

701
// Validation.
702
// ----------------------------------------------------------------------------
703
// The block header is checked/accepted independently.
704

705
code block::check() const NOEXCEPT
×
706
{
707
    // context free.
708
    // empty_block is redundant with first_not_coinbase.
709
    //if (is_empty())
710
    //    return error::empty_block;
711
    if (is_oversized())
×
712
        return error::block_size_limit;
×
713
    if (is_first_non_coinbase())
×
714
        return error::first_not_coinbase;
×
715
    if (is_extra_coinbases())
×
716
        return error::extra_coinbases;
×
717
    if (is_forward_reference())
×
718
        return error::forward_reference;
×
719
    if (is_internal_double_spend())
×
720
        return error::block_internal_double_spend;
×
721
    if (is_invalid_merkle_root())
×
722
        return error::merkle_mismatch;
×
723

724
    return check_transactions();
×
725
}
726

727
// forks
728
// height
729
// timestamp
730
// median_time_past
731

732
code block::check(const context& ctx) const NOEXCEPT
×
733
{
734
    const auto bip34 = ctx.is_enabled(bip34_rule);
×
735
    const auto bip50 = ctx.is_enabled(bip50_rule);
×
736
    const auto bip141 = ctx.is_enabled(bip141_rule);
×
737

738
    // context required.
739
    if (bip141 && is_overweight())
×
740
        return error::block_weight_limit;
×
741
    if (bip34 && is_invalid_coinbase_script(ctx.height))
×
742
        return error::coinbase_height_mismatch;
×
743
    if (bip50 && is_hash_limit_exceeded())
×
744
        return error::temporary_hash_limit;
×
745
    if (bip141 && is_invalid_witness_commitment())
×
746
        return error::invalid_witness_commitment;
×
747

748
    return check_transactions(ctx);
×
749
}
750

751
// forks
752
// height
753

754
// This assumes that prevout caching is completed on all inputs.
755
code block::accept(const context& ctx, size_t subsidy_interval,
×
756
    uint64_t initial_subsidy) const NOEXCEPT
757
{
758
    const auto bip16 = ctx.is_enabled(bip16_rule);
×
759
    const auto bip42 = ctx.is_enabled(bip42_rule);
×
760
    const auto bip141 = ctx.is_enabled(bip141_rule);
×
761

762
    // prevouts required.
763
    if (is_overspent(ctx.height, subsidy_interval, initial_subsidy, bip42))
×
764
        return error::coinbase_value_limit;
×
765
    if (is_signature_operations_limited(bip16, bip141))
×
766
        return error::block_sigop_limit;
×
767

768
    return accept_transactions(ctx);
×
769
}
770

771
// forks
772

773
// Node performs these checks through database query.
774
// This assumes that prevout and metadata caching are completed on all inputs.
775
code block::confirm(const context& ctx) const NOEXCEPT
×
776
{
777
    const auto bip30 = ctx.is_enabled(bip30_rule);
×
778

779
    if (bip30 && is_unspent_coinbase_collision())
×
780
        return error::unspent_coinbase_collision;
×
781

782
    return confirm_transactions(ctx);
×
783
}
784

785
// forks
786

787
code block::connect(const context& ctx) const NOEXCEPT
×
788
{
789
    return connect_transactions(ctx);
×
790
}
791

792
BC_POP_WARNING()
793

794
// JSON value convertors.
795
// ----------------------------------------------------------------------------
796

797
namespace json = boost::json;
798

799
// boost/json will soon have NOEXCEPT: github.com/boostorg/json/pull/636
800
BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)
801

802
block tag_invoke(json::value_to_tag<block>,
1✔
803
    const json::value& value) NOEXCEPT
804
{
805
    return
1✔
806
    {
807
        json::value_to<header>(value.at("header")),
1✔
808
        json::value_to<chain::transactions>(value.at("transactions"))
2✔
809
    };
1✔
810
}
811

812
void tag_invoke(json::value_from_tag, json::value& value,
2✔
813
    const block& block) NOEXCEPT
814
{
815
    value =
2✔
816
    {
817
        { "header", block.header() },
818
        { "transactions", *block.transactions_ptr() },
819
    };
2✔
820
}
2✔
821

822
BC_POP_WARNING()
823

824
block::cptr tag_invoke(json::value_to_tag<block::cptr>,
×
825
    const json::value& value) NOEXCEPT
826
{
827
    return to_shared(tag_invoke(json::value_to_tag<block>{}, value));
×
828
}
829

830
// Shared pointer overload is required for navigation.
831
BC_PUSH_WARNING(SMART_PTR_NOT_NEEDED)
832
BC_PUSH_WARNING(NO_VALUE_OR_CONST_REF_SHARED_PTR)
833

834
void tag_invoke(json::value_from_tag tag, json::value& value,
×
835
    const block::cptr& block) NOEXCEPT
836
{
837
    tag_invoke(tag, value, *block);
×
838
}
×
839

840
BC_POP_WARNING()
841
BC_POP_WARNING()
842

843
} // namespace chain
844
} // namespace system
845
} // 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

© 2025 Coveralls, Inc