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

libbitcoin / libbitcoin-system / 9950156475

16 Jul 2024 03:16AM UTC coverage: 83.203% (+0.3%) from 82.874%
9950156475

push

github

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

Optimizing deserializations.

205 of 222 new or added lines in 12 files covered. (92.34%)

14 existing lines in 8 files now uncovered.

10090 of 12127 relevant lines covered (83.2%)

4761709.16 hits per line

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

52.86
/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 <iterator>
23
#include <memory>
24
#include <numeric>
25
#include <set>
26
#include <type_traits>
27
#include <unordered_map>
28
#include <utility>
29
#include <bitcoin/system/chain/context.hpp>
30
#include <bitcoin/system/chain/enums/flags.hpp>
31
#include <bitcoin/system/chain/enums/magic_numbers.hpp>
32
#include <bitcoin/system/chain/enums/opcode.hpp>
33
#include <bitcoin/system/chain/point.hpp>
34
#include <bitcoin/system/chain/script.hpp>
35
#include <bitcoin/system/data/data.hpp>
36
#include <bitcoin/system/define.hpp>
37
#include <bitcoin/system/error/error.hpp>
38
#include <bitcoin/system/hash/hash.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
block::block() NOEXCEPT
63✔
52
  : block(to_shared<chain::header>(), to_shared<chain::transaction_cptrs>(),
63✔
53
      false)
189✔
54
{
55
}
63✔
56

57
block::block(chain::header&& header, chain::transactions&& txs) NOEXCEPT
13✔
58
  : block(to_shared(std::move(header)), to_shareds(std::move(txs)), true)
39✔
59
{
60
}
13✔
61

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

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

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

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

UNCOV
85
block::block(stream::in::fast& stream, bool witness) NOEXCEPT
×
UNCOV
86
  : block(read::bytes::fast(stream), witness)
×
87
{
UNCOV
88
}
×
89

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

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

100
block::block(reader&& source, bool witness) NOEXCEPT
76✔
101
  : block(source, witness/*from_data(source, witness)*/)
76✔
102
{
UNCOV
103
}
×
104

105
// Initializing here prevents default initialization for header_/txs_, which
106
// would be redundant in light of later in-place initialization. This can be
107
// avoided altogether by not default-initializing, and moving to assign_data.
108
block::block(reader& source, bool witness) NOEXCEPT
82✔
109
////: block(from_data(source, witness))
110
  : header_(
82✔
111
        source.get_allocator().new_object<chain::header>(source),
82✔
112
        source.get_allocator().deleter<chain::header>(source.get_arena())),
82✔
113
    txs_(
82✔
114
        source.get_allocator().new_object<transaction_cptrs>(),
82✔
115
        source.get_allocator().deleter<transaction_cptrs>(source.get_arena()))
164✔
116
{
117
    assign_data(source, witness);
82✔
118
}
82✔
119

120
// protected
121
block::block(const chain::header::cptr& header,
106✔
122
    const chain::transactions_cptr& txs, bool valid) NOEXCEPT
106✔
123
  : header_(header),
124
    txs_(txs),
125
    valid_(valid),
106✔
126
    size_(serialized_size(*txs))
212✔
127
{
128
}
106✔
129

130
// Operators.
131
// ----------------------------------------------------------------------------
132

133
bool block::operator==(const block& other) const NOEXCEPT
29✔
134
{
135
    return (header_ == other.header_ || *header_ == *other.header_)
29✔
136
        && deep_equal(*txs_, *other.txs_);
37✔
137
}
138

139
bool block::operator!=(const block& other) const NOEXCEPT
5✔
140
{
141
    return !(*this == other);
5✔
142
}
143

144
// Deserialization.
145
// ----------------------------------------------------------------------------
146

