Skip to content

Commit

Permalink
Refactor forks, incorporate bip30_deactivate/activate forks.
Browse files Browse the repository at this point in the history
  • Loading branch information
evoskuil committed Mar 28, 2024
1 parent 43e82c0 commit 8e2fc97
Show file tree
Hide file tree
Showing 10 changed files with 384 additions and 277 deletions.
82 changes: 57 additions & 25 deletions include/bitcoin/system/chain/chain_state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,31 @@ class BC_API chain_state
typedef std::deque<uint32_t> bitss;
typedef std::deque<uint32_t> versions;
typedef std::deque<uint32_t> timestamps;
typedef struct { size_t count; size_t high; } range;

typedef std::shared_ptr<chain_state> ptr;
typedef struct { size_t count; size_t high; } range;
typedef struct
{
bool bip16;
bool bip30;
bool bip30_deactivate;
bool bip30_reactivate;
bool bip34;
bool bip42;
bool bip65;
bool bip66;
bool bip68;
bool bip90;
bool bip112;
bool bip113;
bool bip141;
bool bip143;
bool bip147;
bool retarget; // !regtest
bool difficult; // !testnet
bool time_warp_patch; // litecoin
bool retarget_overflow_patch; // litecoin
bool scrypt_proof_of_work; // litecoin
} forks_t;

/// Heights used to identify construction requirements.
/// All values are lower-bounded by the genesis block height.
Expand Down Expand Up @@ -81,11 +103,14 @@ class BC_API chain_state
/// (block - (block % 2016 == 0 ? 2016 : block % 2016))
size_t timestamp_retarget{};

/// mainnet: 227931, testnet: 21111 (or map::unrequested)
size_t bip30_deactivate_height{ unrequested };

/// mainnet: 419328, testnet: 770112 (or map::unrequested)
size_t bip9_bit0_height;
size_t bip9_bit0_height{ unrequested };

/// mainnet: 481824, testnet: 834624 (or map::unrequested)
size_t bip9_bit1_height;
size_t bip9_bit1_height{ unrequested };
};

/// Values used to populate chain state at the target height.
Expand All @@ -97,14 +122,17 @@ class BC_API chain_state
/// Hash of the candidate block or null_hash for memory pool.
hash_digest hash{};

/// Hash of the bip34 block that inactivates bip30, or null_hash.
hash_digest bip30_deactivate_hash{};

/// Hash of the bip9_bit0 block or null_hash if unrequested.
hash_digest bip9_bit0_hash;
hash_digest bip9_bit0_hash{};

/// Hash of the bip9_bit1 block or null_hash if unrequested.
hash_digest bip9_bit1_hash;
hash_digest bip9_bit1_hash{};

/// Sum of all work from genesis to block height.
uint256_t cumulative_work;
uint256_t cumulative_work{};

/// Values must be ordered by height with high (block - 1) last.
struct
Expand Down Expand Up @@ -154,8 +182,8 @@ class BC_API chain_state
static map get_map(size_t height,
const system::settings& settings) NOEXCEPT;

/// The block version to signal based on active forks.
static uint32_t signal_version(uint32_t forks,
/// The block version to signal based on configured forks.
static uint32_t signal_version(
const system::settings& settings) NOEXCEPT;

/// Create pool state from top chain top block state.
Expand All @@ -181,39 +209,42 @@ class BC_API chain_state
uint32_t work_required() const NOEXCEPT;
uint32_t timestamp() const NOEXCEPT;
uint32_t median_time_past() const NOEXCEPT;
uint32_t forks() const NOEXCEPT;
uint32_t flags() const NOEXCEPT;
size_t height() const NOEXCEPT;

protected:
struct activations
{
/// The forks that are active at this height.
uint32_t forks;
uint32_t flags;

/// The minimum block version required at this height.
uint32_t minimum_block_version;
};

/// No failure sentinel.
static activations activation(const data& values, uint32_t forks,
const system::settings& settings) NOEXCEPT;
static activations activation(const data& values,
const forks_t& forks, const system::settings& settings) NOEXCEPT;

/// Returns zero if data is invalid.
static uint32_t median_time_past(const data& values,
uint32_t forks) NOEXCEPT;
const forks_t& forks) NOEXCEPT;

