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

libbitcoin / libbitcoin-system / 4571238631

pending completion
4571238631

push

github

GitHub
Merge pull request #1348 from evoskuil/master

13 of 13 new or added lines in 3 files covered. (100.0%)

9431 of 11324 relevant lines covered (83.28%)

6743188.57 hits per line

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

13.93
/src/chain/chain_state.cpp
1
/**
2
 * Copyright (c) 2011-2022 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
static const checkpoint mainnet_bip30_exception_checkpoint1
43
{
44
    "00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec", 91842
45
};
46
static const checkpoint mainnet_bip30_exception_checkpoint2
47
{
48
    "00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721", 91880
49
};
50

51
// Inlines.
52
// ----------------------------------------------------------------------------
53

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

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

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

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

78
inline bool is_bip30_exception(const checkpoint& check, bool mainnet) NOEXCEPT
79
{
80
    return mainnet &&
81
        ((check == mainnet_bip30_exception_checkpoint1) ||
82
         (check == mainnet_bip30_exception_checkpoint2));
83
}
84

85
inline uint32_t timestamp_high(const chain_state::data& values) NOEXCEPT
2✔
86
{
87
    return values.timestamp.ordered.back();
2✔
88
}
89

90
inline uint32_t bits_high(const chain_state::data& values) NOEXCEPT
4✔
91
{
92
    return values.bits.ordered.back();
8✔
93
}
94

95
// activation
96
// ----------------------------------------------------------------------------
97

98
chain_state::activations chain_state::activation(const data& values,
×
99
    uint32_t forks, const system::settings& settings) NOEXCEPT
100
{
101
    const auto height = values.height;
×
102
    const auto version = values.version.self;
×
103
    const auto& history = values.version.ordered;
×
104
    const auto frozen = script::is_enabled(forks, forks::bip90_rule);
×
105
    ////const auto difficult = script::is_enabled(forks, forks::difficult);
106
    ////const auto retarget = script::is_enabled(forks, forks::retarget);
107
    ////const auto mainnet = retarget && difficult;
108

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

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

126
    // Compute bip34-based activation version summaries.
127
    const auto count_2 = std::count_if(history.begin(), history.end(), ge_2);
×
128
    const auto count_3 = std::count_if(history.begin(), history.end(), ge_3);
×
129
    const auto count_4 = std::count_if(history.begin(), history.end(), ge_4);
×
130

131
    // Frozen activations (require version and enforce above freeze height).
132
    const auto bip34_ice = frozen && height >= settings.bip34_freeze;
×
133
    const auto bip66_ice = frozen && height >= settings.bip66_freeze;
×
134
    const auto bip65_ice = frozen && height >= settings.bip65_freeze;
×
135

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

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

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

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

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

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

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

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

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

166
    ////// bip30 is active for all but two mainnet blocks that violate the rule.
167
    ////// These two blocks each have a coinbase transaction that exactly duplicates
168
    ////// another that is not spent by the arrival of the corresponding duplicate.
169
    ////// This was later applied to the full history in implementation (a no-op).
170
    ////if (!is_bip30_exception({ values.hash, height }, mainnet))
171
    ////{
172
    ////    result.forks |= (forks::bip30_rule & forks);
173
    ////}
174

175
    // bip34 is activated based on 75% of preceding 1000 mainnet blocks.
176
    if (bip34_ice || (is_active(count_2, settings.activation_threshold) &&
×
177
        version >= settings.bip34_version))
×
178
    {
179
        result.forks |= (forks::bip34_rule & forks);
×
180
    }
181

182
    // bip66 is activated based on 75% of preceding 1000 mainnet blocks.
183
    if (bip66_ice || (is_active(count_3, settings.activation_threshold) &&
×
184
        version >= settings.bip66_version))
×
185
    {
186
        result.forks |= (forks::bip66_rule & forks);
×
187
    }
188

189
    // bip65 is activated based on 75% of preceding 1000 mainnet blocks.
190
    if (bip65_ice || (is_active(count_4, settings.activation_threshold) &&
×
191
        version >= settings.bip65_version))
×
192
    {
193
        result.forks |= (forks::bip65_rule & forks);
×
194
    }
195

196
    // version 4/3/2 enforced based on 95% of preceding 1000 mainnet blocks.
197
    if (bip65_ice || is_enforced(count_4, settings.enforcement_threshold))
×
198
    {
199
        result.minimum_block_version = settings.bip65_version;
×
200
    }
201
    else if (bip66_ice || is_enforced(count_3, settings.enforcement_threshold))
×
202
    {
203
        result.minimum_block_version = settings.bip66_version;
×
204
    }
205
    else if (bip34_ice || is_enforced(count_2, settings.enforcement_threshold))
×
206
    {
207
        result.minimum_block_version = settings.bip34_version;
×
208
    }
209
    else
210
    {
211
        result.minimum_block_version = settings.first_version;
212
    }
213

214
    return result;
×
215
}
216

217
size_t chain_state::bits_count(size_t height, uint32_t forks,
×
218
    size_t retargeting_interval) NOEXCEPT
219
{
220
    // Mainnet doesn't use bits in retargeting.
221
    if (script::is_enabled(forks, forks::difficult))
×
222
        return one;
223

224
    // Regtest bypasses all retargeting.
225
    if (!script::is_enabled(forks, forks::retarget))
×
226
        return one;
227

228
    // Testnet uses mainnet retargeting on interval.
229
    if (is_retarget_height(height, retargeting_interval))
×
230
        return one;
231

232
    // Testnet requires all bits for inter-interval retargeting.
233
    return std::min(height, retargeting_interval);
×
234
}
235

236
size_t chain_state::version_count(size_t height, uint32_t forks,
×
237
    size_t activation_sample) NOEXCEPT
238
{
239
    if (script::is_enabled(forks, forks::bip90_rule) ||
×
240
        !script::is_enabled(forks, forks::bip34_activations))
241
    {
242
        return zero;
243
    }
244

245
    return std::min(height, activation_sample);
×
246
}
247

248
size_t chain_state::timestamp_count(size_t height, uint32_t) NOEXCEPT
×
249
{
250
    return std::min(height, median_time_past_interval);
×
251
}
252

253
size_t chain_state::retarget_height(size_t height, uint32_t forks,
×
254
    size_t retargeting_interval) NOEXCEPT
255
{
256
    if (!script::is_enabled(forks, forks::retarget))
×
257
        return map::unrequested;
258

259
    // Height must be a positive multiple of interval, so underflow safe.
260
    // If not retarget height get most recent so that it may be promoted.
261
    return height - (is_retarget_height(height, retargeting_interval) ?
×
262
        retargeting_interval : retarget_distance(height, retargeting_interval));
×
263
}
264

265
// median_time_past
266
// ----------------------------------------------------------------------------
267

268
//*****************************************************************************
269
// CONSENSUS: satoshi associates the median time past for block N with block
270
// N-1, as opposed to block N. Given that the value is actually obtained from
271
// yet another preceding block in all cases except block 1 and 2, this is a
272
// curious and confusing convention. We associate the median time past for
273
// block N with block N. This is simple but requires care when comparing code.
274
//*****************************************************************************
275
uint32_t chain_state::median_time_past(const data& values, uint32_t) NOEXCEPT
×
276
{
277
    // Sort the times by value to obtain the median.
278
    auto times = sort_copy(values.timestamp.ordered);
×
279

280
    // Consensus defines median time using modulo 2 element selection.
281
    // This differs from arithmetic median which averages two middle values.
282
    BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)
283
    return times.empty() ? 0 : times.at(to_half(times.size()));
×
284
    BC_POP_WARNING()
285
}
×
286

287
// work_required
288
// ----------------------------------------------------------------------------
289

290
uint32_t chain_state::work_required(const data& values, uint32_t forks,
2✔
291
    const system::settings& settings) NOEXCEPT
292
{
293
    // Genesis has no preceding block data.
294
    if (is_zero(values.height))
2✔
295
        return 0;
296

297
    // Previous block has an invalid bits value.
298
    if (is_zero(compact::expand(bits_high(values))))
2✔
299
        return 0;
300

301
    // Regtest bypasses all retargeting.
302
    if (!script::is_enabled(forks, forks::retarget))
2✔
303
        return bits_high(values);
×
304

305
    // Mainnet and testnet retarget on interval.
306
    if (is_retarget_height(values.height, settings.retargeting_interval()))
2✔
307
        return work_required_retarget(values, forks,
6✔
308
            settings.proof_of_work_limit,
2✔
309
            settings.minimum_timespan(),
2✔
310
            settings.maximum_timespan(),
2✔
311
            settings.retargeting_interval_seconds);
4✔
312

313
    // Testnet retargets easy on inter-interval.
314
    if (!script::is_enabled(forks, forks::difficult))
×
315
        return easy_work_required(values,
×
316
            settings.retargeting_interval(),
×
317
            settings.proof_of_work_limit,
×
318
            settings.block_spacing_seconds);
×
319

320
    // Mainnet not retargeting, must exact match the previous block bits value.
321
    return bits_high(values);
×
322
}
323

324
// Get the bounded total time spanning the highest 2016 blocks.
325
uint32_t chain_state::retarget_timespan(const data& values,
2✔
326
    uint32_t minimum_timespan, uint32_t maximum_timespan) NOEXCEPT
327
{
328
    //*************************************************************************
329
    // CONSENSUS: "Subtract unsigned 32 bit numbers in signed 64 bit space".
330
    // This is done order to prevent underflow before applying the range
331
    // constraint. This is properly just a floored subtraction in 32 bit space.
332
    //*************************************************************************
333
    const auto timespan = floored_subtract(timestamp_high(values),
2✔
334
        values.timestamp.retarget);
2✔
335

336
    //*************************************************************************
337
    // CONSENSUS: Constrain the timespan to the configured consensus limits.
338
    //*************************************************************************
339
    return limit(timespan, minimum_timespan, maximum_timespan);
2✔
340
}
341

342
constexpr bool patch_timewarp(uint32_t forks, const uint256_t& limit,
2✔
343
    const uint256_t& target) NOEXCEPT
344
{
345
    return script::is_enabled(forks, forks::retarget_overflow_patch) &&
3✔
346
        floored_log2(target) >= floored_log2(limit);
1✔
347
}
348

349
uint32_t chain_state::work_required_retarget(const data& values, uint32_t forks,
2✔
350
    uint32_t proof_of_work_limit, uint32_t minimum_timespan,
351
    uint32_t maximum_timespan, uint32_t retargeting_interval_seconds) NOEXCEPT
352
{
353
    static const auto limit = compact::expand(proof_of_work_limit);
2✔
354
    auto target = compact::expand(bits_high(values));
2✔
355

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

359
    target >>= timewarp;
2✔
360
    target *= retarget_timespan(values, minimum_timespan, maximum_timespan);
2✔
361
    target /= retargeting_interval_seconds;
2✔
362
    target <<= timewarp;
2✔
363

364
    // Disallow target from falling below minimum configured.
365
    // All targets are a bits value normalized by compress here.
366
    return target > limit ? proof_of_work_limit : compact::compress(target);
2✔
367
}
368

369
// A retarget height, or a block that does not have proof_of_work_limit bits.
370
constexpr bool is_retarget_or_non_limit(size_t height, uint32_t bits,
×
371
    size_t retargeting_interval, uint32_t proof_of_work_limit) NOEXCEPT
372
{
373
    // Zero is a retarget height, termination required before height underflow.
374
    // This is guaranteed, just a comment here because it may not be obvious.
375
    return bits != proof_of_work_limit ||
×
376
        is_retarget_height(height, retargeting_interval);
377
}
378

379
uint32_t chain_state::easy_work_required(const data& values,
×
380
    size_t retargeting_interval, uint32_t proof_of_work_limit,
381
    uint32_t block_spacing_seconds) NOEXCEPT
382
{
383
    BC_ASSERT(!is_zero(values.height));
×
384

385
    // Overflow allowed here since supported coins would not do so.
386
    const auto easy_spacing_seconds = shift_left(block_spacing_seconds);
×
387

388
    // If the time limit has passed allow a minimum difficulty block.
389
    if (values.timestamp.self > ceilinged_add(timestamp_high(values),
×
390
        easy_spacing_seconds))
391
        return proof_of_work_limit;
392

393
    auto height = values.height;
×
394
    const auto& bits = values.bits.ordered;
×
395

396
    // Reverse iterate the ordered-by-height list of header bits.
397
    for (auto bit: views_reverse(bits))
×
398
    {
399
        if (is_retarget_or_non_limit(--height, bit, retargeting_interval,
×
400
            proof_of_work_limit))
401
            return bit;
×
402
    }
403

404
    // Since the set of heights is either a full retarget range or ends at
405
    // zero this is not reachable unless the data set is invalid.
406
    BC_ASSERT(false);
×
407
    return proof_of_work_limit;
×
408
}
409

410
// Public static
411
// ----------------------------------------------------------------------------
412

413
chain_state::map chain_state::get_map(size_t height,
×
414
    const system::settings& settings) NOEXCEPT
415
{
416
    if (is_zero(height))
×
417
        return {};
×
418

419
    const auto forks = settings.enabled_forks();
×
420
    const auto interval = settings.retargeting_interval();
×
421
    map map{};
×
422

423
    // The height bound of the reverse (high to low) retarget search.
424
    map.bits_self = height;
×
425
    map.bits.high = sub1(height);
×
426
    map.bits.count = bits_count(height, forks, interval);
×
427

428
    // The height bound of the median time past function.
429
    map.timestamp_self = height;
×
430
    map.timestamp.high = sub1(height);
×
431
    map.timestamp.count = timestamp_count(height, forks);
×
432

433
    // The height bound of the version sample for activations.
434
    map.version_self = height;
×
435
    map.version.high = sub1(height);
×
436
    map.version.count = version_count(height, forks,
×
437
        settings.activation_sample);
×
438

439
    // The most recent past retarget height.
440
    map.timestamp_retarget = retarget_height(height, forks, interval);
×
441
    return map;
×
442
}
443

444
uint32_t chain_state::signal_version(uint32_t forks,
×
445
    const system::settings& settings) NOEXCEPT
446
{
447
    if (script::is_enabled(forks, forks::bip65_rule))
×
448
        return settings.bip65_version;
×
449

450
    if (script::is_enabled(forks, forks::bip66_rule))
×
451
        return settings.bip66_version;
×
452

453
    if (script::is_enabled(forks, forks::bip34_rule))
×
454
        return settings.bip34_version;
×
455

456
    // TODO: these can be retired.
457
    // Signal bip9 bit0 if any of the group is configured.
458
    if (script::is_enabled(forks, forks::bip9_bit0_group))
×
459
        return settings.bip9_version_base | settings.bip9_version_bit0;
×
460

461
    // TODO: these can be retired.
462
    // Signal bip9 bit1 if any of the group is configured.
463
    if (script::is_enabled(forks, forks::bip9_bit1_group))
×
464
        return settings.bip9_version_base | settings.bip9_version_bit1;
×
465

466
    return settings.first_version;
×
467
}
468

469
// Constructors.
470
// ----------------------------------------------------------------------------
471

472
// This is promotion from a preceding height to the next.
473
chain_state::data chain_state::to_pool(const chain_state& top,
×
474
    const system::settings& settings) NOEXCEPT
475
{
476
    // Alias configured forks.
477
    const auto forks = top.forks_;
×
478

479
    // Retargeting is only activated via configuration.
480
    const auto retarget = script::is_enabled(forks, forks::retarget);
×
481

482
    // Copy data from presumed previous-height block state.
483
    chain_state::data data{ top.data_ };
×
484

485
    // If this overflows height is zero and result is handled as invalid.
486
    const auto height = add1(data.height);
×
487
    
488
    // Enqueue previous block values to collections.
489
    BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)
490
    data.bits.ordered.push_back(data.bits.self);
×
491
    data.version.ordered.push_back(data.version.self);
×
492
    data.timestamp.ordered.push_back(data.timestamp.self);
×
493
    BC_POP_WARNING()
494

495
    // If bits collection overflows, dequeue oldest member.
496
    if (data.bits.ordered.size() >
×
497
        bits_count(height, forks, settings.retargeting_interval()))
×
498
        data.bits.ordered.pop_front();
×
499

500
    // If version collection overflows, dequeue oldest member.
501
    if (data.version.ordered.size() > version_count(height, forks,
×
502
        settings.activation_sample))
×
503
        data.version.ordered.pop_front();
×
504

505
    // If timestamp collection overflows, dequeue oldest member.
506
    if (data.timestamp.ordered.size() > timestamp_count(height, forks))
×
507
        data.timestamp.ordered.pop_front();
×
508

509

510
    // Regtest does not perform retargeting.
511
    // If promoting from retarget height, move that timestamp into retarget.
512
    if (retarget && is_retarget_height(sub1(height),
×
513
        settings.retargeting_interval()))
×
514
    {
515
        // Conditionally patch time warp bug (e.g. Litecoin).
516
        const auto patch = script::is_enabled(forks, forks::time_warp_patch);
×
517

518
        data.timestamp.retarget = (patch && height != one) ?
×
519
            *std::next(data.timestamp.ordered.crbegin()) : data.timestamp.self;
×
520
    }
521

522
    // Replace previous block state with tx pool chain state for next height
523
    // Preserve top block timestamp for use in computation of staleness.
524
    // Preserve data.bip9_bit0_hash promotion.
525
    // Preserve data.bip9_bit1_hash promotion.
526
    // bits.self is unused.
527
    data.height = height;
×
528
    data.hash = {};
×
529
    data.bits.self = 0;
×
530
    data.version.self = signal_version(forks, settings);
×
531
    return data;
×
532
}
533

534
// Top to pool.
535
// This generates a state for the pool above the presumed top block state.
536
chain_state::chain_state(const chain_state& top,
×
537
    const system::settings& settings) NOEXCEPT
×
538
  : data_(to_pool(top, settings)),
×
539
    forks_(top.forks_),
×
540
    active_(activation(data_, forks_, settings)),
×
541
    work_required_(work_required(data_, forks_, settings)),
×
542
    median_time_past_(median_time_past(data_, forks_))
×
543
{
544
}
×
545

546
chain_state::data chain_state::to_block(const chain_state& pool,
×
547
    const block& block) NOEXCEPT
548
{
549
    // Copy data from presumed same-height pool state.
550
    chain_state::data data{ pool.data_ };
×
551

552
    // Replace pool chain state with block state at same (next) height.
553
    // Preserve data.timestamp.retarget promotion.
554
    const auto& header = block.header();
×
555
    data.hash = {};
×
556
    data.bits.self = header.bits();
×
557
    data.version.self = header.version();
×
558
    data.timestamp.self = header.timestamp();
×
559

560
    return data;
×
561
}
562

563
// Pool to block.
564
// This assumes that the pool state is the same height as the block.
565
chain_state::chain_state(const chain_state& pool, const block& block,
×
566
    const system::settings& settings) NOEXCEPT
×
567
  : data_(to_block(pool, block)),
×
568
    forks_(pool.forks_),
×
569
    active_(activation(data_, forks_, settings)),
×
570
    work_required_(work_required(data_, forks_, settings)),
×
571
    median_time_past_(median_time_past(data_, forks_))
×
572
{
573
}
×
574

575
chain_state::data chain_state::to_header(const chain_state& parent,
×
576
    const header& header, const system::settings& settings) NOEXCEPT
577
{
578
    BC_ASSERT(header.previous_block_hash() == parent.hash());
×
579

580
    // Copy and promote data from presumed parent-height header/block state.
581
    auto data = to_pool(parent, settings);
×
582

583
    // Replace the parent (pool or previous) block state with given state.
584
    // Preserve data.timestamp.retarget promotion.
585
    data.hash = header.hash();
×
586
    data.bits.self = header.bits();
×
587
    data.version.self = header.version();
×
588
    data.timestamp.self = header.timestamp();
×
589

590
    return data;
×
591
}
592

593
// Parent to header.
594
// This assumes that parent is the state of the header's previous block.
595
chain_state::chain_state(const chain_state& parent, const header& header,
×
596
    const system::settings& settings) NOEXCEPT
×
597
  : data_(to_header(parent, header, settings)),
×
598
    forks_(parent.forks_),
×
599
    active_(activation(data_, forks_, settings)),
×
600
    work_required_(work_required(data_, forks_, settings)),
×
601
    median_time_past_(median_time_past(data_, forks_))
×
602
{
603
}
×
604

605
// From scratch (e.g. raw data obtained from store).
606
chain_state::chain_state(data&& values,
×
607
    const system::settings& settings) NOEXCEPT
×
608
  : data_(std::move(values)),
×
609
    forks_(settings.enabled_forks()),
×
610
    active_(activation(data_, forks_, settings)),
×
611
    work_required_(work_required(data_, forks_, settings)),
×
612
    median_time_past_(median_time_past(data_, forks_))
×
613
{
614
}
×
615

616
// Properties.
617
// ----------------------------------------------------------------------------
618

619
const hash_digest& chain_state::hash() const NOEXCEPT
×
620
{
621
    return data_.hash;
×
622
}
623

624
uint32_t chain_state::minimum_block_version() const NOEXCEPT
×
625
{
626
    return active_.minimum_block_version;
×
627
}
628

629
uint32_t chain_state::work_required() const NOEXCEPT
×
630
{
631
    return work_required_;
×
632
}
633

634
// context
635

636
uint32_t chain_state::timestamp() const NOEXCEPT
×
637
{
638
    return data_.timestamp.self;
×
639
}
640

641
uint32_t chain_state::median_time_past() const NOEXCEPT
×
642
{
643
    return median_time_past_;
×
644
}
645

646
uint32_t chain_state::forks() const NOEXCEPT
×
647
{
648
    return active_.forks;
×
649
}
650

651
size_t chain_state::height() const NOEXCEPT
×
652
{
653
    return data_.height;
×
654
}
655

656
chain::context chain_state::context() const NOEXCEPT
×
657
{
658
    return
×
659
    {
660
        forks(),
×
661
        timestamp(),
×
662
        median_time_past(),
×
663
        possible_narrow_cast<uint32_t>(height()),
×
664
        minimum_block_version(),
×
665
        work_required()
×
666
    };
×
667
}
668

669
/// Current zulu (utc) time in seconds since epoch, using the wall clock.
670
/// Although not defined, epoch is almost always: 00:00, Jan 1 1970 UTC.
671
/// BUGBUG: en.wikipedia.org/wiki/Year_2038_problem
672
inline uint64_t zulu_time_seconds() NOEXCEPT
673
{
674
    using wall_clock = std::chrono::system_clock;
675
    const auto now = wall_clock::now();
676
    return sign_cast<uint64_t>(wall_clock::to_time_t(now));
677
}
678

679
} // namespace chain
680
} // namespace system
681
} // 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