147
////// static/private
148
////block block::from_data(reader& source, bool witness) NOEXCEPT
149
////{
150
////    const auto read_transactions = [witness](reader& source) NOEXCEPT
151
////    {
152
////        // Allocate arena ctxs shared_ptr and std_vector(captures arena).
153
////        auto ctxs = to_allocated<transaction_cptrs>(source.get_arena());
154
////
155
////        BC_PUSH_WARNING(NO_UNGUARDED_POINTERS)
156
////        auto txs = to_non_const_raw_ptr(ctxs);
157
////        BC_POP_WARNING()
158
////
159
////        // Allocate txs capacity(uses arena).
160
////        const auto capacity = source.read_size(max_block_size);
161
////        txs->reserve(capacity);
162
////
163
////        // Allocate each shared_ptr<tx> and move ptr to reservation.
164
////        // Each tx is constructed in place as allocated by/with its pointer.
165
////        for (size_t tx = 0; tx < capacity; ++tx)
166
////            txs->push_back(to_allocated<transaction>(source.get_arena(),
167
////                source, witness));
168
////
169
////        return ctxs;
170
////    };
171
////
172
////    // These two pointers are discarded on assignment to allocated block.
173
////    return
174
////    {
175
////        // Allocate header shared_ptr with header struct.
176
////        to_allocated<chain::header>(source.get_arena(), source),
177
////        read_transactions(source),
178
////        source
179
////    };
180
////}
181

182
// private
183
BC_PUSH_WARNING(NO_UNGUARDED_POINTERS)
184
void block::assign_data(reader& source, bool witness) NOEXCEPT
82✔
185
{
186
    auto& allocator = source.get_allocator();
82✔
187

188
    ////allocator.construct<chain::header::cptr>(&header_,
189
    ////    allocator.new_object<chain::header>(source),
190
    ////    allocator.deleter<chain::header>(source.get_arena()));
191
    ////
192
    ////allocator.construct<transactions_cptr>(&txs_,
193
    ////    allocator.new_object<transaction_cptrs>(),
194
    ////    allocator.deleter<transaction_cptrs>(source.get_arena()));
195

196
    const auto count = source.read_size(max_block_size);
82✔
197
    auto txs = to_non_const_raw_ptr(txs_);
82✔
198
    txs->reserve(count);
82✔
199

200
    for (size_t tx = 0; tx < count; ++tx)
212✔
201
        txs->emplace_back(
260✔
202
            allocator.new_object<transaction>(source, witness),
130✔
203
            allocator.deleter<transaction>(source.get_arena()));
260✔
204

205
    size_ = serialized_size(*txs_);
82✔
206
    valid_ = source;
82✔
207
}
82✔
208
BC_POP_WARNING()
209

210
// Serialization.
211
// ----------------------------------------------------------------------------
212

213
data_chunk block::to_data(bool witness) const NOEXCEPT
20✔
214
{
215
    data_chunk data(serialized_size(witness));
40✔
216
    stream::out::copy ostream(data);
20✔
217
    to_data(ostream, witness);
20✔
218
    return data;
40✔
219
}
20✔
220

221
void block::to_data(std::ostream& stream, bool witness) const NOEXCEPT
21✔
222
{
223
    write::bytes::ostream out(stream);
21✔
224
    to_data(out, witness);
21✔
225
}
21✔
226

227
void block::to_data(writer& sink, bool witness) const NOEXCEPT
22✔
228
{
229
    header_->to_data(sink);
22✔
230
    sink.write_variable(txs_->size());
22✔
231

232
    for (const auto& tx: *txs_)
49✔
233
        tx->to_data(sink, witness);
27✔
234
}
22✔
235

236
// Properties.
237
// ----------------------------------------------------------------------------
238

239
bool block::is_valid() const NOEXCEPT
35✔
240
{
241
    return valid_;
35✔
242
}
243

244
size_t block::transactions() const NOEXCEPT
×
245
{
246
    return txs_->size();
×
247
}
248

249
const chain::header& block::header() const NOEXCEPT
12✔
250
{
251
    return *header_;
2✔
252
}
253

254
const chain::header::cptr block::header_ptr() const NOEXCEPT
×
255
{
256
    return header_;
×
257
}
258

259
// Roll up inputs for concurrent prevout processing.
260
const inputs_cptr block::inputs_ptr() const NOEXCEPT
×
261
{
262
    const auto inputs = std::make_shared<input_cptrs>();
×
263
    const auto append_ins = [&inputs](const auto& tx) NOEXCEPT
×
264
    {
265
        const auto& tx_ins = *tx->inputs_ptr();
×
266
        inputs->insert(inputs->end(), tx_ins.begin(), tx_ins.end());
×
267
    };
×
268

269
    std::for_each(txs_->begin(), txs_->end(), append_ins);
×
270
    return inputs;
×
271
}
272

273
// vector<transaction> is not exposed (because we don't have it).
274
// This would require a from_shared(txs_) conversion (expensive).
275
const transactions_cptr& block::transactions_ptr() const NOEXCEPT
85✔
276
{
277
    return txs_;
85✔
278
}
279

