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

libbitcoin / libbitcoin-system / 4541988544

pending completion
4541988544

Pull #1344

github

GitHub
Merge 76663c241 into b3a9246c4
Pull Request #1344: Remove dead code, add context equality operators.

18 of 18 new or added lines in 2 files covered. (100.0%)

9429 of 11315 relevant lines covered (83.33%)

6748552.12 hits per line

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

14.29
/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
2✔
91
{
92
    return values.bits.ordered.back();
4✔
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 requires no work.
294
    if (is_zero(values.height))
2✔
295
        return 0;
296

297
    BC_ASSERT_MSG(!is_zero(compact::expand(bits_high(values))),
298
        "previous block has invalid bits value");
2✔
299

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

409
// Public static
410
// ----------------------------------------------------------------------------
411

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

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

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

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

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

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

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

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

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

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

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

465
    return settings.first_version;
×
466
}
467

468
// Constructors.
469
// ----------------------------------------------------------------------------
470

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

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

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

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

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

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

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

508

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

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

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

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

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

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

557
    return data;
×
558
}
559

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

572
chain_state::data chain_state::to_header(const chain_state& parent,
×
573
    const header& header, const system::settings& settings) NOEXCEPT
574
{
575
    // Copy and promote data from presumed parent-height header/block state.
576
    auto data = to_pool(parent, settings);
×
577

578
    // Replace the pool (empty) current block state with given header state.
579
    // Preserve data.timestamp.retarget promotion.
580
    data.bits.self = header.bits();
×
581
    data.version.self = header.version();
×
582
    data.timestamp.self = header.timestamp();
×
583

584
    return data;
×
585
}
586

587
// Parent to header.
588
// This assumes that parent is the state of the header's previous block.
589
chain_state::chain_state(const chain_state& parent, const header& header,
×
590
    const system::settings& settings) NOEXCEPT
×
591
  : data_(to_header(parent, header, settings)),
×
592
    forks_(parent.forks_),
×
593
    active_(activation(data_, forks_, settings)),
×
594
    work_required_(work_required(data_, forks_, settings)),
×
595
    median_time_past_(median_time_past(data_, forks_))
×
596
{
597
}
×
598

599
// From scratch (e.g. raw data obtained from store).
600
chain_state::chain_state(data&& values,
×
601
    const system::settings& settings) NOEXCEPT
×
602
  : data_(std::move(values)),
×
603
    forks_(settings.enabled_forks()),
×
604
    active_(activation(data_, forks_, settings)),
×
605
    work_required_(work_required(data_, forks_, settings)),
×
606
    median_time_past_(median_time_past(data_, forks_))
×
607
{
608
}
×
609

610
// Properties.
611
// ----------------------------------------------------------------------------
612

613
uint32_t chain_state::minimum_block_version() const NOEXCEPT
×
614
{
615
    return active_.minimum_block_version;
×
616
}
617

618
uint32_t chain_state::work_required() const NOEXCEPT
×
619
{
620
    return work_required_;
×
621
}
622

623
// context
624

625
uint32_t chain_state::timestamp() const NOEXCEPT
×
626
{
627
    return data_.timestamp.self;
×
628
}
629

630
uint32_t chain_state::median_time_past() const NOEXCEPT
×
631
{
632
    return median_time_past_;
×
633
}
634

635
uint32_t chain_state::forks() const NOEXCEPT
×
636
{
637
    return active_.forks;
×
638
}
639

640
size_t chain_state::height() const NOEXCEPT
×
641
{
642
    return data_.height;
×
643
}
644

645
chain::context chain_state::context() const NOEXCEPT
×
646
{
647
    return
×
648
    {
649
        forks(),
×
650
        timestamp(),
×
651
        median_time_past(),
×
652
        possible_narrow_cast<uint32_t>(height()),
×
653
        minimum_block_version(),
×
654
        work_required()
×
655
    };
×
656
}
657

658
/// Current zulu (utc) time in seconds since epoch, using the wall clock.
659
/// Although not defined, epoch is almost always: 00:00, Jan 1 1970 UTC.
660
/// BUGBUG: en.wikipedia.org/wiki/Year_2038_problem
661
inline uint64_t zulu_time_seconds() NOEXCEPT
662
{
663
    using wall_clock = std::chrono::system_clock;
664
    const auto now = wall_clock::now();
665
    return sign_cast<uint64_t>(wall_clock::to_time_t(now));
666
}
667

668
} // namespace chain
669
} // namespace system
670
} // 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