From 44ca9fccb8b1c4ca6bd7f91aa0ad80d2b2e26e7a Mon Sep 17 00:00:00 2001 From: evoskuil Date: Wed, 6 Mar 2024 21:39:49 -0500 Subject: [PATCH] Update event flow, style. --- include/bitcoin/node/chasers/chaser.hpp | 16 ++++++++++---- include/bitcoin/node/chasers/chaser_block.hpp | 4 ++-- include/bitcoin/node/chasers/chaser_check.hpp | 2 +- .../bitcoin/node/chasers/chaser_header.hpp | 2 +- .../protocols/protocol_block_in_31800.hpp | 2 +- src/chasers/chaser_block.cpp | 22 ++++++++++--------- src/chasers/chaser_candidate.cpp | 1 + src/chasers/chaser_check.cpp | 13 ++++++----- src/chasers/chaser_confirm.cpp | 2 +- src/chasers/chaser_connect.cpp | 4 ++-- src/chasers/chaser_header.cpp | 12 +++++----- src/protocols/protocol_block_in_31800.cpp | 9 ++++---- 12 files changed, 53 insertions(+), 36 deletions(-) diff --git a/include/bitcoin/node/chasers/chaser.hpp b/include/bitcoin/node/chasers/chaser.hpp index 5935a219..0bccf8fd 100644 --- a/include/bitcoin/node/chasers/chaser.hpp +++ b/include/bitcoin/node/chasers/chaser.hpp @@ -56,31 +56,38 @@ class BCN_API chaser /// A new strong branch exists (strong height_t). /// Issued by 'header' and handled by 'check'. /// The block chaser works with the header-first protocol. - header, + strong, - /// New unassociated blocks exist in the strong branch. - unassociated, + /// New headers without associated txs exist as strong (header_t). + /// Issued by 'check' once hashes queued and handled by 'checked'. + header, /// A block has been downloaded, checked and stored (header_t). /// Issued by 'check' and handled by 'connect'. checked, + + /// A downloaded block has failed check. unchecked, /// A branch has been connected (header_t|height_t). /// Issued by 'connect' and handled by 'confirm'. connected, + + /// A checked block has failed connect. unconnected, /// A branch has been confirmed (fork header_t|height_t). /// Issued by 'confirm' and handled by 'transaction'. confirmed, + + /// A connected block has failed confirm. unconfirmed, /// A new transaction has been added to the pool (transaction_t). /// Issued by 'transaction' and handled by 'candidate'. transaction, - /// A new candidate block has been created (?). + /// A new candidate block (template) has been created. /// Issued by 'candidate' and handled by miners. candidate, @@ -92,6 +99,7 @@ class BCN_API chaser using header_t = database::header_link::integer; using transaction_t = database::tx_link::integer; using flags_t = database::context::flag::integer; + using count_t = size_t; typedef std::function organize_handler; typedef std::variant link; diff --git a/include/bitcoin/node/chasers/chaser_block.hpp b/include/bitcoin/node/chasers/chaser_block.hpp index cf345ecb..5179310f 100644 --- a/include/bitcoin/node/chasers/chaser_block.hpp +++ b/include/bitcoin/node/chasers/chaser_block.hpp @@ -87,12 +87,12 @@ class BCN_API chaser_block const system::chain::chain_state::ptr& state) NOEXCEPT; /// Store block to database and push to top of candidate chain. - virtual database::header_link push( + virtual database::header_link push_block( const system::chain::block::cptr& block, const system::chain::context& context) const NOEXCEPT; /// Move tree header to database and push to top of candidate chain. - virtual bool push(const system::hash_digest& key) NOEXCEPT; + virtual bool push_block(const system::hash_digest& key) NOEXCEPT; /// Populate block prevouts and metadata from block tree. virtual void populate(const system::chain::block& block) const NOEXCEPT; diff --git a/include/bitcoin/node/chasers/chaser_check.hpp b/include/bitcoin/node/chasers/chaser_check.hpp index f09c3b0c..94afb144 100644 --- a/include/bitcoin/node/chasers/chaser_check.hpp +++ b/include/bitcoin/node/chasers/chaser_check.hpp @@ -51,7 +51,7 @@ class BCN_API chaser_check protected: virtual void handle_put_hashes(const code&) NOEXCEPT; - virtual void handle_header(height_t branch_point) NOEXCEPT; + virtual void handle_strong(height_t branch_point) NOEXCEPT; virtual void handle_event(const code& ec, chase event_, link value) NOEXCEPT; diff --git a/include/bitcoin/node/chasers/chaser_header.hpp b/include/bitcoin/node/chasers/chaser_header.hpp index babc46bd..39e4908a 100644 --- a/include/bitcoin/node/chasers/chaser_header.hpp +++ b/include/bitcoin/node/chasers/chaser_header.hpp @@ -90,7 +90,7 @@ class BCN_API chaser_header const system::chain::chain_state::ptr& state) NOEXCEPT; /// Store header to database and push to top of candidate chain. - virtual database::header_link push( + virtual database::header_link push_header( const system::chain::header::cptr& header, const system::chain::context& context) const NOEXCEPT; diff --git a/include/bitcoin/node/protocols/protocol_block_in_31800.hpp b/include/bitcoin/node/protocols/protocol_block_in_31800.hpp index 427c5fe3..e0f17301 100644 --- a/include/bitcoin/node/protocols/protocol_block_in_31800.hpp +++ b/include/bitcoin/node/protocols/protocol_block_in_31800.hpp @@ -74,7 +74,7 @@ class BCN_API protocol_block_in_31800 /// Handle result of performance reporting. virtual void handle_performance(const code& ec) NOEXCEPT; - virtual void handle_unassociated(chaser::header_t block) NOEXCEPT; + virtual void handle_header(chaser::count_t count) NOEXCEPT; virtual void handle_event(const code& ec, chaser::chase event_, chaser::link value) NOEXCEPT; diff --git a/src/chasers/chaser_block.cpp b/src/chasers/chaser_block.cpp index 730336cc..aadf5334 100644 --- a/src/chasers/chaser_block.cpp +++ b/src/chasers/chaser_block.cpp @@ -70,7 +70,7 @@ code chaser_block::start() NOEXCEPT void chaser_block::handle_event(const code&, chase event_, link value) NOEXCEPT { - if (event_ == chase::unconnected) + if (event_ == chase::unconfirmed) { POST(handle_unconnected, std::get(value)); } @@ -117,10 +117,10 @@ void chaser_block::do_organize(const block::cptr& block_ptr, } // If header exists test for prior invalidity as a block. - const auto id = query.to_header(hash); - if (!id.is_terminal()) + const auto link = query.to_header(hash); + if (!link.is_terminal()) { - const auto ec = query.get_block_state(id); + const auto ec = query.get_block_state(link); if (ec == database::error::block_unconfirmable) { handler(ec, {}); @@ -255,9 +255,9 @@ void chaser_block::do_organize(const block::cptr& block_ptr, } // Push stored strong block headers to candidate chain. - for (const auto& link: views_reverse(store_branch)) + for (const auto& id: views_reverse(store_branch)) { - if (!query.push_candidate(link)) + if (!query.push_candidate(id)) { handler(error::store_integrity, height); return; @@ -267,7 +267,7 @@ void chaser_block::do_organize(const block::cptr& block_ptr, // Store strong tree blocks and push headers to candidate chain. for (const auto& key: views_reverse(tree_branch)) { - if (!push(key)) + if (!push_block(key)) { handler(error::store_integrity, height); return; @@ -275,12 +275,14 @@ void chaser_block::do_organize(const block::cptr& block_ptr, } // Push new block as top of candidate chain. - if (push(block_ptr, state->context()).is_terminal()) + if (push_block(block_ptr, state->context()).is_terminal()) { handler(error::store_integrity, height); return; } + // ------------------------------------------------------------------------ + top_state_ = state; const auto branch_point = possible_narrow_cast(point); notify(error::success, chase::block, { branch_point }); @@ -380,7 +382,7 @@ void chaser_block::cache(const block::cptr& block, tree_.insert({ block->hash(), { block, state } }); } -database::header_link chaser_block::push(const block::cptr& block, +database::header_link chaser_block::push_block(const block::cptr& block, const context& context) const NOEXCEPT { auto& query = archive(); @@ -394,7 +396,7 @@ database::header_link chaser_block::push(const block::cptr& block, return query.push_candidate(link) ? link : database::header_link{}; } -bool chaser_block::push(const hash_digest& key) NOEXCEPT +bool chaser_block::push_block(const hash_digest& key) NOEXCEPT { const auto value = tree_.extract(key); BC_ASSERT_MSG(!value.empty(), "missing tree value"); diff --git a/src/chasers/chaser_candidate.cpp b/src/chasers/chaser_candidate.cpp index fa5a215b..01b42fbf 100644 --- a/src/chasers/chaser_candidate.cpp +++ b/src/chasers/chaser_candidate.cpp @@ -60,6 +60,7 @@ code chaser_candidate::start() NOEXCEPT void chaser_candidate::handle_event(const code&, chase event_, link value) NOEXCEPT { + // TODO: also handle confirmed/unconfirmed. if (event_ == chase::transaction) { POST(handle_transaction, std::get(value)); diff --git a/src/chasers/chaser_check.cpp b/src/chasers/chaser_check.cpp index 40b81fca..b4e08f62 100644 --- a/src/chasers/chaser_check.cpp +++ b/src/chasers/chaser_check.cpp @@ -73,15 +73,15 @@ code chaser_check::start() NOEXCEPT void chaser_check::handle_event(const code&, chase event_, link value) NOEXCEPT { - if (event_ == chase::header) + if (event_ == chase::strong) { BC_ASSERT(std::holds_alternative(value)); - handle_header(std::get(value)); + handle_strong(std::get(value)); } } // Stale branches are just be allowed to complete (still downloaded). -void chaser_check::handle_header(height_t branch_point) NOEXCEPT +void chaser_check::handle_strong(height_t branch_point) NOEXCEPT { const auto map = std::make_shared( archive().get_all_unassociated_above(branch_point)); @@ -137,8 +137,6 @@ void chaser_check::do_get_hashes(const handler& handler) NOEXCEPT handler(error::success, map); } -// TODO: post event causing channels to get some? -// TODO: otherwise completed channels remain idle until header event. void chaser_check::do_put_hashes(const map_ptr& map, const network::result_handler& handler) NOEXCEPT { @@ -146,6 +144,11 @@ void chaser_check::do_put_hashes(const map_ptr& map, /// Merge "moves" elements from one table to another. map_table_.at(0)->merge(*map); + + const auto count = map_table_.at(0)->size(); + if (!is_zero(count)) + notify(error::success, chase::header, count); + handler(error::success); } diff --git a/src/chasers/chaser_confirm.cpp b/src/chasers/chaser_confirm.cpp index db3afe56..7e3b0191 100644 --- a/src/chasers/chaser_confirm.cpp +++ b/src/chasers/chaser_confirm.cpp @@ -64,7 +64,7 @@ void chaser_confirm::handle_event(const code&, chase event_, } } -// TODO: handle new strong connected branch (may issue 'confirmed'). +// TODO: handle new strong connected branch (may issue 'confirmed'/'unconfirmed'). void chaser_confirm::handle_connected(header_t) NOEXCEPT { BC_ASSERT(stranded()); diff --git a/src/chasers/chaser_connect.cpp b/src/chasers/chaser_connect.cpp index 2a7a9e27..4ff1a1e2 100644 --- a/src/chasers/chaser_connect.cpp +++ b/src/chasers/chaser_connect.cpp @@ -58,13 +58,13 @@ code chaser_connect::start() NOEXCEPT void chaser_connect::handle_event(const code&, chase event_, link value) NOEXCEPT { - if (event_ == chase::connected) + if (event_ == chase::checked) { POST(handle_checked, std::get(value)); } } -// TODO: handle the new checked blocks (may issue 'connected'). +// TODO: handle the new checked blocks (may issue 'connected'/'unconnected'). void chaser_connect::handle_checked(header_t) NOEXCEPT { BC_ASSERT(stranded()); diff --git a/src/chasers/chaser_header.cpp b/src/chasers/chaser_header.cpp index 0e9b6ab7..7d158eb1 100644 --- a/src/chasers/chaser_header.cpp +++ b/src/chasers/chaser_header.cpp @@ -82,7 +82,9 @@ void chaser_header::handle_event(const code&, chase event_, link value) NOEXCEPT { // Posted due to block/header invalidation. - if (event_ == chase::unchecked) + if (event_ == chase::unchecked || + event_ == chase::unconnected || + event_ == chase::unconfirmed) { POST(handle_unchecked, std::get(value)); } @@ -224,7 +226,7 @@ void chaser_header::do_organize(const header::cptr& header_ptr, return; } - // Reorganize candidate header chain. + // Reorganize candidate chain. // ------------------------------------------------------------------------ auto top = top_state_->height(); @@ -265,7 +267,7 @@ void chaser_header::do_organize(const header::cptr& header_ptr, } // Push new header as top of candidate chain. - if (push(header_ptr, state->context()).is_terminal()) + if (push_header(header_ptr, state->context()).is_terminal()) { handler(error::store_integrity, height); return; @@ -275,7 +277,7 @@ void chaser_header::do_organize(const header::cptr& header_ptr, top_state_ = state; const auto branch_point = possible_narrow_cast(point); - notify(error::success, chase::header, { branch_point }); + notify(error::success, chase::strong, { branch_point }); handler(error::success, height); } @@ -383,7 +385,7 @@ void chaser_header::cache(const header::cptr& header, tree_.insert({ header->hash(), { header, state } }); } -database::header_link chaser_header::push(const header::cptr& header, +database::header_link chaser_header::push_header(const header::cptr& header, const context& context) const NOEXCEPT { auto& query = archive(); diff --git a/src/protocols/protocol_block_in_31800.cpp b/src/protocols/protocol_block_in_31800.cpp index b32a21af..45e0e3de 100644 --- a/src/protocols/protocol_block_in_31800.cpp +++ b/src/protocols/protocol_block_in_31800.cpp @@ -146,14 +146,15 @@ void protocol_block_in_31800::start() NOEXCEPT void protocol_block_in_31800::handle_event(const code&, chaser::chase event_, chaser::link value) NOEXCEPT { - if (event_ == chaser::chase::unassociated) + // There are count blocks to download at/above the given header. + if (event_ == chaser::chase::header) { - BC_ASSERT(std::holds_alternative(value)); - POST(handle_unassociated, std::get(value)); + BC_ASSERT(std::holds_alternative(value)); + POST(handle_header, std::get(value)); } } -void protocol_block_in_31800::handle_unassociated(chaser::header_t) NOEXCEPT +void protocol_block_in_31800::handle_header(chaser::count_t) NOEXCEPT { BC_ASSERT(stranded());