280
hashes block::transaction_hashes(bool witness) const NOEXCEPT
14✔
281
{
282
    const auto count = txs_->size();
14✔
283
    const auto size = is_odd(count) && count > one ? add1(count) : count;
14✔
284
    hashes out(size);
14✔
285

286
    // Extra allocation for odd count optimizes for merkle root.
287
    // Vector capacity is never reduced when resizing to smaller size.
288
    out.resize(count);
14✔
289

290
    const auto hash = [witness](const auto& tx) NOEXCEPT
19✔
291
    {
292
        return tx->hash(witness);
19✔
293
    };
14✔
294

295
    std::transform(txs_->begin(), txs_->end(), out.begin(), hash);
14✔
296
    return out;
14✔
297
}
298

299
// computed
300
hash_digest block::hash() const NOEXCEPT
38✔
301
{
302
    return header_->hash();
38✔
303
}
304

305
// computed
306
const hash_digest& block::get_hash() const NOEXCEPT
×
307
{
308
    return header_->get_hash();
×
309
}
310

311
// static/private
312
block::sizes block::serialized_size(
188✔
313
    const chain::transaction_cptrs& txs) NOEXCEPT
314
{
315
    sizes size{};
188✔
316
    std::for_each(txs.begin(), txs.end(), [&](const auto& tx) NOEXCEPT
449✔
317
    {
318
        size.nominal = ceilinged_add(size.nominal, tx->serialized_size(false));
522✔
319
        size.witnessed = ceilinged_add(size.witnessed, tx->serialized_size(true));
261✔
320
    });
261✔
321

322
    const auto common_size = ceilinged_add(
188✔
323
        header::serialized_size(),
324
        variable_size(txs.size()));
325

326
    const auto nominal_size = ceilinged_add(
188✔
327
        common_size,
328
        size.nominal);
329

330
    const auto witnessed_size = ceilinged_add(
188✔
331
        common_size,
332
        size.witnessed);
333

334
    return { nominal_size, witnessed_size };
188✔
335
}
336

337
size_t block::serialized_size(bool witness) const NOEXCEPT
24✔
338
{
339
    return witness ? size_.witnessed : size_.nominal;
21✔
340
}
341

342
// Connect.
343
// ----------------------------------------------------------------------------
344

345
bool block::is_empty() const NOEXCEPT
2✔
346
{
347
    return txs_->empty();
2✔
348
}
349

350
bool block::is_oversized() const NOEXCEPT
3✔
351
{
352
    return serialized_size(false) > max_block_size;
3✔
353
}
354

355
bool block::is_first_non_coinbase() const NOEXCEPT
3✔
356
{
357
    return !txs_->empty() && !txs_->front()->is_coinbase();
3✔
358
}
359

360
// True if there is another coinbase other than the first tx.
361
// No txs or coinbases returns false.
362
bool block::is_extra_coinbases() const NOEXCEPT
3✔
363
{
364
    if (txs_->empty())
3✔
365
        return false;
366

367
    const auto value = [](const auto& tx) NOEXCEPT
2✔
368
    {
369
        return tx->is_coinbase();
2✔
370
    };
371

372
    return std::any_of(std::next(txs_->begin()), txs_->end(), value);
3✔
373
}
374

375
//*****************************************************************************
376
// CONSENSUS: This is only necessary because satoshi stores and queries as it
377
// validates, imposing an otherwise unnecessary partial transaction ordering.
378
//*****************************************************************************
379
bool block::is_forward_reference() const NOEXCEPT
8✔
380
{
381
    if (txs_->empty())
8✔
382
        return false;
383

384
    const auto sum_txs = sub1(txs_->size());
7✔
385
    unordered_set_of_constant_referenced_hashes hashes{ sum_txs };
7✔
386
    const auto spent = [&hashes](const input::cptr& input) NOEXCEPT
11✔
387
    {
388
        return hashes.find(std::ref(input->point().hash())) != hashes.end();
4✔
389
    };
7✔
390

391
    const auto spend = [&spent, &hashes](const auto& tx) NOEXCEPT
7✔
392
    {
393
        const auto& ins = *tx->inputs_ptr();
7✔
394
        const auto forward = std::any_of(ins.begin(), ins.end(), spent);
7✔
395
        hashes.emplace(tx->get_hash(false));
7✔
396
        return forward;
7✔
397
    };
7✔
398

399
    return std::any_of(txs_->rbegin(), std::prev(txs_->rend()), spend);
7✔
400
}
401

