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

libbitcoin / libbitcoin-system / 8057926070

27 Feb 2024 01:00AM UTC coverage: 82.614% (-0.02%) from 82.629%
8057926070

Pull #1411

github

web-flow
Merge 24b08470c into e8296511c
Pull Request #1411: Add settings, checkpoint.equals, uint256_t serialize, chain_state.cumulative_work.

19 of 31 new or added lines in 4 files covered. (61.29%)

2 existing lines in 1 file now uncovered.

9641 of 11670 relevant lines covered (82.61%)

4887990.42 hits per line

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

12.36
/src/chain/chain_state.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/chain_state.hpp>
20

21
#include <algorithm>
22
#include <chrono>
23
#include <iterator>
24
#include <bitcoin/system/chain/block.hpp>
25
#include <bitcoin/system/chain/chain_state.hpp>
26
#include <bitcoin/system/chain/checkpoint.hpp>
27
#include <bitcoin/system/chain/compact.hpp>
28
#include <bitcoin/system/chain/context.hpp>
29
#include <bitcoin/system/chain/enums/forks.hpp>
30
#include <bitcoin/system/chain/enums/policy.hpp>
31
#include <bitcoin/system/chain/script.hpp>
32
#include <bitcoin/system/data/data.hpp>
33
#include <bitcoin/system/hash/hash.hpp>
34
#include <bitcoin/system/math/math.hpp>
35
#include <bitcoin/system/settings.hpp>
36

