diff --git a/Makefile.am b/Makefile.am index 857a09e2b3..f17e906f9d 100755 --- a/Makefile.am +++ b/Makefile.am @@ -418,6 +418,7 @@ include_bitcoin_system_HEADERS = \ include/bitcoin/system/constraints.hpp \ include/bitcoin/system/define.hpp \ include/bitcoin/system/exceptions.hpp \ + include/bitcoin/system/forks.hpp \ include/bitcoin/system/funclets.hpp \ include/bitcoin/system/have.hpp \ include/bitcoin/system/literals.hpp \ @@ -449,7 +450,7 @@ include_bitcoin_system_chain_HEADERS = \ include_bitcoin_system_chain_enumsdir = ${includedir}/bitcoin/system/chain/enums include_bitcoin_system_chain_enums_HEADERS = \ include/bitcoin/system/chain/enums/coverage.hpp \ - include/bitcoin/system/chain/enums/forks.hpp \ + include/bitcoin/system/chain/enums/flags.hpp \ include/bitcoin/system/chain/enums/magic_numbers.hpp \ include/bitcoin/system/chain/enums/numbers.hpp \ include/bitcoin/system/chain/enums/opcode.hpp \ diff --git a/builds/msvc/vs2022/libbitcoin-system/libbitcoin-system.vcxproj b/builds/msvc/vs2022/libbitcoin-system/libbitcoin-system.vcxproj index f6df65a402..f79db3df19 100644 --- a/builds/msvc/vs2022/libbitcoin-system/libbitcoin-system.vcxproj +++ b/builds/msvc/vs2022/libbitcoin-system/libbitcoin-system.vcxproj @@ -332,6 +332,7 @@ + @@ -610,4 +611,4 @@ - \ No newline at end of file + diff --git a/builds/msvc/vs2022/libbitcoin-system/libbitcoin-system.vcxproj.filters b/builds/msvc/vs2022/libbitcoin-system/libbitcoin-system.vcxproj.filters index b2d538d89f..0cd02801f5 100644 --- a/builds/msvc/vs2022/libbitcoin-system/libbitcoin-system.vcxproj.filters +++ b/builds/msvc/vs2022/libbitcoin-system/libbitcoin-system.vcxproj.filters @@ -875,6 +875,9 @@ include\bitcoin\system + + include\bitcoin\system + include\bitcoin\system @@ -1604,4 +1607,4 @@ resource - \ No newline at end of file + diff --git a/include/bitcoin/system.hpp b/include/bitcoin/system.hpp index 9a65b19da8..be4fd77623 100755 --- a/include/bitcoin/system.hpp +++ b/include/bitcoin/system.hpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/include/bitcoin/system/chain/chain_state.hpp b/include/bitcoin/system/chain/chain_state.hpp index eeda1cc973..72fd892cea 100644 --- a/include/bitcoin/system/chain/chain_state.hpp +++ b/include/bitcoin/system/chain/chain_state.hpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -38,6 +39,8 @@ namespace chain { class block; class header; +/// system::settings are using within chain_state to compute context, but are +/// not used directly within chain classes, which would be an abstraction leak. class BC_API chain_state { public: @@ -49,35 +52,6 @@ class BC_API chain_state typedef std::shared_ptr ptr; typedef struct { size_t count; size_t high; } range; - /// Chain state accepts configured forks and maps them onto active flags - /// for the a given validaton context (i.e. block). These are exposed as - /// chain::chain_state.flags() and chain::context.flags. system::settings - /// settings are using within chain_state to compute context, but are never - /// used directly within chain classes, which would be an abstraction leak. - 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. /// Obtaining all values even in the case where the set of queries could be @@ -230,23 +204,23 @@ class BC_API chain_state /// No failure sentinel. static activations activation(const data& values, - const forks_t& forks, const system::settings& settings) NOEXCEPT; + const forks& forks, const system::settings& settings) NOEXCEPT; /// Returns zero if data is invalid. static uint32_t median_time_past(const data& values, - const forks_t& forks) NOEXCEPT; + const forks& forks) NOEXCEPT; /// Returns zero if data is invalid. static uint32_t work_required(const data& values, - const forks_t& forks, const system::settings& settings) NOEXCEPT; + const forks& forks, const system::settings& settings) NOEXCEPT; private: - static size_t bits_count(size_t height, const forks_t& forks, + static size_t bits_count(size_t height, const forks& forks, size_t retargeting_interval) NOEXCEPT; - static size_t version_count(size_t height, const forks_t& forks, + static size_t version_count(size_t height, const forks& forks, size_t bip34_activation_sample) NOEXCEPT; - 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, + static size_t timestamp_count(size_t height, const forks& forks) NOEXCEPT; + static size_t retarget_height(size_t height, const forks& forks, size_t retargeting_interval) NOEXCEPT; static size_t bip30_deactivate_height(size_t height, @@ -264,7 +238,7 @@ class BC_API chain_state const system::settings& settings) NOEXCEPT; static uint32_t work_required_retarget(const data& values, - const forks_t& forks, uint32_t proof_of_work_limit, + const forks& 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, @@ -275,7 +249,7 @@ class BC_API chain_state // These are thread safe. const data data_; - const forks_t& forks_; + const forks& forks_; const activations activations_; const uint32_t work_required_; const uint32_t median_time_past_; diff --git a/include/bitcoin/system/forks.hpp b/include/bitcoin/system/forks.hpp new file mode 100644 index 0000000000..0097c5407f --- /dev/null +++ b/include/bitcoin/system/forks.hpp @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2011-2024 libbitcoin developers (see AUTHORS) + * + * This file is part of libbitcoin. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +#ifndef LIBBITCOIN_SYSTEM_FORKS_HPP +#define LIBBITCOIN_SYSTEM_FORKS_HPP + +namespace libbitcoin { +namespace system { + +/// Chain state accepts configured forks and maps them onto active flags +/// for the a given validaton context (i.e. block). These are exposed as +/// chain::chain_state.flags() and chain::context.flags. +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; + +} // namespace system +} // namespace libbitcoin + +#endif diff --git a/include/bitcoin/system/settings.hpp b/include/bitcoin/system/settings.hpp index 2e296ac568..1d97f75bb2 100644 --- a/include/bitcoin/system/settings.hpp +++ b/include/bitcoin/system/settings.hpp @@ -23,6 +23,7 @@ #include #include #include +#include namespace libbitcoin { namespace system { @@ -53,7 +54,7 @@ class BC_API settings /// ----------------------------------------------------------------------- /// These are used by chain_state (only). - chain::chain_state::forks_t forks{}; + forks forks{}; /// Consensus parameters. /// ----------------------------------------------------------------------- diff --git a/src/chain/chain_state.cpp b/src/chain/chain_state.cpp index 465e62ff30..da53d2fd95 100644 --- a/src/chain/chain_state.cpp +++ b/src/chain/chain_state.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -100,7 +101,7 @@ inline uint32_t bits_high(const chain_state::data& values) NOEXCEPT // ---------------------------------------------------------------------------- chain_state::activations chain_state::activation(const data& values, - const forks_t& forks, const system::settings& settings) NOEXCEPT + const forks& forks, const system::settings& settings) NOEXCEPT { // Initialize activation results with genesis values. activations result{ flags::no_rules, settings.first_version }; @@ -270,7 +271,7 @@ chain_state::activations chain_state::activation(const data& values, return result; } -size_t chain_state::bits_count(size_t height, const forks_t& forks, +size_t chain_state::bits_count(size_t height, const forks& forks, size_t retargeting_interval) NOEXCEPT { // Mainnet doesn't use bits in retargeting. @@ -289,7 +290,7 @@ size_t chain_state::bits_count(size_t height, const forks_t& forks, return std::min(height, retargeting_interval); } -size_t chain_state::version_count(size_t height, const forks_t& forks, +size_t chain_state::version_count(size_t height, const forks& forks, size_t bip34_activation_sample) NOEXCEPT { if (forks.bip90 || (!forks.bip34 && !forks.bip65 && !forks.bip66)) @@ -298,12 +299,12 @@ size_t chain_state::version_count(size_t height, const forks_t& forks, return std::min(height, bip34_activation_sample); } -size_t chain_state::timestamp_count(size_t height, const forks_t&) NOEXCEPT +size_t chain_state::timestamp_count(size_t height, const forks&) NOEXCEPT { return std::min(height, median_time_past_interval); } -size_t chain_state::retarget_height(size_t height, const forks_t& forks, +size_t chain_state::retarget_height(size_t height, const forks& forks, size_t retargeting_interval) NOEXCEPT { if (!forks.retarget) @@ -326,7 +327,7 @@ size_t chain_state::retarget_height(size_t height, const forks_t& forks, // block N with block N. This is simple but requires care when comparing code. //***************************************************************************** uint32_t chain_state::median_time_past(const data& values, - const forks_t&) NOEXCEPT + const forks&) NOEXCEPT { // Sort the times by value to obtain the median. auto times = sort_copy(values.timestamp.ordered); @@ -341,7 +342,7 @@ uint32_t chain_state::median_time_past(const data& values, // work_required // ---------------------------------------------------------------------------- -uint32_t chain_state::work_required(const data& values, const forks_t& forks, +uint32_t chain_state::work_required(const data& values, const forks& forks, const system::settings& settings) NOEXCEPT { // Genesis has no preceding block data. @@ -393,15 +394,15 @@ uint32_t chain_state::retarget_timespan(const data& values, return limit(timespan, minimum_timespan, maximum_timespan); } -constexpr bool patch_timewarp(const chain_state::forks_t& forks, - const uint256_t& limit, const uint256_t& target) NOEXCEPT +constexpr bool patch_timewarp(const forks& forks, const uint256_t& limit, + const uint256_t& target) NOEXCEPT { return forks.retarget_overflow_patch && floored_log2(target) >= floored_log2(limit); } uint32_t chain_state::work_required_retarget(const data& values, - const forks_t& forks, uint32_t proof_of_work_limit, + const forks& forks, uint32_t proof_of_work_limit, uint32_t minimum_timespan, uint32_t maximum_timespan, uint32_t retargeting_interval_seconds) NOEXCEPT { diff --git a/src/define.cpp b/src/define.cpp index d67f9c7572..3eb1589a04 100644 --- a/src/define.cpp +++ b/src/define.cpp @@ -36,6 +36,7 @@ // typelets : funclets // constraints : typelets // define : constraints +// forks : // Other directory common includes are not internally chained. // Each header includes only its required common headers. @@ -52,11 +53,11 @@ // /hash : /radix // /crypto : /hash // /stream : /crypto /endian /error -// /chain : /stream [forward: settings] +// /chain : /stream forks [forward: settings] // /machine : /chain // /config : /chain // /wallet : /chain -// settings : /chain +// settings : /chain forks // When a symbol is unexplainably undefined, its defining include is probably // creating the circularity.