402
// This also precludes the block merkle calculation DoS exploit by preventing
403
// duplicate txs, as a duplicate non-empty tx implies a duplicate point.
404
// bitcointalk.org/?topic=102395
405
bool block::is_internal_double_spend() const NOEXCEPT
6✔
406
{
407
    if (txs_->empty())
6✔
408
        return false;
409

410
    // Overflow returns max_size_t.
411
    const auto sum_ins = [](size_t total, const auto& tx) NOEXCEPT
11✔
412
    {
413
        return ceilinged_add(total, tx->inputs());
11✔
414
    };
415

416
    const auto tx1 = std::next(txs_->begin());
5✔
417
    const auto spends_count = std::accumulate(tx1, txs_->end(), zero, sum_ins);
5✔
418
    unordered_set_of_constant_referenced_points points{ spends_count };
5✔
419
    const auto spent = [&points](const input::cptr& in) NOEXCEPT
14✔
420
    {
421
        return !points.emplace(in->point()).second;
9✔
422
    };
5✔
423

424
    const auto double_spent = [&spent](const auto& tx) NOEXCEPT
9✔
425
    {
426
        const auto& ins = *tx->inputs_ptr();
9✔
427
        return std::any_of(ins.begin(), ins.end(), spent);
9✔
428
    };
5✔
429

430
    return std::any_of(tx1, txs_->end(), double_spent);
5✔
431
}
432

433
// private
434
hash_digest block::generate_merkle_root(bool witness) const NOEXCEPT
14✔
435
{
436
    return sha256::merkle_root(transaction_hashes(witness));
14✔
437
}
438

439
bool block::is_invalid_merkle_root() const NOEXCEPT
14✔
440
{
441
    return generate_merkle_root(false) != header_->merkle_root();
14✔
442
}
443

444
// Accept (contextual).
445
// ----------------------------------------------------------------------------
446

447
size_t block::weight() const NOEXCEPT
×
448
{
449
    // Block weight is 3 * nominal size * + 1 * witness size (bip141).
450
    return ceilinged_add(
×
451
        ceilinged_multiply(base_size_contribution, serialized_size(false)),
452
        ceilinged_multiply(total_size_contribution, serialized_size(true)));
×
453
}
454

455
bool block::is_overweight() const NOEXCEPT
×
456
{
457
    return weight() > max_block_weight;
×
458
}
459

460
bool block::is_invalid_coinbase_script(size_t height) const NOEXCEPT
×
461
{
462
    if (txs_->empty() || txs_->front()->inputs_ptr()->empty())
×
463
        return false;
×
464

465
    const auto& script = txs_->front()->inputs_ptr()->front()->script();
×
466
    return !script::is_coinbase_pattern(script.ops(), height);
×
467
}
468

469
// TODO: add bip50 to chain_state with timestamp range activation.
470
// "Special short-term limits to avoid 10,000 BDB lock limit.
471
// Count of unique txids <= 4500 to prevent 10000 BDB lock exhaustion.
472
// header.timestamp > 1363039171 && header.timestamp < 1368576000."
473
bool block::is_hash_limit_exceeded() const NOEXCEPT
×
474
{
475
    if (txs_->empty())
×
476
        return false;
477

478
    // A set is used to collapse duplicates.
479
    unordered_set_of_constant_referenced_hashes hashes{};
×
480

481
    // Just the coinbase tx hash, skip its null input hashes.
482
    hashes.emplace(txs_->front()->get_hash(false));
×
483

484
    for (auto tx = std::next(txs_->begin()); tx != txs_->end(); ++tx)
×
485
    {
486
        // Insert the transaction hash.
487
        hashes.emplace((*tx)->get_hash(false));
×
488
        const auto& inputs = *(*tx)->inputs_ptr();
×
489

490
        // Insert all input point hashes.
491
        for (const auto& input: inputs)
×
492
            hashes.emplace(input->point().hash());
×
493
    }
494

495
    return hashes.size() > hash_limit;
×
496
}
497

498
// Malleability does not imply malleated.
499
bool block::is_malleable() const NOEXCEPT
3✔
500
{
501
    return is_malleable64() || is_malleable32();
3✔
502
}
503