/// Returns zero if data is invalid.
static uint32_t work_required(const data& values, uint32_t forks,
const system::settings& settings) NOEXCEPT;
static uint32_t work_required(const data& values,
const forks_t& forks, const system::settings& settings) NOEXCEPT;

private:
static size_t bits_count(size_t height, uint32_t forks,
static size_t bits_count(size_t height, const forks_t& forks,
size_t retargeting_interval) NOEXCEPT;
static size_t version_count(size_t height, uint32_t forks,
static size_t version_count(size_t height, const forks_t& forks,
size_t bip34_activation_sample) NOEXCEPT;
static size_t timestamp_count(size_t height, uint32_t forks) NOEXCEPT;
static size_t retarget_height(size_t height, uint32_t forks,
static size_t timestamp_count(size_t height, const forks_t& forks) NOEXCEPT;
static size_t retarget_height(size_t height, const forks_t& forks,
size_t retargeting_interval) NOEXCEPT;

static size_t bip30_deactivate_height(size_t height,
const checkpoint& bip30_deactivate_checkpoint) NOEXCEPT;
static size_t bip9_bit0_height(size_t height,
const checkpoint& bip9_bit0_active_checkpoint) NOEXCEPT;
static size_t bip9_bit1_height(size_t height,
Expand All @@ -226,9 +257,10 @@ class BC_API chain_state
static data to_header(const chain_state& parent, const header& header,
const system::settings& settings) NOEXCEPT;

static uint32_t work_required_retarget(const data& values, uint32_t forks,
uint32_t proof_of_work_limit, uint32_t minimum_timespan,
uint32_t maximum_timespan, uint32_t retargeting_interval_seconds) NOEXCEPT;
static uint32_t work_required_retarget(const data& values,
const forks_t& forks, uint32_t proof_of_work_limit,
uint32_t minimum_timespan, uint32_t maximum_timespan,
uint32_t retargeting_interval_seconds) NOEXCEPT;
static uint32_t retarget_timespan(const data& values,
uint32_t minimum_timespan, uint32_t maximum_timespan) NOEXCEPT;
static uint32_t easy_work_required(const data& values,
Expand All @@ -237,8 +269,8 @@ class BC_API chain_state

// These are thread safe.
const data data_;
const uint32_t forks_;
const activations active_;
const forks_t& forks_;
const activations activations_;
const uint32_t work_required_;
const uint32_t median_time_past_;
const uint256_t cumulative_work_;
Expand Down
2 changes: 1 addition & 1 deletion include/bitcoin/system/chain/context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class BC_API context final
bool is_enabled(chain::forks fork) const NOEXCEPT;

/// Header context within chain.
uint32_t forks;
uint32_t flags;
uint32_t timestamp;
uint32_t median_time_past;
size_t height;
Expand Down
31 changes: 11 additions & 20 deletions include/bitcoin/system/chain/enums/forks.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ enum forks : uint32_t
/// Pay-to-script-hash enabled (soft fork, feature).
bip16_rule = bit_right<uint32_t>(2),

/// No duplicated unspent transaction ids (soft fork, deflation).
/// No duplicated unspent transaction ids (soft/hard/soft fork, deflation).
/// This (initially) soft fork rule expires and then unexpires (hard/soft).
bip30_rule = bit_right<uint32_t>(3),

/// Coinbase must include height, redundant w/bip30 (soft fork, arbitrary).
Expand Down Expand Up @@ -86,81 +87,71 @@ enum forks : uint32_t
/// Finite monetary supply, effective at 13,440,000 (soft fork, inflation).
bip42_rule = bit_right<uint32_t>(17),

// TODO:
/// TODO: hardwired or obsoleted (historical).
/// -----------------------------------------------------------------------

/// Promote nop1..nop10 [0.3.6] (hard fork, expansion).
/// Combined script max 20,000 bytes, push_data 520 (soft fork, arbitrary).
/// Initial script and push_data size limits (soft fork, arbitrary).
/// Demote return, op_ver, verif, vernotif (soft fork, security).
nops_rule = bit_right<uint32_t>(18),

// TODO:
/// Splits script evaluation, activated by [0.3.7] (hard fork, security).
/// Per script max 10,000 bytes, one more total byte than prior, as the
/// previous limit was imposed after concatenating with op_codeseparator.
split_rule = bit_right<uint32_t>(19),

// TODO:
/// Invalidate op_cat, etc. [0.3.9] (soft fork, security).
cats_rule = bit_right<uint32_t>(20),

// TODO:
/// The original rule leaked output value, was plugged here (soft fork).
/// This was activated at block 74,638 [0.3.10], later to all blocks.
plug_rule = bit_right<uint32_t>(21),

// TODO:
/// Limit block size to 1,000,000 bytes (soft fork, system DoS).
/// Limit signature operations per block (soft fork, system DoS).
/// This was activated at block 79,400 [0.3.12], and later to all blocks.
size_rule = bit_right<uint32_t>(22),

// TODO:
/// Release [0.8.0] removal of hash limit, chain split at block 225,430.
/// Original rule was from Berkely DB [unknown] (hard fork, determinism).
unlock_rule = bit_right<uint32_t>(23),

// TODO:
/// This allowed double spends, applied and removed (hard fork, inflation).
/// Activated (hard fork) in [0.15.0] deactivated (soft fork) in [0.16.3].
inflation_rule = bit_right<uint32_t>(24),

// TODO:
/// Tx and input hashes max 4,500 per block (hard fork, determinism).
/// Tx and input hashes max 4,500 per block (soft/hard fork, determinism).
/// This (initially) soft fork rule expires, which makes it a hard fork.
bip50_rule = bit_right<uint32_t>(25),

// TODO:
/// Reduces threshold segregated witness signaling (soft fork, feature).
bip91_rule = bit_right<uint32_t>(26),

/// TODO: taproot rules.
/// Agregates
/// -----------------------------------------------------------------------

/// Rules that use bip34-based activation.
bip34_activations =
forks::bip34_rule |
forks::bip65_rule |
forks::bip66_rule,

/// TODO:
/// Rules that use BIP9 bit 0 first time activation.
bip9_bit0_group =
forks::bip68_rule |
forks::bip112_rule |
forks::bip113_rule,

/// TODO:
/// Rules that use BIP9 bit 1 first time activation.
bip9_bit1_group =
forks::bip141_rule |
forks::bip143_rule |
forks::bip147_rule,

/// TODO:
/// Rules that use BIP9 bit 4 first time activation.
bip9_bit4_group =
forks::bip91_rule,

/// TODO: rules that use taproot-style activation.
/////// Rules that use BIP9 bit 4 first time activation.
////bip9_bit4_group =
//// forks::bip91_rule,

/// Mask to set all rule bits.
all_rules = bit_all<uint32_t>
Expand Down
10 changes: 5 additions & 5 deletions include/bitcoin/system/impl/machine/interpreter.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -1607,7 +1607,7 @@ connect(const context& state, const transaction& tx,
return error::missing_previous_output;

// Evaluate input script.
interpreter in_program(tx, it, state.forks);
interpreter in_program(tx, it, state.flags);
if ((ec = in_program.run()))
return ec;

Expand All @@ -1622,13 +1622,13 @@ connect(const context& state, const transaction& tx,
{
return error::stack_false;
}
else if (prevout->is_pay_to_script_hash(state.forks))
else if (prevout->is_pay_to_script_hash(state.flags))
{
// Because output script pushed script hash program (bip16).
if ((ec = connect_embedded(state, tx, it, in_program)))
return ec;
}
else if (prevout->is_pay_to_witness(state.forks))
else if (prevout->is_pay_to_witness(state.flags))
{
// The input script must be empty (bip141).
if (!input.script().ops().empty())
Expand Down Expand Up @@ -1674,7 +1674,7 @@ code interpreter<Stack>::connect_embedded(const context& state,
{
return error::stack_false;
}
else if (prevout->is_pay_to_witness(state.forks))
else if (prevout->is_pay_to_witness(state.flags))
{
// The input script must be a push of the embedded_script (bip141).
if (input.script().ops().size() != one)
Expand Down Expand Up @@ -1716,7 +1716,7 @@ code interpreter<Stack>::connect_witness(const context&state,
return error::invalid_witness;

// A defined version indicates bip141 is active.
interpreter program(tx, it, script, state.forks, version, stack);
interpreter program(tx, it, script, state.flags, version, stack);
if ((ec = program.run()))
return ec;

Expand Down
44 changes: 13 additions & 31 deletions include/bitcoin/system/settings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,34 +43,17 @@ class BC_API settings
virtual uint64_t max_money() const NOEXCEPT;
virtual uint64_t initial_subsidy() const NOEXCEPT;
virtual uint64_t bitcoin_to_satoshi(uint64_t value) const NOEXCEPT;
virtual uint32_t enabled_forks() const NOEXCEPT;

/// These are used internal to system.
virtual uint32_t minimum_timespan() const NOEXCEPT;
virtual uint32_t maximum_timespan() const NOEXCEPT;
virtual size_t retargeting_interval() const NOEXCEPT;

/// Implemented chain::forks.
/// Configured forks.
/// -----------------------------------------------------------------------

/// These are not used internal to system.
bool bip16;
bool bip30;
bool bip34;
bool bip42;
bool bip65;
bool bip66;
bool bip68;
bool bip90;
bool bip112;
bool bip113;
bool bip141;
bool bip143;
bool bip147;
bool retarget; // !regtest
bool difficult; // !testnet
bool time_warp_patch; // litecoin
bool retarget_overflow_patch; // litecoin
bool scrypt_proof_of_work; // litecoin
chain::chain_state::forks_t forks{};

/// Consensus parameters.
/// -----------------------------------------------------------------------
Expand Down Expand Up @@ -101,24 +84,23 @@ class BC_API settings
uint32_t bip9_version_bit1;
uint32_t bip9_version_base;

/// Block 514 is the first testnet block after date-based activation.
/// Block 173805 is the first mainnet block after date-based activation.
/// First mainnet activation window hardwired in satoshi 0.6.0rc1 failed.
uint32_t bip16_activation_time{};

/// Activation parameters (bip34-style activations).
size_t bip34_activation_threshold{};
size_t bip34_enforcement_threshold{};
size_t bip34_activation_sample{};

/// Frozen activation heights (frozen_activations).
size_t bip65_freeze{};
size_t bip66_freeze{};
size_t bip34_freeze{};

/// Block 514 is the first testnet block after date-based activation.
/// Block 173805 is the first mainnet block after date-based activation.
/// First mainnet activation window hardwired in satoshi 0.6.0rc1 failed.
uint32_t bip16_activation_time{};
size_t bip90_bip34_height{};
size_t bip90_bip65_height{};
size_t bip90_bip66_height{};

/// This is not used in consensus computations.
/// bip90 stops checking unspent duplicates above this bip34 activation.
chain::checkpoint bip34_active_checkpoint{};
size_t bip30_reactivate_height{};
chain::checkpoint bip30_deactivate_checkpoint{};

/// This cannot be reactivated in a future branch due to window expiration.
chain::checkpoint bip9_bit0_active_checkpoint{};
Expand Down
Loading

0 comments on commit 8e2fc97

Please sign in to comment.