37
namespace libbitcoin {
38
namespace system {
39
namespace chain {
40

41
// github.com/bitcoin/bips/blob/master/bip-0030.mediawiki#specification
42
// As bip30 exceptions apply only to bitcoin mainnet these can be embedded.
43
static const checkpoint mainnet_bip30_exception_checkpoint1
44
{
45
    "00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec", 91842
46
};
47
static const checkpoint mainnet_bip30_exception_checkpoint2
48
{
49
    "00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721", 91880
50
};
51

52
// Inlines.
53
// ----------------------------------------------------------------------------
54

55
constexpr bool is_active(size_t count, size_t bip34_activation_threshold) NOEXCEPT
56
{
57
    return count >= bip34_activation_threshold;
58
}
59

60
constexpr bool is_enforced(size_t count, size_t bip34_enforcement_threshold) NOEXCEPT
61
{
62
    return count >= bip34_enforcement_threshold;
63
}
64

65
// Determine the number of blocks back to the closest retarget height.
66
constexpr size_t retarget_distance(size_t height,
2✔
67
    size_t retargeting_interval) NOEXCEPT
68
{
69
    return height % retargeting_interval;
2✔
70
}
71

72
// Determine if height is a multiple of retargeting_interval.
73
constexpr bool is_retarget_height(size_t height,
2✔
74
    size_t retargeting_interval) NOEXCEPT
75
{
76
    return is_zero(retarget_distance(height, retargeting_interval));
2✔
77
}
78

79
// bip30 is active for all but two mainnet blocks that violate the rule.
80
// These two blocks each have a coinbase transaction that exactly duplicates
81
// another that is not spent by the arrival of the corresponding duplicate.
82
inline bool is_bip30_exception(const checkpoint& check, bool mainnet) NOEXCEPT
×
83
{
84
    return mainnet &&
×
85
        ((check == mainnet_bip30_exception_checkpoint1) ||
×
86
         (check == mainnet_bip30_exception_checkpoint2));
×
87
}
88

89
inline uint32_t timestamp_high(const chain_state::data& values) NOEXCEPT
2✔
90
{
91
    return values.timestamp.ordered.back();
2✔
92
}
93

94
inline uint32_t bits_high(const chain_state::data& values) NOEXCEPT
4✔
95
{
96
    return values.bits.ordered.back();
4✔
97
}
98

99
// activation
100
// ----------------------------------------------------------------------------
101

102
chain_state::activations chain_state::activation(const data& values,
×
103
    uint32_t forks, const system::settings& settings) NOEXCEPT
104
{
105
    const auto height = values.height;
×
106
    const auto version = values.version.self;
×
107
    const auto& history = values.version.ordered;
×
108
    const auto bip90 = script::is_enabled(forks, forks::bip90_rule);
×
109

110
    //*************************************************************************
111
    // CONSENSUS: Though unspecified in bip34, the satoshi implementation
112
    // performed this comparison using the signed integer version value.
113
    //*************************************************************************
114
    constexpr auto ge = [](uint32_t value, uint32_t version) NOEXCEPT
×
115
    {
116
        return sign_cast<int32_t>(value) >= sign_cast<int32_t>(version);
×
117
    };
118

119
    // Declare bip34-based version predicates.
120
    const auto ge_2 = [&](uint32_t value) NOEXCEPT { return ge(value,
×
121
        settings.bip34_version); };
×
122
    const auto ge_3 = [&](uint32_t value) NOEXCEPT { return ge(value,
×
123
        settings.bip66_version); };
×
124
    const auto ge_4 = [&](uint32_t value) NOEXCEPT { return ge(value,
×
125
        settings.bip65_version); };
×
126

127
    // Compute bip34-based activation version summaries.
128
    // TODO: avoid these computations if forks not configured.
129
    const auto count_2 = std::count_if(history.begin(), history.end(), ge_2);
×
130
    const auto count_3 = std::count_if(history.begin(), history.end(), ge_3);
×
131
    const auto count_4 = std::count_if(history.begin(), history.end(), ge_4);
×
132

133
    // Frozen activations (require version and enforce above freeze height).
134
    const auto bip90_34 = bip90 && height >= settings.bip34_freeze;
×
135
    const auto bip90_66 = bip90 && height >= settings.bip66_freeze;
×
136
    const auto bip90_65 = bip90 && height >= settings.bip65_freeze;
×
137

138
    // Initialize activation results with genesis values.
139
    activations result{ forks::no_rules, settings.first_version };
×
140

141
    // regtest is only activated via configuration (hard fork).
142
    result.forks |= (forks::retarget & forks);
×
143

144
    // testnet is activated based on configuration alone (hard fork).
145
    result.forks |= (forks::difficult & forks);
×
146

147
    // bip42 is activated based on configuration alone (soft fork).
148
    result.forks |= (forks::bip42_rule & forks);
×
149

150
    // bip90 is activated based on configuration alone (hard fork).
151
    result.forks |= (forks::bip90_rule & forks);
×
152

153
    // time_warp_patch is activated based on configuration alone (hard fork).
154
    result.forks |= (forks::time_warp_patch & forks);
×
155

156
    // retarget_overflow_patch is activated based on configuration alone (hard fork).
157
    result.forks |= (forks::retarget_overflow_patch & forks);
×
158

159
    // scrypt_proof_of_work is activated based on configuration alone (hard fork).
160
    result.forks |= (forks::scrypt_proof_of_work & forks);
×
161

162
    // bip16 was activated based on manual inspection of signal history (~55% rule).
163
    if (values.timestamp.self >= settings.bip16_activation_time)
×
164
    {
165
        result.forks |= (forks::bip16_rule & forks);
×
166
    }
167

168
    // bip34 is activated based on 75% of preceding 1000 mainnet blocks.
169
    // bip30 is disabled by bip34 or unconditional activation of it by bip90.
170
    if (bip90_34 || (is_active(count_2, settings.bip34_activation_threshold) &&
×
171
        version >= settings.bip34_version))
×
172
    {
173
        // TODO: check is_enabled(bip34_rule, forks) before above calculations.
174
        result.forks |= (forks::bip34_rule & forks);
×
175
    }
176
    else
177
    {
178
        const auto difficult = script::is_enabled(forks, forks::difficult);
×
179
        const auto retarget = script::is_enabled(forks, forks::retarget);
×
180
        const auto mainnet = retarget && difficult;
×
181

182
        // If not bip30 exception, existing duplicate coinbase must be spent.
183
        if (!is_bip30_exception({ values.hash, height }, mainnet))
×
184
        {
185
            result.forks |= (forks::bip30_rule & forks);
×
186
        }
187
    }
188

189
    // bip66 is activated based on 75% of preceding 1000 mainnet blocks.
190
    if (bip90_66 || (is_active(count_3, settings.bip34_activation_threshold) &&
×
191
        version >= settings.bip66_version))
×
192
    {
193
        // TODO: check is_enabled(bip66_rule, forks) before above calculations.
194
        result.forks |= (forks::bip66_rule & forks);
×
195
    }
196

197
    // bip65 is activated based on 75% of preceding 1000 mainnet blocks.
198
    if (bip90_65 || (is_active(count_4, settings.bip34_activation_threshold) &&
×
199
        version >= settings.bip65_version))
×
200
    {
201
        // TODO: check is_enabled(bip65_rule, forks) before above calculations.
202
        result.forks |= (forks::bip65_rule & forks);
×
203
    }
204

205
    // version 4/3/2 enforced based on 95% of preceding 1000 mainnet blocks.
206
    if (bip90_65 || is_enforced(count_4, settings.bip34_enforcement_threshold))
×
207
    {
208
        // TODO: requires is_enabled(bip65_rule, forks).
209
        result.minimum_block_version = settings.bip65_version;
×
210
    }
211
    else if (bip90_66 || is_enforced(count_3, settings.bip34_enforcement_threshold))
×
212
    {
213
        // TODO: requires is_enabled(bip66_rule, forks).
214
        result.minimum_block_version = settings.bip66_version;
×
215
    }
216
    else if (bip90_34 || is_enforced(count_2, settings.bip34_enforcement_threshold))
×
217
    {
218
        // TODO: requires is_enabled(bip34_rule, forks).
219
        result.minimum_block_version = settings.bip34_version;
×
220
    }
221
    else
222
    {
223
        result.minimum_block_version = settings.first_version;
×
224
    }
225

226
    // bip9_bit0 forks are enforced above the bip9_bit0 checkpoint.
227
    if (values.bip9_bit0_hash == settings.bip9_bit0_active_checkpoint.hash())
×
228
    {
229
        result.forks |= (forks::bip9_bit0_group & forks);
×
230
    }
231

232
    // bip9_bit1 forks are enforced above the bip9_bit1 checkpoint.
233
    if (values.bip9_bit1_hash == settings.bip9_bit1_active_checkpoint.hash())
×
234
    {
235
        result.forks |= (forks::bip9_bit1_group & forks);
×
236
    }
237

238
    return result;
×
239
}
240

241
size_t chain_state::bits_count(size_t height, uint32_t forks,
×
242
    size_t retargeting_interval) NOEXCEPT
243
{
244
    // Mainnet doesn't use bits in retargeting.
245
    if (script::is_enabled(forks, forks::difficult))
×
246
        return one;
247

248
    // Regtest bypasses all retargeting.
249
    if (!script::is_enabled(forks, forks::retarget))
×
250
        return one;
251

252
    // Testnet uses mainnet retargeting on interval.
253
    if (is_retarget_height(height, retargeting_interval))
×
254
        return one;
255

256
    // Testnet requires all bits for inter-interval retargeting.
257
    return std::min(height, retargeting_interval);
×
258
}
259

260
size_t chain_state::version_count(size_t height, uint32_t forks,
×
261
    size_t bip34_activation_sample) NOEXCEPT
262
{
263
    if (script::is_enabled(forks, forks::bip90_rule) ||
×
264
        !script::is_enabled(forks, forks::bip34_activations))
265
    {
266
        return zero;
267
    }
268

269
    return std::min(height, bip34_activation_sample);
×
270
}
271

272
size_t chain_state::timestamp_count(size_t height, uint32_t) NOEXCEPT
×
273
{
274
    return std::min(height, median_time_past_interval);
×
275
}
276

277
size_t chain_state::retarget_height(size_t height, uint32_t forks,
×
278
    size_t retargeting_interval) NOEXCEPT
279
{
280
    if (!script::is_enabled(forks, forks::retarget))
×
281
        return map::unrequested;
282

283
    // Height must be a positive multiple of interval, so underflow safe.
284
    // If not retarget height get most recent so that it may be promoted.
285
    return height - (is_retarget_height(height, retargeting_interval) ?
×
286
        retargeting_interval : retarget_distance(height, retargeting_interval));
×
287
}
288

289
// median_time_past
290
// ----------------------------------------------------------------------------
291

292
//*****************************************************************************
293
// CONSENSUS: satoshi associates the median time past for block N with block
294
// N-1, as opposed to block N. Given that the value is actually obtained from
295
// yet another preceding block in all cases except block 1 and 2, this is a
296
// curious and confusing convention. We associate the median time past for
297
// block N with block N. This is simple but requires care when comparing code.
298
//*****************************************************************************
299
uint32_t chain_state::median_time_past(const data& values, uint32_t) NOEXCEPT
×
300
{
301
    // Sort the times by value to obtain the median.
302
    auto times = sort_copy(values.timestamp.ordered);
×
303

304
    // Consensus defines median time using modulo 2 element selection.
305
    // This differs from arithmetic median which averages two middle values.
306
    BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)
307
    return times.empty() ? 0 : times.at(to_half(times.size()));
×
308
    BC_POP_WARNING()
309
}
×
310

311
// work_required
312
// ----------------------------------------------------------------------------
313

314
uint32_t chain_state::work_required(const data& values, uint32_t forks,
2✔
315
    const system::settings& settings) NOEXCEPT
316
{
317
    // Genesis has no preceding block data.
318
    if (is_zero(values.height))
2✔
319
        return 0;
320

321
    // Previous block has an invalid bits value.
322
    if (is_zero(compact::expand(bits_high(values))))
2✔
323
        return 0;
324

325
    // Regtest bypasses all retargeting.
326
    if (!script::is_enabled(forks, forks::retarget))
2✔
327
        return bits_high(values);
×
328

329
    // Mainnet and testnet retarget on interval.
330
    if (is_retarget_height(values.height, settings.retargeting_interval()))
2✔
331
        return work_required_retarget(values, forks,
6✔
332
            settings.proof_of_work_limit,
2✔
333
            settings.minimum_timespan(),
2✔
334
            settings.maximum_timespan(),
2✔
335
            settings.retargeting_interval_seconds);
4✔
336

337
    // Testnet retargets easy on inter-interval.
338
    if (!script::is_enabled(forks, forks::difficult))
×
339
        return easy_work_required(values,
×
340
            settings.retargeting_interval(),
×
341
            settings.proof_of_work_limit,
×
342
            settings.block_spacing_seconds);
×
343

344
    // Mainnet not retargeting, must exact match the previous block bits value.
345
    return bits_high(values);
×
346
}
347

348
// Get the bounded total time spanning the highest 2016 blocks.
349
uint32_t chain_state::retarget_timespan(const data& values,
2✔
350
    uint32_t minimum_timespan, uint32_t maximum_timespan) NOEXCEPT
351
{
352
    //*************************************************************************
353
    // CONSENSUS: "Subtract unsigned 32 bit numbers in signed 64 bit space".
354
    // This is done order to prevent underflow before applying the range
355
    // constraint. This is properly just a floored subtraction in 32 bit space.
356
    //*************************************************************************
357
    const auto timespan = floored_subtract(timestamp_high(values),
2✔
358
        values.timestamp.retarget);
2✔
359

360
    //*************************************************************************
361
    // CONSENSUS: Constrain the timespan to the configured consensus limits.
362
    //*************************************************************************
363
    return limit(timespan, minimum_timespan, maximum_timespan);
2✔
364
}
365

366
constexpr bool patch_timewarp(uint32_t forks, const uint256_t& limit,
2✔
367
    const uint256_t& target) NOEXCEPT
368
{
369
    return script::is_enabled(forks, forks::retarget_overflow_patch) &&
3✔
370
        floored_log2(target) >= floored_log2(limit);
1✔
371
}
372

373
uint32_t chain_state::work_required_retarget(const data& values, uint32_t forks,
2✔
374
    uint32_t proof_of_work_limit, uint32_t minimum_timespan,
375
    uint32_t maximum_timespan, uint32_t retargeting_interval_seconds) NOEXCEPT
376
{
377
    static const auto limit = compact::expand(proof_of_work_limit);
2✔
378
    auto target = compact::expand(bits_high(values));
2✔
379

380
    // Conditionally implement retarget overflow patch (e.g. Litecoin).
381
    const auto timewarp = to_int(patch_timewarp(forks, limit, target));
2✔
382

383
    target >>= timewarp;
2✔
384
    target *= retarget_timespan(values, minimum_timespan, maximum_timespan);
2✔
385
    target /= retargeting_interval_seconds;
2✔
386
    target <<= timewarp;
2✔
387

388
    // Disallow target from falling below minimum configured.
389
    // All targets are a bits value normalized by compress here.
390
    return target > limit ? proof_of_work_limit : compact::compress(target);
2✔
391
}
392

393
// A retarget height, or a block that does not have proof_of_work_limit bits.
394
constexpr bool is_retarget_or_non_limit(size_t height, uint32_t bits,
×
395
    size_t retargeting_interval, uint32_t proof_of_work_limit) NOEXCEPT
396
{
397
    // Zero is a retarget height, termination required before height underflow.
398
    // This is guaranteed, just a comment here because it may not be obvious.
399
    return bits != proof_of_work_limit ||
×
400
        is_retarget_height(height, retargeting_interval);
401
}
402

403
uint32_t chain_state::easy_work_required(const data& values,
×
404
    size_t retargeting_interval, uint32_t proof_of_work_limit,
405
    uint32_t block_spacing_seconds) NOEXCEPT
406
{
407
    BC_ASSERT(!is_zero(values.height));
×
408

409
    // Overflow allowed here since supported coins would not do so.
410
    const auto easy_spacing_seconds = shift_left(block_spacing_seconds);
×
411

412
    // If the time limit has passed allow a minimum difficulty block.
413
    if (values.timestamp.self > ceilinged_add(timestamp_high(values),
×
414
        easy_spacing_seconds))
415
        return proof_of_work_limit;
416

417
    auto height = values.height;
×
418
    const auto& bits = values.bits.ordered;
×
419

420
    // Reverse iterate the ordered-by-height list of header bits.
421
    for (auto bit: views_reverse(bits))
×
422
    {
423
        if (is_retarget_or_non_limit(--height, bit, retargeting_interval,
×
424
            proof_of_work_limit))
425
            return bit;
×
426
    }
427

428
    // Since the set of heights is either a full retarget range or ends at
429
    // zero this is not reachable unless the data set is invalid.
430
    BC_ASSERT(false);
×
431
    return proof_of_work_limit;
×
432
}
433

434
size_t chain_state::bip9_bit0_height(size_t height,
×
435
    const checkpoint& bip9_bit0_active_checkpoint) NOEXCEPT
436
{
437
    const auto activation_height = bip9_bit0_active_checkpoint.height();
×
438

439
    // Require bip9_bit0 hash at heights above historical bip9_bit0 activation.
440
    return height > activation_height ? activation_height : map::unrequested;
×
441
}
442

443
size_t chain_state::bip9_bit1_height(size_t height,
×
444
    const checkpoint& bip9_bit1_active_checkpoint) NOEXCEPT
445
{
446
    const auto activation_height = bip9_bit1_active_checkpoint.height();
×
447

448
    // Require bip9_bit1 hash at heights above historical bip9_bit1 activation.
449
    return height > activation_height ? activation_height : map::unrequested;
×
450
}
451

452
// Public static
453
// ----------------------------------------------------------------------------
454

455
chain_state::map chain_state::get_map(size_t height,
×
456
    const system::settings& settings) NOEXCEPT
457
{
458
    if (is_zero(height))
×
459
        return {};
×
460

461
    const auto forks = settings.enabled_forks();
×
462
    const auto interval = settings.retargeting_interval();
×
463
    map map{};
×
464

465
    // The height bound of the reverse (high to low) retarget search.
466
    map.bits_self = height;
×
467
    map.bits.high = sub1(height);
×
468
    map.bits.count = bits_count(height, forks, interval);
×
469

470
    // The height bound of the median time past function.
471
    map.timestamp_self = height;
×
472
    map.timestamp.high = sub1(height);
×
473
    map.timestamp.count = timestamp_count(height, forks);
×
474

475
    // The height bound of the version sample for activations.
476
    map.version_self = height;
×
477
    map.version.high = sub1(height);
×
478
    map.version.count = version_count(height, forks,
×
479
        settings.bip34_activation_sample);
×
480

481
    // The most recent past retarget height.
482
    map.timestamp_retarget = retarget_height(height, forks, interval);
×
483

484
    // The checkpoint above which bip9_bit0 rules are enforced.
485
    map.bip9_bit0_height = bip9_bit0_height(height,
×
486
        settings.bip9_bit0_active_checkpoint);
×
487

488
    // The checkpoint above which bip9_bit1 rules are enforced.
489
    map.bip9_bit1_height = bip9_bit1_height(height,
×
490
        settings.bip9_bit1_active_checkpoint);
×
491

492
    return map;
×
493
}
494

495
uint32_t chain_state::signal_version(uint32_t forks,
×
496
    const system::settings& settings) NOEXCEPT
497
{
498
    if (script::is_enabled(forks, forks::bip65_rule))
×
499
        return settings.bip65_version;
×
500

501
    if (script::is_enabled(forks, forks::bip66_rule))
×
502
        return settings.bip66_version;
×
503

504
    if (script::is_enabled(forks, forks::bip34_rule))
×
505
        return settings.bip34_version;
×
506

507
    // TODO: these can be retired.
508
    // Signal bip9 bit0 if any of the group is configured.
509
    if (script::is_enabled(forks, forks::bip9_bit0_group))
×
510
        return settings.bip9_version_base | settings.bip9_version_bit0;
×
511

512
    // TODO: these can be retired.
513
    // Signal bip9 bit1 if any of the group is configured.
514
    if (script::is_enabled(forks, forks::bip9_bit1_group))
×
515
        return settings.bip9_version_base | settings.bip9_version_bit1;
×
516

517
    return settings.first_version;
×
518
}
519

520
// Constructors.
521
// ----------------------------------------------------------------------------
522

523
// This is promotion from a preceding height to the next.
524
chain_state::data chain_state::to_pool(const chain_state& top,
×
525
    const system::settings& settings) NOEXCEPT
526
{
527
    // Alias configured forks.
528
    const auto forks = top.forks_;
×
529

530
    // Retargeting is only activated via configuration.
531
    const auto retarget = script::is_enabled(forks, forks::retarget);
×
532

533
    // Copy data from presumed previous-height block state.
534
    chain_state::data data{ top.data_ };
×
535

536
    // If this overflows height is zero and result is handled as invalid.
537
    const auto height = add1(data.height);
×
538
    
539
    // Enqueue previous block values to collections.
540
    BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)
541
    data.bits.ordered.push_back(data.bits.self);
×
542
    data.version.ordered.push_back(data.version.self);
×
543
    data.timestamp.ordered.push_back(data.timestamp.self);
×
544
    BC_POP_WARNING()
545

546
    // If bits collection overflows, dequeue oldest member.
547
    if (data.bits.ordered.size() >
×
548
        bits_count(height, forks, settings.retargeting_interval()))
×
549
        data.bits.ordered.pop_front();
×
550

551
    // If version collection overflows, dequeue oldest member.
552
    if (data.version.ordered.size() > version_count(height, forks,
×
553
        settings.bip34_activation_sample))
×
554
        data.version.ordered.pop_front();
×
555

556
    // If timestamp collection overflows, dequeue oldest member.
557
    if (data.timestamp.ordered.size() > timestamp_count(height, forks))
×
558
        data.timestamp.ordered.pop_front();
×
559

560

561
    // Regtest does not perform retargeting.
562
    // If promoting from retarget height, move that timestamp into retarget.
563
    if (retarget && is_retarget_height(sub1(height),
×
564
        settings.retargeting_interval()))
×
565
    {
566
        // Conditionally patch time warp bug (e.g. Litecoin).
567
        const auto patch = script::is_enabled(forks, forks::time_warp_patch);
×
568

569
        data.timestamp.retarget = (patch && height != one) ?
×
570
            *std::next(data.timestamp.ordered.crbegin()) : data.timestamp.self;
×
571
    }
572

573
    // Replace previous block state with tx pool chain state for next height
574
    // Preserve top block timestamp for use in computation of staleness.
575
    // Preserve data.bip9_bit0_hash promotion.
576
    // Preserve data.bip9_bit1_hash promotion.
577
    // bits.self is unused.
578
    data.height = height;
×
579
    data.hash = {};
×
580
    data.bits.self = 0;
×
581
    data.version.self = signal_version(forks, settings);
×
582
    return data;
×
583
}
584

585
// Top to pool.
586
// This generates a state for the pool above the presumed top block state.
587
// Work is not acculuated for a pool state.
588
chain_state::chain_state(const chain_state& top,
×
589
    const system::settings& settings) NOEXCEPT
×
590
  : data_(to_pool(top, settings)),
×
591
    forks_(top.forks_),
×
592
    active_(activation(data_, forks_, settings)),
×
593
    work_required_(work_required(data_, forks_, settings)),
×
NEW
594
    median_time_past_(median_time_past(data_, forks_)),
×
NEW
595
    cumulative_work_(top.cumulative_work())
×
596
{
597
}
×
598

599
chain_state::data chain_state::to_block(const chain_state& pool,
×
600
    const block& block, const system::settings& settings) NOEXCEPT
601
{
602
    // Copy data from presumed same-height pool state.
603
    chain_state::data data{ pool.data_ };
×
604

605
    // Replace pool chain state with block state at same (next) height.
606
    // Preserve data.timestamp.retarget promotion.
607
    const auto& header = block.header();
×
608
    data.hash = {};
×
609
    data.bits.self = header.bits();
×
610
    data.version.self = header.version();
×
611
    data.timestamp.self = header.timestamp();
×
612

613
    // Cache hash of bip9 bit0 height block, otherwise use preceding state.
614
    if (data.height == settings.bip9_bit0_active_checkpoint.height())
×
615
        data.bip9_bit0_hash = data.hash;
×
616

617
    // Cache hash of bip9 bit1 height block, otherwise use preceding state.
618
    if (data.height == settings.bip9_bit1_active_checkpoint.height())
×
619
        data.bip9_bit1_hash = data.hash;
×
620

621
    return data;
×
622
}
623

624
// Pool to block.
625
// This assumes that the pool state is the same height as the block.
626
chain_state::chain_state(const chain_state& pool, const block& block,
×
627
    const system::settings& settings) NOEXCEPT
×
628
  : data_(to_block(pool, block, settings)),
×
629
    forks_(pool.forks_),
×
630
    active_(activation(data_, forks_, settings)),
×
631
    work_required_(work_required(data_, forks_, settings)),
×
NEW
632
    median_time_past_(median_time_past(data_, forks_)),
×
NEW
633
    cumulative_work_(pool.cumulative_work() + block.header().proof())
×
634
{
635
}
×
636

637
chain_state::data chain_state::to_header(const chain_state& parent,
×
638
    const header& header, const system::settings& settings) NOEXCEPT
639
{
640
    BC_ASSERT(header.previous_block_hash() == parent.hash());
×
641

642
    // Copy and promote data from presumed parent-height header/block state.
643
    auto data = to_pool(parent, settings);
×
644

645
    // Replace the parent (pool or previous) block state with given state.
646
    // Preserve data.timestamp.retarget promotion.
647
    data.hash = header.hash();
×
648
    data.bits.self = header.bits();
×
649
    data.version.self = header.version();
×
650
    data.timestamp.self = header.timestamp();
×
651

652
    // Cache hash of bip9 bit0 height block, otherwise use preceding state.
653
    if (data.height == settings.bip9_bit0_active_checkpoint.height())
×
654
        data.bip9_bit0_hash = data.hash;
×
655

656
    // Cache hash of bip9 bit1 height block, otherwise use preceding state.
657
    if (data.height == settings.bip9_bit1_active_checkpoint.height())
×
658
        data.bip9_bit1_hash = data.hash;
×
659

660
    return data;
×
661
}
662

663
// Parent to header.
664
// This assumes that parent is the state of the header's previous block.
665
chain_state::chain_state(const chain_state& parent, const header& header,
×
666
    const system::settings& settings) NOEXCEPT
×
667
  : data_(to_header(parent, header, settings)),
×
668
    forks_(parent.forks_),
×
669
    active_(activation(data_, forks_, settings)),
×
670
    work_required_(work_required(data_, forks_, settings)),
×
NEW
671
    median_time_past_(median_time_past(data_, forks_)),
×
NEW
672
    cumulative_work_(parent.cumulative_work() + header.proof())
×
673
{
674
}
×
675

676
// From scratch (e.g. raw data obtained from store).
677
chain_state::chain_state(data&& values,
×
678
    const system::settings& settings) NOEXCEPT
×
679
  : data_(std::move(values)),
×
680
    forks_(settings.enabled_forks()),
×
681
    active_(activation(data_, forks_, settings)),
×
682
    work_required_(work_required(data_, forks_, settings)),
×
683
    median_time_past_(median_time_past(data_, forks_))
×
684
{
685
}
×
686

687
// Properties.
688
// ----------------------------------------------------------------------------
689

NEW
690
chain::context chain_state::context() const NOEXCEPT
×
691
{
NEW
692
    return
×
693
    {
694
        forks(),
695
        timestamp(),
696
        median_time_past(),
697
        possible_narrow_cast<uint32_t>(height()),
698
        minimum_block_version(),
699
        work_required()
NEW
700
    };
×
701
}
702

UNCOV
703
const hash_digest& chain_state::hash() const NOEXCEPT
×
704
{
705
    return data_.hash;
×
706
}
707

NEW
708
const uint256_t& chain_state::cumulative_work() const NOEXCEPT
×
709
{
NEW
710
    return cumulative_work_;
×
711
}
712

UNCOV
713
uint32_t chain_state::minimum_block_version() const NOEXCEPT
×
714
{
715
    return active_.minimum_block_version;
×
716
}
717

718
uint32_t chain_state::work_required() const NOEXCEPT
×
719
{
720
    return work_required_;
×
721
}
722

723
// context
724

725
uint32_t chain_state::timestamp() const NOEXCEPT
×
726
{
727
    return data_.timestamp.self;
×
728
}
729

730
uint32_t chain_state::median_time_past() const NOEXCEPT
×
731
{
732
    return median_time_past_;
×
733
}
734

735
uint32_t chain_state::forks() const NOEXCEPT
×
736
{
737
    return active_.forks;
×
738
}
739

740
size_t chain_state::height() const NOEXCEPT
×
741
{
742
    return data_.height;
×
743
}
744

745
} // namespace chain
746
} // namespace system
747
} // 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