504
bool block::is_malleated() const NOEXCEPT
×
505
{
506
    return is_malleated64() || is_malleated32();
×
507
}
508

509
// Malleability does not imply malleated.
510
bool block::is_malleable32() const NOEXCEPT
12✔
511
{
512
    const auto unmalleated = txs_->size();
12✔
513
    for (auto mally = one; mally <= unmalleated; mally *= two)
23✔
514
        if (is_malleable32(unmalleated, mally))
17✔
515
            return true;
516

517
    return false;
518
}
519

520
// Malleated32 implies malleable and invalid due to internal tx hash pairing.
521
bool block::is_malleated32() const NOEXCEPT
11✔
522
{
523
    return !is_zero(malleated32_size());
11✔
524
}
525

526
// protected
527
// The size of an actual malleation of this block, or zero.
528
size_t block::malleated32_size() const NOEXCEPT
11✔
529
{
530
    const auto malleated = txs_->size();
11✔
531
    for (auto mally = one; mally <= to_half(malleated); mally *= two)
23✔
532
        if (is_malleable32(malleated - mally, mally) && is_malleated32(mally))
14✔
533
            return mally;
2✔
534

535
    return zero;
536
}
537

538
// protected
539
// True if the last width set of tx hashes repeats.
540
bool block::is_malleated32(size_t width) const NOEXCEPT
7✔
541
{
542
    const auto malleated = txs_->size();
7✔
543
    if (is_zero(width) || width > to_half(malleated))
7✔
544
        return false;
545

546
    auto mally = txs_->rbegin();
6✔
547
    auto legit = std::next(mally, width);
6✔
548
    while (!is_zero(width--))
9✔
549
        if ((*mally++)->hash(false) != (*legit++)->hash(false))
7✔
550
            return false;
551

552
    return true;
553
}
554

555
// Malleability does not imply malleated.
556
bool block::is_malleable64() const NOEXCEPT
12✔
557
{
558
    return is_malleable64(*txs_);
12✔
559
}
560

561
// static
562
// If all non-witness tx serializations are 64 bytes the id is malleable.
563
bool block::is_malleable64(const transaction_cptrs& txs) NOEXCEPT
12✔
564
{
565
    const auto two_leaves = [](const auto& tx) NOEXCEPT
15✔
566
    {
567
        return tx->serialized_size(false) == two * hash_size;
15✔
568
    };
569

570
    return !txs.empty() && std::all_of(txs.begin(), txs.end(), two_leaves);
12✔
571
}
572

573
// Malleated64 implies malleable64 and invalid due to non-null coinbase point.
574
// It is considered computationally infeasible to produce malleable64 with a
575
// valid (null) coinbase input point.
576
bool block::is_malleated64() const NOEXCEPT
×
577
{
578
    return !txs_->empty() && !txs_->front()->is_coinbase() &&
×
579
        is_malleable64(*txs_);
×
580
}
581

582
bool block::is_segregated() const NOEXCEPT
2✔
583
{
584
    const auto segregated = [](const auto& tx) NOEXCEPT
4✔
585
    {
586
        return tx->is_segregated();
4✔
587
    };
588

589
    return std::any_of(txs_->begin(), txs_->end(), segregated);
2✔
590
}
591

592
// The witness merkle root is obtained from wtxids, subject to malleation just
593
// as the txs commitment. However, since tx duplicates are precluded by the
594
// malleable32 (or complete) block check, there is no opportunity for this.
595
// Similarly the witness commitment cannot be malleable64.
596
bool block::is_invalid_witness_commitment() const NOEXCEPT
×
597
{
598
    if (txs_->empty())
×
599
        return false;
600

601
    const auto& coinbase = *txs_->front();
×
602
    if (coinbase.inputs_ptr()->empty())
×
603
        return false;
604

605
    // If there is a valid commitment, return false (valid).
606
    // Coinbase input witness must be 32 byte witness reserved value (bip141).
607
    // Last output of commitment pattern holds the committed value (bip141).
608
    hash_digest reserved{}, committed{};
×
609
    if (coinbase.inputs_ptr()->front()->reserved_hash(reserved))
×
610
        for (const auto& output: views_reverse(*coinbase.outputs_ptr()))
×
611
            if (output->committed_hash(committed))
×
612
                if (committed == sha256::double_hash(
×
613
                    generate_merkle_root(true), reserved))
×
614
                    return false;
615
    
616
    // If no valid commitment, return true (invalid) if segregated.
617
    // If no block tx has witness data the commitment is optional (bip141).
618
    return is_segregated();
×
619
}
620

