From c49683c4aec06bfd0ff8140d555b5e8cf5f1f824 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Mon, 12 Feb 2024 05:50:23 -0500 Subject: [PATCH 1/5] Stub in chain object archivers. --- include/bitcoin/node/chasers/chaser_check.hpp | 2 ++ include/bitcoin/node/chasers/chaser_header.hpp | 2 ++ include/bitcoin/node/chasers/chaser_transaction.hpp | 2 ++ src/chasers/chaser_check.cpp | 9 ++++++++- src/chasers/chaser_header.cpp | 8 +++++++- src/chasers/chaser_transaction.cpp | 9 +++++++-- 6 files changed, 28 insertions(+), 4 deletions(-) diff --git a/include/bitcoin/node/chasers/chaser_check.hpp b/include/bitcoin/node/chasers/chaser_check.hpp index ac39fa28..d614c6cc 100644 --- a/include/bitcoin/node/chasers/chaser_check.hpp +++ b/include/bitcoin/node/chasers/chaser_check.hpp @@ -37,6 +37,8 @@ class BCN_API chaser_check chaser_check(full_node& node) NOEXCEPT; + void archive(const system::chain::block::cptr& block) NOEXCEPT; + private: void handle_event(const code& ec, chase value) NOEXCEPT; void do_handle_event(const code& ec, chase value) NOEXCEPT; diff --git a/include/bitcoin/node/chasers/chaser_header.hpp b/include/bitcoin/node/chasers/chaser_header.hpp index 27b58d41..6a1e1185 100644 --- a/include/bitcoin/node/chasers/chaser_header.hpp +++ b/include/bitcoin/node/chasers/chaser_header.hpp @@ -37,6 +37,8 @@ class BCN_API chaser_header chaser_header(full_node& node) NOEXCEPT; + void archive(const system::chain::header::cptr& header) NOEXCEPT; + private: void handle_event(const code& ec, chase value) NOEXCEPT; void do_handle_event(const code& ec, chase value) NOEXCEPT; diff --git a/include/bitcoin/node/chasers/chaser_transaction.hpp b/include/bitcoin/node/chasers/chaser_transaction.hpp index 31b49019..80488cb4 100644 --- a/include/bitcoin/node/chasers/chaser_transaction.hpp +++ b/include/bitcoin/node/chasers/chaser_transaction.hpp @@ -37,6 +37,8 @@ class BCN_API chaser_transaction chaser_transaction(full_node& node) NOEXCEPT; + void archive(const system::chain::transaction::cptr& block) NOEXCEPT; + private: void handle_event(const code& ec, chase value) NOEXCEPT; void do_handle_event(const code& ec, chase value) NOEXCEPT; diff --git a/src/chasers/chaser_check.cpp b/src/chasers/chaser_check.cpp index cc52c4f4..78ac2abc 100644 --- a/src/chasers/chaser_check.cpp +++ b/src/chasers/chaser_check.cpp @@ -26,7 +26,8 @@ namespace libbitcoin { namespace node { - + +using namespace system::chain; using namespace std::placeholders; BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT) @@ -65,6 +66,12 @@ void chaser_check::do_handle_event(const code& ec, chase value) NOEXCEPT } } +void chaser_check::archive(const block::cptr& block) NOEXCEPT +{ + // Push checked block into store and issue checked event so that connect + // can connect the next blocks in order, as applicable. +} + BC_POP_WARNING() } // namespace database diff --git a/src/chasers/chaser_header.cpp b/src/chasers/chaser_header.cpp index b02efe61..1d4d3e36 100644 --- a/src/chasers/chaser_header.cpp +++ b/src/chasers/chaser_header.cpp @@ -27,6 +27,7 @@ namespace libbitcoin { namespace node { +using namespace system::chain; using namespace std::placeholders; BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT) @@ -62,7 +63,12 @@ void chaser_header::do_handle_event(const code& ec, chase value) NOEXCEPT } } -// TODO: handle new headers (may issue 'header'). +void chaser_header::archive(const header::cptr& header) NOEXCEPT +{ + // Connect and push header on a stack (simulate tree). + // When header time is current, reorg into candidate chain and then send + // header event so that check can start downloading blocks. +} BC_POP_WARNING() diff --git a/src/chasers/chaser_transaction.cpp b/src/chasers/chaser_transaction.cpp index 8f6c2de7..9a25952b 100644 --- a/src/chasers/chaser_transaction.cpp +++ b/src/chasers/chaser_transaction.cpp @@ -26,7 +26,8 @@ namespace libbitcoin { namespace node { - + +using namespace system::chain; using namespace std::placeholders; BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT) @@ -65,7 +66,11 @@ void chaser_transaction::do_handle_event(const code& ec, chase value) NOEXCEPT } } -// TODO: handle the new unconfirmed transactions (may issue 'transaction'). +void chaser_transaction::archive(const transaction::cptr& tx) NOEXCEPT +{ + // Push new checked tx into store and update DAG. Issue transaction event + // so that candidate may construct a new template. +} BC_POP_WARNING() From de57f88d2567e365d89d9823ed42d792037d40dd Mon Sep 17 00:00:00 2001 From: evoskuil Date: Tue, 13 Feb 2024 05:44:54 -0500 Subject: [PATCH 2/5] Remove vestige of libbitcoin-blockchain dependency. --- console/executor.cpp | 1 - console/localize.hpp | 1 - include/bitcoin/node.hpp | 2 +- include/bitcoin/node/configuration.hpp | 5 +++-- src/configuration.cpp | 4 ++-- src/parser.cpp | 2 +- 6 files changed, 7 insertions(+), 8 deletions(-) diff --git a/console/executor.cpp b/console/executor.cpp index 86157599..06faf540 100644 --- a/console/executor.cpp +++ b/console/executor.cpp @@ -1128,7 +1128,6 @@ bool executor::do_version() log_.stop(); console(format(BN_VERSION_MESSAGE) % LIBBITCOIN_NODE_VERSION - % LIBBITCOIN_BLOCKCHAIN_VERSION % LIBBITCOIN_DATABASE_VERSION % LIBBITCOIN_NETWORK_VERSION % LIBBITCOIN_SYSTEM_VERSION); diff --git a/console/localize.hpp b/console/localize.hpp index 2dab100c..82597a6c 100644 --- a/console/localize.hpp +++ b/console/localize.hpp @@ -173,7 +173,6 @@ namespace node { "\nVersion Information\n" \ "----------------------------\n" \ "libbitcoin-node: %1%\n" \ - "libbitcoin-blockchain: %2%\n" \ "libbitcoin-database: %3%\n" \ "libbitcoin-network: %4%\n" \ "libbitcoin-system: %5%" diff --git a/include/bitcoin/node.hpp b/include/bitcoin/node.hpp index af936f4f..81a01d08 100644 --- a/include/bitcoin/node.hpp +++ b/include/bitcoin/node.hpp @@ -14,7 +14,7 @@ * Maintainers: Do not include this header internal to this library. */ -#include +////#include #include #include #include diff --git a/include/bitcoin/node/configuration.hpp b/include/bitcoin/node/configuration.hpp index 23178e77..75a6a328 100644 --- a/include/bitcoin/node/configuration.hpp +++ b/include/bitcoin/node/configuration.hpp @@ -19,7 +19,8 @@ #ifndef LIBBITCOIN_NODE_CONFIGURATION_HPP #define LIBBITCOIN_NODE_CONFIGURATION_HPP -#include +////#include +#include #include #include #include @@ -71,7 +72,7 @@ class BCN_API configuration /// Settings. log::settings log; node::settings node; - blockchain::settings chain; + ////blockchain::settings chain; database::settings database; network::settings network; system::settings bitcoin; diff --git a/src/configuration.cpp b/src/configuration.cpp index 91e3512b..d62ae3db 100644 --- a/src/configuration.cpp +++ b/src/configuration.cpp @@ -19,7 +19,7 @@ #include #include -#include +////#include #include namespace libbitcoin { @@ -41,7 +41,7 @@ configuration::configuration(system::chain::selection context) NOEXCEPT write(false), log(context), node(context), - chain(context), + ////chain(context), database(context), network(context), bitcoin(context) diff --git a/src/parser.cpp b/src/parser.cpp index ca00b08e..f0d87541 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -20,7 +20,7 @@ #include #include -#include +////#include #include #include #include From ba972548d2c24a4b929bfea8e306b75ab42a3193 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Mon, 12 Feb 2024 15:51:16 -0500 Subject: [PATCH 3/5] Rename headers.current() to .complete(). --- .../bitcoin/node/protocols/protocol_header_in_31800.hpp | 2 +- .../bitcoin/node/protocols/protocol_header_in_70012.hpp | 4 ++-- src/protocols/protocol_header_in_31800.cpp | 8 ++++---- src/protocols/protocol_header_in_70012.cpp | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/bitcoin/node/protocols/protocol_header_in_31800.hpp b/include/bitcoin/node/protocols/protocol_header_in_31800.hpp index 463945a0..ad5dcc33 100644 --- a/include/bitcoin/node/protocols/protocol_header_in_31800.hpp +++ b/include/bitcoin/node/protocols/protocol_header_in_31800.hpp @@ -46,7 +46,7 @@ class BCN_API protocol_header_in_31800 protected: /// Invoked when initial headers sync is current. - virtual void current() NOEXCEPT; + virtual void complete() NOEXCEPT; /// Recieved incoming headers message. virtual bool handle_receive_headers(const code& ec, diff --git a/include/bitcoin/node/protocols/protocol_header_in_70012.hpp b/include/bitcoin/node/protocols/protocol_header_in_70012.hpp index 1f17a04c..3b362ddc 100644 --- a/include/bitcoin/node/protocols/protocol_header_in_70012.hpp +++ b/include/bitcoin/node/protocols/protocol_header_in_70012.hpp @@ -42,8 +42,8 @@ class BCN_API protocol_header_in_70012 } protected: - /// Invoked when initial headers sync is current. - void current() NOEXCEPT override; + /// Invoked when initial headers sync is complete. + void complete() NOEXCEPT override; private: bool sent_{}; diff --git a/src/protocols/protocol_header_in_31800.cpp b/src/protocols/protocol_header_in_31800.cpp index 95e8319c..0da465f1 100644 --- a/src/protocols/protocol_header_in_31800.cpp +++ b/src/protocols/protocol_header_in_31800.cpp @@ -166,16 +166,16 @@ bool protocol_header_in_31800::handle_receive_headers(const code& ec, } else { - // Currency assumes empty response from peer if caught up at 2000. - current(); + // Completeness assumes empty response from peer if caught up at 2000. + complete(); } return true; } // This could be the end of a catch-up sequence, or a singleton announcement. -// The distinction is ultimately arbitrary, but this signals initial currency. -void protocol_header_in_31800::current() NOEXCEPT +// The distinction is ultimately arbitrary, but this signals peer completeness. +void protocol_header_in_31800::complete() NOEXCEPT { ////reporter::fire(event_current_headers, state_->height()); LOGN("Headers from [" << authority() << "] complete at (" diff --git a/src/protocols/protocol_header_in_70012.cpp b/src/protocols/protocol_header_in_70012.cpp index 971a842e..99d3dacf 100644 --- a/src/protocols/protocol_header_in_70012.cpp +++ b/src/protocols/protocol_header_in_70012.cpp @@ -30,9 +30,9 @@ using namespace network; using namespace network::messages; using namespace std::placeholders; -void protocol_header_in_70012::current() NOEXCEPT +void protocol_header_in_70012::complete() NOEXCEPT { - protocol_header_in_31800::current(); + protocol_header_in_31800::complete(); if (!sent_) { From 7135ccb5e3d713d3a80c3a5e2a67f3c0cc21f717 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Mon, 12 Feb 2024 15:51:51 -0500 Subject: [PATCH 4/5] Add currency_window setting. --- include/bitcoin/node/settings.hpp | 2 ++ src/settings.cpp | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/include/bitcoin/node/settings.hpp b/include/bitcoin/node/settings.hpp index 5ecd6ae7..74cb6854 100644 --- a/include/bitcoin/node/settings.hpp +++ b/include/bitcoin/node/settings.hpp @@ -67,9 +67,11 @@ class BCN_API settings /// Properties. float allowed_deviation; uint16_t sample_period_seconds; + uint32_t currency_window_minutes; /// Helpers. virtual network::steady_clock::duration sample_period() const NOEXCEPT; + virtual network::wall_clock::duration currency_window() const NOEXCEPT; }; } // namespace node diff --git a/src/settings.cpp b/src/settings.cpp index 5ecb8923..a414df6d 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -63,7 +63,8 @@ namespace node { settings::settings() NOEXCEPT : allowed_deviation{ 1.0 }, - sample_period_seconds{ 5 } + sample_period_seconds{ 5 }, + currency_window_minutes{ 60 } { } @@ -77,5 +78,10 @@ network::steady_clock::duration settings::sample_period() const NOEXCEPT return network::seconds(sample_period_seconds); } +network::wall_clock::duration settings::currency_window() const NOEXCEPT +{ + return network::seconds(currency_window_minutes); +} + } // namespace node } // namespace libbitcoin From 478b79cd9eef3776d9b7967b581e15d4083dfe7c Mon Sep 17 00:00:00 2001 From: evoskuil Date: Tue, 13 Feb 2024 05:54:45 -0500 Subject: [PATCH 5/5] Add variant parameter to chaser events. --- include/bitcoin/node/chasers/chaser.hpp | 19 +++-- .../bitcoin/node/chasers/chaser_candidate.hpp | 4 +- include/bitcoin/node/chasers/chaser_check.hpp | 6 +- .../bitcoin/node/chasers/chaser_confirm.hpp | 4 +- .../bitcoin/node/chasers/chaser_connect.hpp | 4 +- .../bitcoin/node/chasers/chaser_header.hpp | 12 ++- .../node/chasers/chaser_transaction.hpp | 6 +- include/bitcoin/node/full_node.hpp | 8 ++ src/chasers/chaser.cpp | 20 +++-- src/chasers/chaser_candidate.cpp | 12 +-- src/chasers/chaser_check.cpp | 13 +-- src/chasers/chaser_confirm.cpp | 12 +-- src/chasers/chaser_connect.cpp | 12 +-- src/chasers/chaser_header.cpp | 82 ++++++++++++++++--- src/chasers/chaser_transaction.cpp | 14 ++-- src/full_node.cpp | 17 ++-- 16 files changed, 172 insertions(+), 73 deletions(-) diff --git a/include/bitcoin/node/chasers/chaser.hpp b/include/bitcoin/node/chasers/chaser.hpp index c8815e7e..c6ff92f7 100644 --- a/include/bitcoin/node/chasers/chaser.hpp +++ b/include/bitcoin/node/chasers/chaser.hpp @@ -19,6 +19,8 @@ #ifndef LIBBITCOIN_NODE_CHASERS_CHASER_HPP #define LIBBITCOIN_NODE_CHASERS_CHASER_HPP +#include +#include #include #include @@ -71,7 +73,11 @@ class BCN_API chaser stop }; - typedef network::subscriber event_subscriber; + typedef database::store store; + typedef database::query query; + + typedef std::variant link; + typedef network::subscriber event_subscriber; typedef event_subscriber::handler event_handler; DELETE_COPY_MOVE(chaser); @@ -82,8 +88,8 @@ class BCN_API chaser chaser(full_node& node) NOEXCEPT; ~chaser() NOEXCEPT; - /// Close the node. - void close(const code& ec) NOEXCEPT; + /// Thread safe synchronous archival interface. + query& archive() const NOEXCEPT; /// The chaser's strand. network::asio::strand& strand() NOEXCEPT; @@ -95,10 +101,13 @@ class BCN_API chaser code subscribe(event_handler&& handler) NOEXCEPT; /// Set chaser event (does not require network strand). - void notify(const code& ec, chase value) NOEXCEPT; + void notify(const code& ec, chase event_, link value) NOEXCEPT; + + /// Close the node. + void close(const code& ec) NOEXCEPT; private: - void do_notify(const code& ec, chase value) NOEXCEPT; + void do_notify(const code& ec, chase event_, link value) NOEXCEPT; // These are thread safe (mostly). full_node& node_; diff --git a/include/bitcoin/node/chasers/chaser_candidate.hpp b/include/bitcoin/node/chasers/chaser_candidate.hpp index 3e857e49..e5760a6c 100644 --- a/include/bitcoin/node/chasers/chaser_candidate.hpp +++ b/include/bitcoin/node/chasers/chaser_candidate.hpp @@ -38,8 +38,8 @@ class BCN_API chaser_candidate chaser_candidate(full_node& node) NOEXCEPT; private: - void handle_event(const code& ec, chase value) NOEXCEPT; - void do_handle_event(const code& ec, chase value) NOEXCEPT; + void handle_event(const code& ec, chase event_, link value) NOEXCEPT; + void do_handle_event(const code& ec, chase event_, link value) NOEXCEPT; }; } // namespace node diff --git a/include/bitcoin/node/chasers/chaser_check.hpp b/include/bitcoin/node/chasers/chaser_check.hpp index d614c6cc..59b7891c 100644 --- a/include/bitcoin/node/chasers/chaser_check.hpp +++ b/include/bitcoin/node/chasers/chaser_check.hpp @@ -37,11 +37,11 @@ class BCN_API chaser_check chaser_check(full_node& node) NOEXCEPT; - void archive(const system::chain::block::cptr& block) NOEXCEPT; + void store(const system::chain::block::cptr& block) NOEXCEPT; private: - void handle_event(const code& ec, chase value) NOEXCEPT; - void do_handle_event(const code& ec, chase value) NOEXCEPT; + void handle_event(const code& ec, chase event_, link value) NOEXCEPT; + void do_handle_event(const code& ec, chase event_, link value) NOEXCEPT; }; } // namespace node diff --git a/include/bitcoin/node/chasers/chaser_confirm.hpp b/include/bitcoin/node/chasers/chaser_confirm.hpp index 42d95e87..54a54c8e 100644 --- a/include/bitcoin/node/chasers/chaser_confirm.hpp +++ b/include/bitcoin/node/chasers/chaser_confirm.hpp @@ -38,8 +38,8 @@ class BCN_API chaser_confirm chaser_confirm(full_node& node) NOEXCEPT; private: - void handle_event(const code& ec, chase value) NOEXCEPT; - void do_handle_event(const code& ec, chase value) NOEXCEPT; + void handle_event(const code& ec, chase event_, link value) NOEXCEPT; + void do_handle_event(const code& ec, chase event_, link value) NOEXCEPT; }; } // namespace node diff --git a/include/bitcoin/node/chasers/chaser_connect.hpp b/include/bitcoin/node/chasers/chaser_connect.hpp index 8297ad8e..08d7579a 100644 --- a/include/bitcoin/node/chasers/chaser_connect.hpp +++ b/include/bitcoin/node/chasers/chaser_connect.hpp @@ -38,8 +38,8 @@ class BCN_API chaser_connect chaser_connect(full_node& node) NOEXCEPT; private: - void handle_event(const code& ec, chase value) NOEXCEPT; - void do_handle_event(const code& ec, chase value) NOEXCEPT; + void handle_event(const code& ec, chase event_, link value) NOEXCEPT; + void do_handle_event(const code& ec, chase event_, link value) NOEXCEPT; }; } // namespace node diff --git a/include/bitcoin/node/chasers/chaser_header.hpp b/include/bitcoin/node/chasers/chaser_header.hpp index 6a1e1185..02e3cd80 100644 --- a/include/bitcoin/node/chasers/chaser_header.hpp +++ b/include/bitcoin/node/chasers/chaser_header.hpp @@ -37,11 +37,17 @@ class BCN_API chaser_header chaser_header(full_node& node) NOEXCEPT; - void archive(const system::chain::header::cptr& header) NOEXCEPT; + void store(const system::chain::header::cptr& header) NOEXCEPT; private: - void handle_event(const code& ec, chase value) NOEXCEPT; - void do_handle_event(const code& ec, chase value) NOEXCEPT; + bool is_current(const system::chain::header& header) const NOEXCEPT; + bool is_strong(const system::chain::header& header) const NOEXCEPT; + void handle_event(const code& ec, chase event_, link value) NOEXCEPT; + void do_handle_event(const code& ec, chase event_, link value) NOEXCEPT; + void do_store(const system::chain::header::cptr& header) NOEXCEPT; + + const network::wall_clock::duration currency_window_; + std::vector chain_{}; }; } // namespace node diff --git a/include/bitcoin/node/chasers/chaser_transaction.hpp b/include/bitcoin/node/chasers/chaser_transaction.hpp index 80488cb4..b674b746 100644 --- a/include/bitcoin/node/chasers/chaser_transaction.hpp +++ b/include/bitcoin/node/chasers/chaser_transaction.hpp @@ -37,11 +37,11 @@ class BCN_API chaser_transaction chaser_transaction(full_node& node) NOEXCEPT; - void archive(const system::chain::transaction::cptr& block) NOEXCEPT; + void store(const system::chain::transaction::cptr& block) NOEXCEPT; private: - void handle_event(const code& ec, chase value) NOEXCEPT; - void do_handle_event(const code& ec, chase value) NOEXCEPT; + void handle_event(const code& ec, chase event_, link value) NOEXCEPT; + void do_handle_event(const code& ec, chase event_, link value) NOEXCEPT; }; } // namespace node diff --git a/include/bitcoin/node/full_node.hpp b/include/bitcoin/node/full_node.hpp index fe2a6b64..78f58f87 100644 --- a/include/bitcoin/node/full_node.hpp +++ b/include/bitcoin/node/full_node.hpp @@ -62,6 +62,9 @@ class BCN_API full_node /// Configuration settings for all libraries. const configuration& config() const NOEXCEPT; + /// Node configuration settings. + const settings& node_settings() const NOEXCEPT; + /// Thread safe synchronous archival interface. query& archive() const NOEXCEPT; @@ -69,6 +72,9 @@ class BCN_API full_node chaser::event_subscriber& event_subscriber() NOEXCEPT; protected: + + /// Chasers configuration. + /// ----------------------------------------------------------------------- virtual code create_chasers() NOEXCEPT; virtual void stop_chasers() NOEXCEPT; virtual void delete_chasers() NOEXCEPT; @@ -79,6 +85,8 @@ class BCN_API full_node network::session_inbound::ptr attach_inbound_session() NOEXCEPT override; network::session_outbound::ptr attach_outbound_session() NOEXCEPT override; + /// Virtual handlers. + /// ----------------------------------------------------------------------- void do_start(const network::result_handler& handler) NOEXCEPT override; void do_run(const network::result_handler& handler) NOEXCEPT override; void do_close() NOEXCEPT override; diff --git a/src/chasers/chaser.cpp b/src/chasers/chaser.cpp index 694af662..4e13ad39 100644 --- a/src/chasers/chaser.cpp +++ b/src/chasers/chaser.cpp @@ -43,11 +43,9 @@ chaser::~chaser() NOEXCEPT { } - -void chaser::close(const code& ec) NOEXCEPT +chaser::query& chaser::archive() const NOEXCEPT { - LOGF("Chaser fault, " << ec.message()); - node_.close(); + return node_.archive(); } asio::strand& chaser::strand() NOEXCEPT @@ -69,17 +67,23 @@ code chaser::subscribe(event_handler&& handler) NOEXCEPT } // Posts to network strand (call from chaser strands). -void chaser::notify(const code& ec, chase value) NOEXCEPT +void chaser::notify(const code& ec, chase event_, link value) NOEXCEPT { boost::asio::post(node_.strand(), - std::bind(&chaser::do_notify, this, ec, value)); + std::bind(&chaser::do_notify, this, ec, event_, value)); } // Executed on network strand (handler should bounce to chaser strand). -void chaser::do_notify(const code& ec, chase value) NOEXCEPT +void chaser::do_notify(const code& ec, chase event_, link value) NOEXCEPT { BC_ASSERT_MSG(node_.stranded(), "chaser"); - subscriber_.notify(ec, value); + subscriber_.notify(ec, event_, value); +} + +void chaser::close(const code& ec) NOEXCEPT +{ + LOGF("Chaser fault, " << ec.message()); + node_.close(); } BC_POP_WARNING() diff --git a/src/chasers/chaser_candidate.cpp b/src/chasers/chaser_candidate.cpp index bef2ea71..82c8cd5e 100644 --- a/src/chasers/chaser_candidate.cpp +++ b/src/chasers/chaser_candidate.cpp @@ -35,16 +35,18 @@ chaser_candidate::chaser_candidate(full_node& node) NOEXCEPT : chaser(node), tracker(node.log) { - subscribe(std::bind(&chaser_candidate::handle_event, this, _1, _2)); + subscribe(std::bind(&chaser_candidate::handle_event, this, _1, _2, _3)); } -void chaser_candidate::handle_event(const code& ec, chase value) NOEXCEPT +void chaser_candidate::handle_event(const code& ec, chase event_, + link value) NOEXCEPT { boost::asio::post(strand(), - std::bind(&chaser_candidate::do_handle_event, this, ec, value)); + std::bind(&chaser_candidate::do_handle_event, this, ec, event_, value)); } -void chaser_candidate::do_handle_event(const code& ec, chase value) NOEXCEPT +void chaser_candidate::do_handle_event(const code& ec, chase event_, + link) NOEXCEPT { BC_ASSERT_MSG(stranded(), "chaser_candidate"); @@ -52,7 +54,7 @@ void chaser_candidate::do_handle_event(const code& ec, chase value) NOEXCEPT if (ec) return; - switch (value) + switch (event_) { case chase::start: // TODO: initialize. diff --git a/src/chasers/chaser_check.cpp b/src/chasers/chaser_check.cpp index 78ac2abc..6aee01f7 100644 --- a/src/chasers/chaser_check.cpp +++ b/src/chasers/chaser_check.cpp @@ -36,16 +36,17 @@ chaser_check::chaser_check(full_node& node) NOEXCEPT : chaser(node), tracker(node.log) { - subscribe(std::bind(&chaser_check::handle_event, this, _1, _2)); + subscribe(std::bind(&chaser_check::handle_event, this, _1, _2, _3)); } -void chaser_check::handle_event(const code& ec, chase value) NOEXCEPT +void chaser_check::handle_event(const code& ec, chase event_, + link value) NOEXCEPT { boost::asio::post(strand(), - std::bind(&chaser_check::do_handle_event, this, ec, value)); + std::bind(&chaser_check::do_handle_event, this, ec, event_, value)); } -void chaser_check::do_handle_event(const code& ec, chase value) NOEXCEPT +void chaser_check::do_handle_event(const code& ec, chase event_, link) NOEXCEPT { BC_ASSERT_MSG(stranded(), "chaser_check"); @@ -53,7 +54,7 @@ void chaser_check::do_handle_event(const code& ec, chase value) NOEXCEPT if (ec) return; - switch (value) + switch (event_) { case chase::start: // TODO: initialize. @@ -66,7 +67,7 @@ void chaser_check::do_handle_event(const code& ec, chase value) NOEXCEPT } } -void chaser_check::archive(const block::cptr& block) NOEXCEPT +void chaser_check::store(const block::cptr&) NOEXCEPT { // Push checked block into store and issue checked event so that connect // can connect the next blocks in order, as applicable. diff --git a/src/chasers/chaser_confirm.cpp b/src/chasers/chaser_confirm.cpp index fc543e46..8be08ac1 100644 --- a/src/chasers/chaser_confirm.cpp +++ b/src/chasers/chaser_confirm.cpp @@ -35,16 +35,18 @@ chaser_confirm::chaser_confirm(full_node& node) NOEXCEPT : chaser(node), tracker(node.log) { - subscribe(std::bind(&chaser_confirm::handle_event, this, _1, _2)); + subscribe(std::bind(&chaser_confirm::handle_event, this, _1, _2, _3)); } -void chaser_confirm::handle_event(const code& ec, chase value) NOEXCEPT +void chaser_confirm::handle_event(const code& ec, chase event_, + link value) NOEXCEPT { boost::asio::post(strand(), - std::bind(&chaser_confirm::do_handle_event, this, ec, value)); + std::bind(&chaser_confirm::do_handle_event, this, ec, event_, value)); } -void chaser_confirm::do_handle_event(const code& ec, chase value) NOEXCEPT +void chaser_confirm::do_handle_event(const code& ec, chase event_, + link) NOEXCEPT { BC_ASSERT_MSG(stranded(), "chaser_confirm"); @@ -52,7 +54,7 @@ void chaser_confirm::do_handle_event(const code& ec, chase value) NOEXCEPT if (ec) return; - switch (value) + switch (event_) { case chase::start: // TODO: initialize. diff --git a/src/chasers/chaser_connect.cpp b/src/chasers/chaser_connect.cpp index c3d7c5e4..9a67b63a 100644 --- a/src/chasers/chaser_connect.cpp +++ b/src/chasers/chaser_connect.cpp @@ -35,16 +35,18 @@ chaser_connect::chaser_connect(full_node& node) NOEXCEPT : chaser(node), tracker(node.log) { - subscribe(std::bind(&chaser_connect::handle_event, this, _1, _2)); + subscribe(std::bind(&chaser_connect::handle_event, this, _1, _2, _3)); } -void chaser_connect::handle_event(const code& ec, chase value) NOEXCEPT +void chaser_connect::handle_event(const code& ec, chase event_, + link value) NOEXCEPT { boost::asio::post(strand(), - std::bind(&chaser_connect::do_handle_event, this, ec, value)); + std::bind(&chaser_connect::do_handle_event, this, ec, event_, value)); } -void chaser_connect::do_handle_event(const code& ec, chase value) NOEXCEPT +void chaser_connect::do_handle_event(const code& ec, chase event_, + link) NOEXCEPT { BC_ASSERT_MSG(stranded(), "chaser_connect"); @@ -52,7 +54,7 @@ void chaser_connect::do_handle_event(const code& ec, chase value) NOEXCEPT if (ec) return; - switch (value) + switch (event_) { case chase::start: // TODO: initialize. diff --git a/src/chasers/chaser_header.cpp b/src/chasers/chaser_header.cpp index 1d4d3e36..b26c8836 100644 --- a/src/chasers/chaser_header.cpp +++ b/src/chasers/chaser_header.cpp @@ -26,7 +26,8 @@ namespace libbitcoin { namespace node { - + +using namespace network; using namespace system::chain; using namespace std::placeholders; @@ -34,40 +35,97 @@ BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT) chaser_header::chaser_header(full_node& node) NOEXCEPT : chaser(node), + currency_window_(node.node_settings().currency_window()), tracker(node.log) { - subscribe(std::bind(&chaser_header::handle_event, this, _1, _2)); + subscribe(std::bind(&chaser_header::handle_event, this, _1, _2, _3)); } -void chaser_header::handle_event(const code& ec, chase value) NOEXCEPT +// private +void chaser_header::handle_event(const code& ec, chase event_, + link value) NOEXCEPT { boost::asio::post(strand(), - std::bind(&chaser_header::do_handle_event, this, ec, value)); + std::bind(&chaser_header::do_handle_event, this, ec, event_, value)); } -void chaser_header::do_handle_event(const code& ec, chase value) NOEXCEPT +// private +void chaser_header::do_handle_event(const code& ec, chase event_, link) NOEXCEPT { BC_ASSERT_MSG(stranded(), "chaser_header"); - // The code should be error::service_stopped when error::stop is set. if (ec) return; - switch (value) + switch (event_) { case chase::start: - // TODO: initialize. + // TODO: initialize header tree from store. break; default: return; } } -void chaser_header::archive(const header::cptr& header) NOEXCEPT +// private +bool chaser_header::is_current(const header& header) const NOEXCEPT +{ + const auto time = wall_clock::from_time_t(header.timestamp()); + const auto current = wall_clock::now() - currency_window_; + return time >= current; +} + +// private +// **************************************************************************** +// CONSENSUS: tree branch with greater work causes candidate re/organization. +// Chasers eventually re/organize candidate branch into confirmed if valid. +// **************************************************************************** +bool chaser_header::is_strong(const header& header) const NOEXCEPT +{ + BC_ASSERT_MSG(stranded(), "chaser_header"); + + // TODO: Compute branch proof above branch point. + const uint256_t branch = header.proof(); + + // TODO: Compute candidate proof above branch point to strong. + // If candidate proof ever exceeds branch proof then return false. + // This is a short-circuiting optimization to minimize store reads. + // Since this strand is the only place where the candidate chain changes + // the strong computation here is protected by the strand. + const uint256_t candidate{}; + + // TODO: Each new header is currently strong (assumes no branching). + return branch > candidate; +} + +void chaser_header::store(const header::cptr& header) NOEXCEPT { - // Connect and push header on a stack (simulate tree). - // When header time is current, reorg into candidate chain and then send - // header event so that check can start downloading blocks. + // Full accept performed in protocol (for concurrency). + boost::asio::post(strand(), + std::bind(&chaser_header::do_store, this, header)); +} + +// private +void chaser_header::do_store(const header::cptr& header) NOEXCEPT +{ + BC_ASSERT_MSG(stranded(), "chaser_header"); + + // If false we assume the parent is deeper on the stack, since protocol + // connected, and therefore this header is as well (assumes linear). + if (!chain_.empty() && chain_.back()->hash() == + header->previous_block_hash()) + { + chain_.push_back(header); + + if (is_current(*header) && is_strong(*header)) + { + // TODO: reorganize current branch into the candidate chain. + // TODO: store and pop tree branch (chain_). + chain_.clear(); + + notify(error::success, chase::checked, { 42_i32 }); + } + } } BC_POP_WARNING() diff --git a/src/chasers/chaser_transaction.cpp b/src/chasers/chaser_transaction.cpp index 9a25952b..ac518384 100644 --- a/src/chasers/chaser_transaction.cpp +++ b/src/chasers/chaser_transaction.cpp @@ -36,16 +36,18 @@ chaser_transaction::chaser_transaction(full_node& node) NOEXCEPT : chaser(node), tracker(node.log) { - subscribe(std::bind(&chaser_transaction::handle_event, this, _1, _2)); + subscribe(std::bind(&chaser_transaction::handle_event, this, _1, _2, _3)); } -void chaser_transaction::handle_event(const code& ec, chase value) NOEXCEPT +void chaser_transaction::handle_event(const code& ec, chase event_, + link value) NOEXCEPT { boost::asio::post(strand(), - std::bind(&chaser_transaction::do_handle_event, this, ec, value)); + std::bind(&chaser_transaction::do_handle_event, this, ec, event_, value)); } -void chaser_transaction::do_handle_event(const code& ec, chase value) NOEXCEPT +void chaser_transaction::do_handle_event(const code& ec, chase event_, + link) NOEXCEPT { BC_ASSERT_MSG(stranded(), "chaser_transaction"); @@ -53,7 +55,7 @@ void chaser_transaction::do_handle_event(const code& ec, chase value) NOEXCEPT if (ec) return; - switch (value) + switch (event_) { case chase::start: // TODO: initialize. @@ -66,7 +68,7 @@ void chaser_transaction::do_handle_event(const code& ec, chase value) NOEXCEPT } } -void chaser_transaction::archive(const transaction::cptr& tx) NOEXCEPT +void chaser_transaction::store(const transaction::cptr&) NOEXCEPT { // Push new checked tx into store and update DAG. Issue transaction event // so that candidate may construct a new template. diff --git a/src/full_node.cpp b/src/full_node.cpp index 495827ed..940fda8a 100644 --- a/src/full_node.cpp +++ b/src/full_node.cpp @@ -125,7 +125,7 @@ code full_node::create_chasers() NOEXCEPT chaser_candidate_ = std::make_unique(*this); // Post start event to all chasers. - event_subscriber_.notify(error::success, chaser::chase::start); + event_subscriber_.notify(error::success, chaser::chase::start, {}); return error::success; } @@ -134,7 +134,7 @@ void full_node::stop_chasers() NOEXCEPT BC_ASSERT_MSG(stranded(), "full_node"); event_subscriber_.stop(network::error::service_stopped, - chaser::chase::stop); + chaser::chase::stop, {}); } // These should be reset upon destruct, which could only follow close(), which @@ -153,20 +153,25 @@ void full_node::delete_chasers() NOEXCEPT // Properties. // ---------------------------------------------------------------------------- +const settings& full_node::node_settings() const NOEXCEPT +{ + return config().node; +} + full_node::query& full_node::archive() const NOEXCEPT { return query_; } -const configuration& full_node::config() const NOEXCEPT +chaser::event_subscriber& full_node::event_subscriber() NOEXCEPT { - return config_; + return event_subscriber_; } // protected -chaser::event_subscriber& full_node::event_subscriber() NOEXCEPT +const configuration& full_node::config() const NOEXCEPT { - return event_subscriber_; + return config_; } // Session attachments.