From 2344f35b450384b1d96e33d0649bc636d43621aa Mon Sep 17 00:00:00 2001 From: evoskuil Date: Sat, 17 Feb 2024 18:07:41 -0500 Subject: [PATCH 01/10] Move chaser_header properties to protected for test. --- include/bitcoin/node/chasers/chaser_header.hpp | 4 ++++ src/chasers/chaser_header.cpp | 16 ++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/include/bitcoin/node/chasers/chaser_header.hpp b/include/bitcoin/node/chasers/chaser_header.hpp index 980d512b..a6924f39 100644 --- a/include/bitcoin/node/chasers/chaser_header.hpp +++ b/include/bitcoin/node/chasers/chaser_header.hpp @@ -88,6 +88,10 @@ class BCN_API chaser_header /// Move tree header to database and push to top of candidate chain. virtual bool push(const system::hash_digest& key) NOEXCEPT; + /// Properties. + virtual const network::wall_clock::duration& currency_window() const NOEXCEPT; + virtual bool use_currency_window() const NOEXCEPT; + private: void do_handle_event(const code& ec, chase event_, link value) NOEXCEPT; void do_organize(const system::chain::header::cptr& header, diff --git a/src/chasers/chaser_header.cpp b/src/chasers/chaser_header.cpp index 59db43ac..00824ab9 100644 --- a/src/chasers/chaser_header.cpp +++ b/src/chasers/chaser_header.cpp @@ -41,6 +41,18 @@ chaser_header::chaser_header(full_node& node) NOEXCEPT { } +// protected +const network::wall_clock::duration& chaser_header::currency_window() const NOEXCEPT +{ + return currency_window_; +} + +// protected +bool chaser_header::use_currency_window() const NOEXCEPT +{ + return use_currency_window_; +} + // protected code chaser_header::start() NOEXCEPT { @@ -190,11 +202,11 @@ void chaser_header::do_organize(const chain::header::cptr& header, // protected bool chaser_header::is_current(const chain::header& header) const NOEXCEPT { - if (!use_currency_window_) + if (!use_currency_window()) return true; const auto time = wall_clock::from_time_t(header.timestamp()); - const auto current = wall_clock::now() - currency_window_; + const auto current = wall_clock::now() - currency_window(); return time >= current; } From 7198f3a07cd50e03d0a9ec61322d180854d3d124 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Sat, 17 Feb 2024 18:08:01 -0500 Subject: [PATCH 02/10] Add chaser_header property tests. --- test/chasers/chaser.cpp | 42 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/test/chasers/chaser.cpp b/test/chasers/chaser.cpp index 8094d70d..9ee047a7 100644 --- a/test/chasers/chaser.cpp +++ b/test/chasers/chaser.cpp @@ -20,9 +20,47 @@ BOOST_AUTO_TEST_SUITE(chaser_tests) -BOOST_AUTO_TEST_CASE(chaser_test) +class chaser_header_accessor + : chaser_header { - BOOST_REQUIRE(true); +public: + using chaser_header::chaser_header; + + const network::wall_clock::duration& currency_window_() const NOEXCEPT + { + return currency_window(); + } + + bool use_currency_window_() const NOEXCEPT + { + return use_currency_window(); + } +}; + +BOOST_AUTO_TEST_CASE(chaser_test__currency_window__zero__use_currency_window_false) +{ + const network::logger log{}; + node::configuration config(system::chain::selection::mainnet); + config.node.currency_window_minutes = 0; + + full_node::store store(config.database); + full_node::query query(store); + full_node node(query, config, log); + chaser_header_accessor instance(node); + BOOST_REQUIRE(!instance.use_currency_window_()); +} + +BOOST_AUTO_TEST_CASE(chaser_test__currency_window__nonzero__use_currency_window_true) +{ + const network::logger log{}; + node::configuration config(system::chain::selection::mainnet); + config.node.currency_window_minutes = 60; + + full_node::store store(config.database); + full_node::query query(store); + full_node node(query, config, log); + chaser_header_accessor instance(node); + BOOST_REQUIRE(instance.use_currency_window_()); } BOOST_AUTO_TEST_SUITE_END() From 34787fea348844d6f3b03e8263584a0fdc5e80fa Mon Sep 17 00:00:00 2001 From: evoskuil Date: Sun, 18 Feb 2024 08:58:10 -0500 Subject: [PATCH 03/10] Comment on inherent Year 2106 bug. --- src/chasers/chaser_header.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/chasers/chaser_header.cpp b/src/chasers/chaser_header.cpp index 00824ab9..8db9b899 100644 --- a/src/chasers/chaser_header.cpp +++ b/src/chasers/chaser_header.cpp @@ -205,6 +205,7 @@ bool chaser_header::is_current(const chain::header& header) const NOEXCEPT if (!use_currency_window()) return true; + /// BUGBUG: en.wikipedia.org/wiki/Time_formatting_and_storage_bugs#Year_2106 const auto time = wall_clock::from_time_t(header.timestamp()); const auto current = wall_clock::now() - currency_window(); return time >= current; From 5f72c994e1c72909b5830671073d80ce7cf2ec50 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Sun, 18 Feb 2024 09:00:20 -0500 Subject: [PATCH 04/10] Add chaser_header_tests, move to correct test file. --- test/chasers/chaser.cpp | 42 +---------- test/chasers/chaser_header.cpp | 125 ++++++++++++++++++++++++++++++++- 2 files changed, 125 insertions(+), 42 deletions(-) diff --git a/test/chasers/chaser.cpp b/test/chasers/chaser.cpp index 9ee047a7..8094d70d 100644 --- a/test/chasers/chaser.cpp +++ b/test/chasers/chaser.cpp @@ -20,47 +20,9 @@ BOOST_AUTO_TEST_SUITE(chaser_tests) -class chaser_header_accessor - : chaser_header +BOOST_AUTO_TEST_CASE(chaser_test) { -public: - using chaser_header::chaser_header; - - const network::wall_clock::duration& currency_window_() const NOEXCEPT - { - return currency_window(); - } - - bool use_currency_window_() const NOEXCEPT - { - return use_currency_window(); - } -}; - -BOOST_AUTO_TEST_CASE(chaser_test__currency_window__zero__use_currency_window_false) -{ - const network::logger log{}; - node::configuration config(system::chain::selection::mainnet); - config.node.currency_window_minutes = 0; - - full_node::store store(config.database); - full_node::query query(store); - full_node node(query, config, log); - chaser_header_accessor instance(node); - BOOST_REQUIRE(!instance.use_currency_window_()); -} - -BOOST_AUTO_TEST_CASE(chaser_test__currency_window__nonzero__use_currency_window_true) -{ - const network::logger log{}; - node::configuration config(system::chain::selection::mainnet); - config.node.currency_window_minutes = 60; - - full_node::store store(config.database); - full_node::query query(store); - full_node node(query, config, log); - chaser_header_accessor instance(node); - BOOST_REQUIRE(instance.use_currency_window_()); + BOOST_REQUIRE(true); } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/chasers/chaser_header.cpp b/test/chasers/chaser_header.cpp index 8829f11f..7e16057b 100644 --- a/test/chasers/chaser_header.cpp +++ b/test/chasers/chaser_header.cpp @@ -20,9 +20,130 @@ BOOST_AUTO_TEST_SUITE(chaser_header_tests) -BOOST_AUTO_TEST_CASE(chaser_header_test) +class mock_chaser_header + : chaser_header { - BOOST_REQUIRE(true); +public: + using chaser_header::chaser_header; + + const auto& tree() NOEXCEPT + { + return tree_; + } + + const network::wall_clock::duration& currency_window() const NOEXCEPT + { + return chaser_header::currency_window(); + } + + bool use_currency_window() const NOEXCEPT + { + return chaser_header::use_currency_window(); + } + + code start() NOEXCEPT override + { + return chaser_header::start(); + } + + void handle_event(const code& ec, chase event_, + link value) NOEXCEPT override + { + return chaser_header::handle_event(ec, event_, value); + } + + bool get_branch_work(uint256_t& work, size_t& point, + system::hashes& tree_branch, header_links& store_branch, + const system::chain::header& header) const NOEXCEPT override + { + return chaser_header::get_branch_work(work, point, tree_branch, + store_branch, header); + } + + bool get_is_strong(bool& strong, const uint256_t& work, + size_t point) const NOEXCEPT override + { + return chaser_header::get_is_strong(strong, work, point); + } + + bool is_current( + const system::chain::header& header) const NOEXCEPT override + { + return chaser_header::is_current(header); + } + + void save(const system::chain::header::cptr& header, + const system::chain::context& context) NOEXCEPT override + { + return chaser_header::save(header, context); + } + + database::header_link push(const system::chain::header::cptr& header, + const system::chain::context& context) const NOEXCEPT override + { + return chaser_header::push(header, context); + } + + bool push(const system::hash_digest& key) NOEXCEPT override + { + return chaser_header::push(key); + } +}; + +BOOST_AUTO_TEST_CASE(chaser_header_test__currency_window__zero__use_currency_window_false) +{ + const network::logger log{}; + node::configuration config(system::chain::selection::mainnet); + config.node.currency_window_minutes = 0; + + full_node::store store(config.database); + full_node::query query(store); + full_node node(query, config, log); + mock_chaser_header instance(node); + BOOST_REQUIRE(!instance.use_currency_window()); +} + +BOOST_AUTO_TEST_CASE(chaser_header_test__currency_window__nonzero__use_currency_window_true) +{ + const network::logger log{}; + node::configuration config(system::chain::selection::mainnet); + config.node.currency_window_minutes = 60; + + full_node::store store(config.database); + full_node::query query(store); + full_node node(query, config, log); + mock_chaser_header instance(node); + BOOST_REQUIRE(instance.use_currency_window()); +} + +BOOST_AUTO_TEST_CASE(chaser_header_test__is_current__zero_currency_window__true) +{ + const network::logger log{}; + node::configuration config(system::chain::selection::mainnet); + config.node.currency_window_minutes = 0; + + full_node::store store(config.database); + full_node::query query(store); + full_node node(query, config, log); + mock_chaser_header instance(node); + + BOOST_REQUIRE(instance.is_current(system::chain::header{ {}, {}, {}, 0, {}, {} })); + BOOST_REQUIRE(instance.is_current(system::chain::header{ {}, {}, {}, max_uint32, {}, {} })); +} + +BOOST_AUTO_TEST_CASE(chaser_header_test__is_current__one_minute_currency_window__expected) +{ + const network::logger log{}; + node::configuration config(system::chain::selection::mainnet); + config.node.currency_window_minutes = 1; + + full_node::store store(config.database); + full_node::query query(store); + full_node node(query, config, log); + mock_chaser_header instance(node); + + BOOST_REQUIRE(!instance.is_current(system::chain::header{ {}, {}, {}, 0, {}, {} })); + BOOST_REQUIRE(instance.is_current(system::chain::header{ {}, {}, {}, max_uint32, {}, {} })); } BOOST_AUTO_TEST_SUITE_END() From 7a51ce0b00d3e9766f715f0510ec6b6c1ce19ca7 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Sun, 18 Feb 2024 09:20:06 -0500 Subject: [PATCH 05/10] Remove dead code. --- src/protocols/protocol_header_in_31800.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/protocols/protocol_header_in_31800.cpp b/src/protocols/protocol_header_in_31800.cpp index 1ec1850e..26fc79bf 100644 --- a/src/protocols/protocol_header_in_31800.cpp +++ b/src/protocols/protocol_header_in_31800.cpp @@ -51,14 +51,8 @@ void protocol_header_in_31800::start() NOEXCEPT // header sync is always CANDIDATEs. state_ = archive().get_candidate_chain_state(config().bitcoin); + BC_ASSERT_MSG(state_, "Store not initialized."); - if (!state_) - { - LOGF("protocol_header_in_31800, state not initialized."); - return; - } - - // There is one persistent common headers subscription. SUBSCRIBE_CHANNEL2(headers, handle_receive_headers, _1, _2); SEND1(create_get_headers(), handle_send, _1); protocol::start(); @@ -75,6 +69,14 @@ bool protocol_header_in_31800::handle_receive_headers(const code& ec, if (stopped(ec)) return false; + // This only stops protocol, not node. + ////if (state_) + ////{ + //// // Cannot stop from start, so handle before first use. + //// stop(node::error::store_integrity); + //// return false; + ////} + const auto& coin = config().bitcoin; LOGP("Headers (" << message->header_ptrs.size() From f673f3a47c31209ede160d805bbfd9b0c9ab245e Mon Sep 17 00:00:00 2001 From: evoskuil Date: Sun, 18 Feb 2024 09:32:08 -0500 Subject: [PATCH 06/10] Comments. --- include/bitcoin/node/chasers/chaser.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/bitcoin/node/chasers/chaser.hpp b/include/bitcoin/node/chasers/chaser.hpp index 4d372e15..e9ec3ed9 100644 --- a/include/bitcoin/node/chasers/chaser.hpp +++ b/include/bitcoin/node/chasers/chaser.hpp @@ -36,6 +36,7 @@ class full_node; /// Events are passed between chasers using the full_node shared notifier. /// Notifications are bounced from sink (e.g. chaser) to its strand, and /// notify bounces from source (e.g. chaser) to network strand. +/// Unlike protocols chasers can stop the node. class BCN_API chaser : public network::reporter { From fd97d0c0f2508ff83c088abb83ae6c89dc5d8212 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Sun, 18 Feb 2024 09:32:37 -0500 Subject: [PATCH 07/10] Remove dead code. --- src/protocols/protocol_header_in_31800.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/protocols/protocol_header_in_31800.cpp b/src/protocols/protocol_header_in_31800.cpp index 26fc79bf..a9cda270 100644 --- a/src/protocols/protocol_header_in_31800.cpp +++ b/src/protocols/protocol_header_in_31800.cpp @@ -69,14 +69,6 @@ bool protocol_header_in_31800::handle_receive_headers(const code& ec, if (stopped(ec)) return false; - // This only stops protocol, not node. - ////if (state_) - ////{ - //// // Cannot stop from start, so handle before first use. - //// stop(node::error::store_integrity); - //// return false; - ////} - const auto& coin = config().bitcoin; LOGP("Headers (" << message->header_ptrs.size() From bbc4b6d9db042b0f5a0dffad922ad38250845a9a Mon Sep 17 00:00:00 2001 From: evoskuil Date: Sun, 18 Feb 2024 11:22:16 -0500 Subject: [PATCH 08/10] Remove dead comments. --- console/executor.cpp | 4 ---- src/protocols/protocol_block_in.cpp | 4 ---- src/protocols/protocol_header_in_31800.cpp | 3 --- 3 files changed, 11 deletions(-) diff --git a/console/executor.cpp b/console/executor.cpp index 06faf540..b35bf68a 100644 --- a/console/executor.cpp +++ b/console/executor.cpp @@ -791,10 +791,6 @@ void executor::read_test() const //// state.median_time_past = ctx.mtp; //// state.timestamp = block->header().timestamp(); //// -//// // hack in bit0 late and _bit1(segwit) on schedule. -//// state.forks |= (chain::forks::bip9_bit0_group | -//// chain::forks::bip9_bit1_group); -//// //// // split from accept. //// if ((ec = block->check(state))) //// { diff --git a/src/protocols/protocol_block_in.cpp b/src/protocols/protocol_block_in.cpp index 5ae4c1a6..bdb33db3 100644 --- a/src/protocols/protocol_block_in.cpp +++ b/src/protocols/protocol_block_in.cpp @@ -269,10 +269,6 @@ bool protocol_block_in::handle_receive_block(const code& ec, ////auto& query = archive(); ////const auto context = state_->context(); - //// - ////// TODO: ensure soft forks activated in chain_state. - //////// context.forks |= (chain::forks::bip9_bit0_group | chain::forks::bip9_bit1_group); - //// ////const auto link = query.set_link(block, context); ////if (link.is_terminal()) ////{ diff --git a/src/protocols/protocol_header_in_31800.cpp b/src/protocols/protocol_header_in_31800.cpp index a9cda270..e3e71c3a 100644 --- a/src/protocols/protocol_header_in_31800.cpp +++ b/src/protocols/protocol_header_in_31800.cpp @@ -117,10 +117,7 @@ bool protocol_header_in_31800::handle_receive_headers(const code& ec, BC_POP_WARNING() auto context = state_->context(); - // TODO: ensure soft forks activated in chain_state. - //// context.forks |= (chain::forks::bip9_bit0_group | chain::forks::bip9_bit1_group); error = header.accept(context); - if (error) { LOGR("Invalid header (accept) [" << encode_hash(hash) From 65c9c7cc03216a1378749a084e6e5e33c9eee760 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Sun, 18 Feb 2024 11:24:22 -0500 Subject: [PATCH 09/10] Update activation settings for renames in system. --- src/parser.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/parser.cpp b/src/parser.cpp index 9967c627..5dc7621b 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -367,18 +367,18 @@ options_metadata parser::load_settings() THROWS ) // [version properties excluded here] ( - "bitcoin.activation_threshold", - value(&configured.bitcoin.activation_threshold), + "bitcoin.bip34_activation_threshold", + value(&configured.bitcoin.bip34_activation_threshold), "The number of new version blocks required for bip34 style soft fork activation, defaults to 750." ) ( - "bitcoin.enforcement_threshold", - value(&configured.bitcoin.enforcement_threshold), + "bitcoin.bip34_enforcement_threshold", + value(&configured.bitcoin.bip34_enforcement_threshold), "The number of new version blocks required for bip34 style soft fork enforcement, defaults to 950." ) ( - "bitcoin.activation_sample", - value(&configured.bitcoin.activation_sample), + "bitcoin.bip34_activation_sample", + value(&configured.bitcoin.bip34_activation_sample), "The number of blocks considered for bip34 style soft fork activation, defaults to 1000." ) ( From 7f41379653547593966e233b70b8d33c7602c0e7 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Sun, 18 Feb 2024 13:17:45 -0500 Subject: [PATCH 10/10] Style. --- src/chasers/chaser_header.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/chasers/chaser_header.cpp b/src/chasers/chaser_header.cpp index 8db9b899..2bcd9bba 100644 --- a/src/chasers/chaser_header.cpp +++ b/src/chasers/chaser_header.cpp @@ -42,7 +42,8 @@ chaser_header::chaser_header(full_node& node) NOEXCEPT } // protected -const network::wall_clock::duration& chaser_header::currency_window() const NOEXCEPT +const network::wall_clock::duration& +chaser_header::currency_window() const NOEXCEPT { return currency_window_; } @@ -205,7 +206,7 @@ bool chaser_header::is_current(const chain::header& header) const NOEXCEPT if (!use_currency_window()) return true; - /// BUGBUG: en.wikipedia.org/wiki/Time_formatting_and_storage_bugs#Year_2106 + // en.wikipedia.org/wiki/Time_formatting_and_storage_bugs#Year_2106 const auto time = wall_clock::from_time_t(header.timestamp()); const auto current = wall_clock::now() - currency_window(); return time >= current; @@ -224,8 +225,7 @@ bool chaser_header::get_branch_work(uint256_t& work, size_t& point, const auto& query = archive(); // Sum all branch work from tree. - for (auto it = tree_.find(*previous); - it != tree_.end(); + for (auto it = tree_.find(*previous); it != tree_.end(); it = tree_.find(*previous)) { previous = &it->second.header->previous_block_hash(); @@ -235,8 +235,7 @@ bool chaser_header::get_branch_work(uint256_t& work, size_t& point, // Sum branch work from store. database::height_link link{}; - for (link = query.to_header(*previous); - !query.is_candidate_block(link); + for (link = query.to_header(*previous); !query.is_candidate_block(link); link = query.to_parent(link)) { uint32_t bits{}; @@ -300,8 +299,7 @@ database::header_link chaser_header::push(const chain::header::cptr& header, const chain::context& context) const NOEXCEPT { auto& query = archive(); - const auto link = query.set_link(*header, - database::context + const auto link = query.set_link(*header, database::context { possible_narrow_cast(context.forks), possible_narrow_cast(context.height),