621
//*****************************************************************************
622
// CONSENSUS:
623
// bip42 compensates for C++ undefined behavior of a right shift of a number of
624
// bits greater or equal to the shifted integer width. Yet being undefined, the
625
// result of this operation may vary by compiler. The shift_right call below
626
// explicitly implements presumed pre-bip42 behavior (shift overflow modulo) by
627
// default, and specified bip42 behavior (shift overflow to zero) with bip42.
628
//*****************************************************************************
629
static uint64_t block_subsidy(size_t height, uint64_t subsidy_interval,
×
630
    uint64_t initial_block_subsidy_satoshi, bool bip42) NOEXCEPT
631
{
632
    // Guard: quotient domain cannot increase with positive integer divisor.
633
    const auto halves = possible_narrow_cast<size_t>(height / subsidy_interval);
×
634
    return shift_right(initial_block_subsidy_satoshi, halves, bip42);
×
635
}
636

637
// Prevouts required.
638

639
uint64_t block::fees() const NOEXCEPT
×
640
{
641
    // Overflow returns max_uint64.
642
    const auto value = [](uint64_t total, const auto& tx) NOEXCEPT
×
643
    {
644
        return ceilinged_add(total, tx->fee());
×
645
    };
646

647
    return std::accumulate(txs_->begin(), txs_->end(), uint64_t{0}, value);
×
648
}
649

650
uint64_t block::claim() const NOEXCEPT
×
651
{
652
    return txs_->empty() ? zero : txs_->front()->value();
×
653
}
654

655
uint64_t block::reward(size_t height, uint64_t subsidy_interval,
×
656
    uint64_t initial_block_subsidy_satoshi, bool bip42) const NOEXCEPT
657
{
658
    // Overflow returns max_uint64.
659
    return ceilinged_add(fees(), block_subsidy(height, subsidy_interval,
×
660
        initial_block_subsidy_satoshi, bip42));
×
661
}
662

663
bool block::is_overspent(size_t height, uint64_t subsidy_interval,
×
664
    uint64_t initial_block_subsidy_satoshi, bool bip42) const NOEXCEPT
665
{
666
    return claim() > reward(height, subsidy_interval,
×
667
        initial_block_subsidy_satoshi, bip42);
×
668
}
669

670
size_t block::signature_operations(bool bip16, bool bip141) const NOEXCEPT
×
671
{
672
    // Overflow returns max_size_t.
673
    const auto value = [=](size_t total, const auto& tx) NOEXCEPT
×
674
    {
675
        return ceilinged_add(total, tx->signature_operations(bip16, bip141));
×
676
    };
×
677

678
    return std::accumulate(txs_->begin(), txs_->end(), zero, value);
×
679
}
680

681
bool block::is_signature_operations_limited(bool bip16,
×
682
    bool bip141) const NOEXCEPT
683
{
684
    const auto limit = bip141 ? max_fast_sigops : max_block_sigops;
×
685
    return signature_operations(bip16, bip141) > limit;
×
686
}
687

688
//*****************************************************************************
689
// CONSENSUS:
690
// This check is excluded under two bip30 exception blocks and bip30_deactivate
691
// until bip30_reactivate. These conditions are rolled up into the bip30 flag.
692
//*****************************************************************************
693
bool block::is_unspent_coinbase_collision() const NOEXCEPT
×
694
{
695
    if (txs_->empty() || txs_->front()->inputs_ptr()->empty())
×
696
        return false;
×
697

698
    // May only commit duplicate coinbase that is already confirmed spent.
699
    // Metadata population defaults coinbase to spent (not a collision).
700
    return !txs_->front()->inputs_ptr()->front()->metadata.spent;
×
701
}
702

703
// Search is not ordered, forward references are caught by block.check.
704
void block::populate() const NOEXCEPT
×
705
{
706
    std::unordered_map<point, output::cptr> points{};
×
707
    uint32_t index{};
×
708

709
    // Populate outputs hash table.
710
    for (auto tx = txs_->begin(); tx != txs_->end(); ++tx, index = 0)
×
711
        for (const auto& out: *(*tx)->outputs_ptr())
×
712
            points.emplace(std::pair{ point{ (*tx)->hash(false), index++ },
×
713
                out });
714

715
    // Populate input prevouts from hash table.
716
    for (auto tx = txs_->begin(); tx != txs_->end(); ++tx)
×
717
    {
718
        for (const auto& in: *(*tx)->inputs_ptr())
×
719
        {
720
            const auto point = points.find(in->point());
×
721
            if (point != points.end())
×
722
                in->prevout = point->second;
×
723
        }
724
    }
725
}
×
726

727
// Delegated.
728
// ----------------------------------------------------------------------------
729

730
// DO invoke on coinbase.
731
code block::check_transactions() const NOEXCEPT
3✔
732
{
733
    for (const auto& tx: *txs_)
8✔
734
        if (const auto ec = tx->check())
5✔
735
            return ec;
×
736

737
    return error::block_success;
3✔
738
}
739

740
// DO invoke on coinbase.
741
code block::check_transactions(const context& ctx) const NOEXCEPT
×
742
{
743
    for (const auto& tx: *txs_)
×
744
        if (const auto ec = tx->check(ctx))
×
745
            return ec;
×
746

747
    return error::block_success;
×
748
}
749

750
// Do NOT invoke on coinbase.
751
code block::accept_transactions(const context& ctx) const NOEXCEPT
×
752
{
753
    if (!is_empty())
×
754
        for (auto tx = std::next(txs_->begin()); tx != txs_->end(); ++tx)
×
755
            if (const auto ec = (*tx)->accept(ctx))
×
756
                return ec;
×
757

758
    return error::block_success;
×
759
}
760

761
// Do NOT invoke on coinbase.
762
code block::connect_transactions(const context& ctx) const NOEXCEPT
×
763
{
764
    if (!is_empty())
×
765
        for (auto tx = std::next(txs_->begin()); tx != txs_->end(); ++tx)
×
766
            if (const auto ec = (*tx)->connect(ctx))
×
767
                return ec;
×
768

769
    return error::block_success;
×
770
}
771

772
// Do NOT invoke on coinbase.
773
code block::confirm_transactions(const context& ctx) const NOEXCEPT
×
774
{
775
    if (!is_empty())
×
776
        for (auto tx = std::next(txs_->begin()); tx != txs_->end(); ++tx)
×
777
            if (const auto ec = (*tx)->confirm(ctx))
×
778
                return ec;
×
779

780
    return error::block_success;
×
781
}
782

783
// Identity.
784
// ----------------------------------------------------------------------------
785
// invalid_transaction_commitment, invalid_witness_commitment, block_malleated
786
// codes specifically indicate lack of block hash tx identification (identity).
787

788
code block::identify() const NOEXCEPT
×
789
{
790
    // type64 malleated is a subset of first_not_coinbase.
791
    // type32 malleated is a subset of is_internal_double_spend.
792
    if (is_malleated())
×
793
        return error::block_malleated;
×
794
    if (is_invalid_merkle_root())
×
795
        return error::invalid_transaction_commitment;
×
796

797
    return error::block_success;
×
798
}
799

800
code block::identify(const context& ctx) const NOEXCEPT
×
801
{
802
    const auto bip141 = ctx.is_enabled(bip141_rule);
×
803

804
    if (bip141 && is_invalid_witness_commitment())
×
805
        return error::invalid_witness_commitment;
×
806

807
    return error::block_success;
×
808
}
809

810
// Validation.
811
// ----------------------------------------------------------------------------
812
// In the case of validation failure
813
// The block header is checked/accepted independently.
814

815
// TODO: use of get_hash() in is_forward_reference makes this thread unsafe.
816
code block::check() const NOEXCEPT
3✔
817
{
818
    // empty_block is subset of first_not_coinbase.
819
    //if (is_empty())
820
    //    return error::empty_block;
821
    if (is_oversized())
3✔
822
        return error::block_size_limit;
×
823
    if (is_first_non_coinbase())
3✔
824
        return error::first_not_coinbase;
×
825
    if (is_extra_coinbases())
3✔
826
        return error::extra_coinbases;
×
827
    if (is_forward_reference())
3✔
828
        return error::forward_reference;
×
829
    if (is_internal_double_spend())
3✔
830
        return error::block_internal_double_spend;
×
831
    if (is_invalid_merkle_root())
3✔
832
        return error::invalid_transaction_commitment;
×
833

834
    return check_transactions();
3✔
835
}
836

837
// forks
838
// height
839
// timestamp
840
// median_time_past
841

842
// TODO: use of get_hash() in is_hash_limit_exceeded makes this thread unsafe.
843
code block::check(const context& ctx) const NOEXCEPT
×
844
{
845
    const auto bip141 = ctx.is_enabled(bip141_rule);
×
846
    const auto bip34 = ctx.is_enabled(bip34_rule);
×
847
    const auto bip50 = ctx.is_enabled(bip50_rule);
×
848

849
    if (bip141 && is_overweight())
×
850
        return error::block_weight_limit;
×
851
    if (bip34 && is_invalid_coinbase_script(ctx.height))
×
852
        return error::coinbase_height_mismatch;
×
853
    if (bip50 && is_hash_limit_exceeded())
×
854
        return error::temporary_hash_limit;
×
855
    if (bip141 && is_invalid_witness_commitment())
×
856
        return error::invalid_witness_commitment;
×
857

858
    return check_transactions(ctx);
×
859
}
860

861
// forks
862
// height
863

864
// This assumes that prevout caching is completed on all inputs.
865
code block::accept(const context& ctx, size_t subsidy_interval,
×
866
    uint64_t initial_subsidy) const NOEXCEPT
867
{
868
    const auto bip16 = ctx.is_enabled(bip16_rule);
×
869
    const auto bip42 = ctx.is_enabled(bip42_rule);
×
870
    const auto bip141 = ctx.is_enabled(bip141_rule);
×
871

872
    // prevouts required.
873
    if (is_overspent(ctx.height, subsidy_interval, initial_subsidy, bip42))
×
874
        return error::coinbase_value_limit;
×
875
    if (is_signature_operations_limited(bip16, bip141))
×
876
        return error::block_sigop_limit;
×
877

878
    return accept_transactions(ctx);
×
879
}
880

881
// forks
882

883
// Node performs these checks through database query.
884
// This assumes that prevout and metadata caching are completed on all inputs.
885
code block::confirm(const context& ctx) const NOEXCEPT
×
886
{
887
    const auto bip30 = ctx.is_enabled(bip30_rule);
×
888

889
    if (bip30 && is_unspent_coinbase_collision())
×
890
        return error::unspent_coinbase_collision;
×
891

892
    return confirm_transactions(ctx);
×
893
}
894

895
// forks
896

897
code block::connect(const context& ctx) const NOEXCEPT
×
898
{
899
    return connect_transactions(ctx);
×
900
}
901

902
BC_POP_WARNING()
903

904
// JSON value convertors.
905
// ----------------------------------------------------------------------------
906

907
namespace json = boost::json;
908

909
// boost/json will soon have NOEXCEPT: github.com/boostorg/json/pull/636
910
BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)
911

912
block tag_invoke(json::value_to_tag<block>,
1✔
913
    const json::value& value) NOEXCEPT
914
{
915
    return
1✔
916
    {
917
        json::value_to<header>(value.at("header")),
1✔
918
        json::value_to<chain::transactions>(value.at("transactions"))
2✔
919
    };
1✔
920
}
921

922
void tag_invoke(json::value_from_tag, json::value& value,
2✔
923
    const block& block) NOEXCEPT
924
{
925
    value =
2✔
926
    {
927
        { "header", block.header() },
928
        { "transactions", *block.transactions_ptr() },
929
    };
2✔
930
}
2✔
931

932
BC_POP_WARNING()
933

934
block::cptr tag_invoke(json::value_to_tag<block::cptr>,
×
935
    const json::value& value) NOEXCEPT
936
{
937
    return to_shared(tag_invoke(json::value_to_tag<block>{}, value));
×
938
}
939

940
// Shared pointer overload is required for navigation.
941
BC_PUSH_WARNING(SMART_PTR_NOT_NEEDED)
942
BC_PUSH_WARNING(NO_VALUE_OR_CONST_REF_SHARED_PTR)
943

944
void tag_invoke(json::value_from_tag tag, json::value& value,
×
945
    const block::cptr& block) NOEXCEPT
946
{
947
    tag_invoke(tag, value, *block);
×
948
}
×
949

950
BC_POP_WARNING()
951
BC_POP_WARNING()
952

953
} // namespace chain
954
} // namespace system
955
} // 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