From 712c04cd07ce29e88f1af78c1860510d3010ec5e Mon Sep 17 00:00:00 2001 From: evoskuil Date: Wed, 21 Feb 2024 16:58:00 -0500 Subject: [PATCH] Pass result handler to organize methods. --- include/bitcoin/node/chasers/chaser.hpp | 7 +- include/bitcoin/node/chasers/chaser_block.hpp | 8 +- .../bitcoin/node/chasers/chaser_header.hpp | 8 +- include/bitcoin/node/full_node.hpp | 13 +++- include/bitcoin/node/protocols/protocol.hpp | 13 +++- .../protocols/protocol_header_in_31800.hpp | 6 +- include/bitcoin/node/sessions/session.hpp | 10 ++- src/chasers/chaser.cpp | 14 ++-- src/chasers/chaser_block.cpp | 78 ++++++++++--------- src/chasers/chaser_check.cpp | 5 +- src/chasers/chaser_connect.cpp | 4 +- src/chasers/chaser_header.cpp | 55 +++++++------ src/full_node.cpp | 15 +++- src/protocols/protocol.cpp | 18 ++++- src/protocols/protocol_block_in.cpp | 4 +- src/protocols/protocol_block_in_31800.cpp | 2 +- src/protocols/protocol_header_in_31800.cpp | 2 +- src/sessions/session.cpp | 10 ++- 18 files changed, 158 insertions(+), 114 deletions(-) diff --git a/include/bitcoin/node/chasers/chaser.hpp b/include/bitcoin/node/chasers/chaser.hpp index 03a23f6e..07f9a1c0 100644 --- a/include/bitcoin/node/chasers/chaser.hpp +++ b/include/bitcoin/node/chasers/chaser.hpp @@ -99,6 +99,9 @@ class BCN_API chaser chaser(full_node& node) NOEXCEPT; ~chaser() NOEXCEPT; + /// Node is closed. + bool closed() const NOEXCEPT; + /// Node configuration settings. const node::configuration& config() const NOEXCEPT; @@ -120,15 +123,11 @@ class BCN_API chaser /// Set chaser event (does not require network strand). void notify(const code& ec, chase event_, link value) NOEXCEPT; - /// Close the node in case of failure. - void stop(const code& ec) NOEXCEPT; - private: void do_notify(const code& ec, chase event_, link value) NOEXCEPT; // These are thread safe (mostly). full_node& node_; - const node::configuration& config_; network::asio::strand strand_; // This is protected by the network strand. diff --git a/include/bitcoin/node/chasers/chaser_block.hpp b/include/bitcoin/node/chasers/chaser_block.hpp index 424fe2b8..fdad7bf3 100644 --- a/include/bitcoin/node/chasers/chaser_block.hpp +++ b/include/bitcoin/node/chasers/chaser_block.hpp @@ -45,9 +45,8 @@ class BCN_API chaser_block virtual code start() NOEXCEPT; /// Validate and organize next block in sequence relative to caller peer. - /// Causes a fault/stop if preceding blocks have not been stored. - virtual void organize( - const system::chain::block::cptr& block_ptr) NOEXCEPT; + virtual void organize(const system::chain::block::cptr& block_ptr, + network::result_handler&& handler) NOEXCEPT; protected: struct validated_block @@ -99,7 +98,8 @@ class BCN_API chaser_block private: void do_handle_event(const code& ec, chase event_, link value) NOEXCEPT; - void do_organize(const system::chain::block::cptr& block) NOEXCEPT; + void do_organize(const system::chain::block::cptr& block, + const network::result_handler& handler) NOEXCEPT; // These are thread safe. const system::chain::checkpoints& checkpoints_; diff --git a/include/bitcoin/node/chasers/chaser_header.hpp b/include/bitcoin/node/chasers/chaser_header.hpp index 132767ac..b225386d 100644 --- a/include/bitcoin/node/chasers/chaser_header.hpp +++ b/include/bitcoin/node/chasers/chaser_header.hpp @@ -46,9 +46,8 @@ class BCN_API chaser_header virtual code start() NOEXCEPT; /// Validate and organize next header in sequence relative to caller peer. - /// Causes a fault/stop if preceding headers have not been stored. - virtual void organize( - const system::chain::header::cptr& header_ptr) NOEXCEPT; + virtual void organize(const system::chain::header::cptr& header_ptr, + network::result_handler&& handler) NOEXCEPT; protected: struct proposed_header @@ -99,7 +98,8 @@ class BCN_API chaser_header private: void do_handle_event(const code& ec, chase event_, link value) NOEXCEPT; - void do_organize(const system::chain::header::cptr& header) NOEXCEPT; + void do_organize(const system::chain::header::cptr& header, + const network::result_handler& handler) NOEXCEPT; // These are thread safe. const system::chain::checkpoints& checkpoints_; diff --git a/include/bitcoin/node/full_node.hpp b/include/bitcoin/node/full_node.hpp index 69f3ac59..fcaa6725 100644 --- a/include/bitcoin/node/full_node.hpp +++ b/include/bitcoin/node/full_node.hpp @@ -58,14 +58,19 @@ class BCN_API full_node /// Close the node. void close() NOEXCEPT override; + /// The node is closed. + bool closed() const NOEXCEPT override; + /// Chasers. /// ----------------------------------------------------------------------- - /// Organize a validated header, failures stop the node. - virtual void organize(const system::chain::header::cptr& header) NOEXCEPT; + /// Organize a validated header. + virtual void organize(const system::chain::header::cptr& header, + network::result_handler&& handler) NOEXCEPT; - /// Organize a validated block, failures stop the node. - virtual void organize(const system::chain::block::cptr& block) NOEXCEPT; + /// Organize a validated block. + virtual void organize(const system::chain::block::cptr& block, + network::result_handler&& handler) NOEXCEPT; /// Properties. /// ----------------------------------------------------------------------- diff --git a/include/bitcoin/node/protocols/protocol.hpp b/include/bitcoin/node/protocols/protocol.hpp index ce7cf4af..eae5027a 100644 --- a/include/bitcoin/node/protocols/protocol.hpp +++ b/include/bitcoin/node/protocols/protocol.hpp @@ -53,11 +53,16 @@ class BCN_API protocol virtual void performance(uint64_t channel, uint64_t speed, network::result_handler&& handler) const NOEXCEPT; - /// Organize a validated header, failures stop the node. - virtual void organize(const system::chain::header::cptr& header) NOEXCEPT; + /// Organize a validated header. + virtual void organize(const system::chain::header::cptr& header, + network::result_handler&& handler) NOEXCEPT; - /// Organize a validated block, failures stop the node. - virtual void organize(const system::chain::block::cptr& block) NOEXCEPT; + /// Organize a validated block. + virtual void organize(const system::chain::block::cptr& block, + network::result_handler&& handler) NOEXCEPT; + + /// Handle organize result. + virtual void handle_organize(const code& ec) NOEXCEPT; /// Configuration settings for all libraries. const configuration& config() const NOEXCEPT; diff --git a/include/bitcoin/node/protocols/protocol_header_in_31800.hpp b/include/bitcoin/node/protocols/protocol_header_in_31800.hpp index 1fd37995..c671bfbc 100644 --- a/include/bitcoin/node/protocols/protocol_header_in_31800.hpp +++ b/include/bitcoin/node/protocols/protocol_header_in_31800.hpp @@ -45,13 +45,13 @@ class BCN_API protocol_header_in_31800 void start() NOEXCEPT override; protected: - /// Invoked when initial headers sync is complete. - virtual void complete() NOEXCEPT; - /// Recieved incoming headers message. virtual bool handle_receive_headers(const code& ec, const network::messages::headers::cptr& message) NOEXCEPT; + /// Invoked when initial headers sync is complete. + virtual void complete() NOEXCEPT; + private: network::messages::get_headers create_get_headers() NOEXCEPT; network::messages::get_headers create_get_headers( diff --git a/include/bitcoin/node/sessions/session.hpp b/include/bitcoin/node/sessions/session.hpp index 55d76141..2d468b46 100644 --- a/include/bitcoin/node/sessions/session.hpp +++ b/include/bitcoin/node/sessions/session.hpp @@ -36,11 +36,13 @@ class BCN_API session virtual void performance(uint64_t channel, uint64_t speed, network::result_handler&& handler) NOEXCEPT; - /// Organize a validated header, failures stop the node. - virtual void organize(const system::chain::header::cptr& header) NOEXCEPT; + /// Organize a validated header. + virtual void organize(const system::chain::header::cptr& header, + network::result_handler&& handler) NOEXCEPT; - /// Organize a validated block, failures stop the node. - virtual void organize(const system::chain::block::cptr& block) NOEXCEPT; + /// Organize a validated block. + virtual void organize(const system::chain::block::cptr& block, + network::result_handler&& handler) NOEXCEPT; /// Configuration settings for all libraries. const configuration& config() const NOEXCEPT; diff --git a/src/chasers/chaser.cpp b/src/chasers/chaser.cpp index 761e205b..b4174f96 100644 --- a/src/chasers/chaser.cpp +++ b/src/chasers/chaser.cpp @@ -34,7 +34,6 @@ BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT) chaser::chaser(full_node& node) NOEXCEPT : node_(node), - config_(node.config()), strand_(node.service().get_executor()), subscriber_(node.event_subscriber()), reporter(node.log) @@ -45,9 +44,14 @@ chaser::~chaser() NOEXCEPT { } +bool chaser::closed() const NOEXCEPT +{ + return node_.closed(); +} + const node::configuration& chaser::config() const NOEXCEPT { - return config_; + return node_.config(); } chaser::query& chaser::archive() const NOEXCEPT @@ -90,12 +94,6 @@ void chaser::do_notify(const code& ec, chase event_, link value) NOEXCEPT subscriber_.notify(ec, event_, value); } -void chaser::stop(const code& ec) NOEXCEPT -{ - LOGF("Chaser fault, " << ec.message()); - node_.close(); -} - BC_POP_WARNING() } // namespace database diff --git a/src/chasers/chaser_block.cpp b/src/chasers/chaser_block.cpp index aa923219..e5ace80e 100644 --- a/src/chasers/chaser_block.cpp +++ b/src/chasers/chaser_block.cpp @@ -87,15 +87,18 @@ void chaser_block::do_handle_event(const code&, chase, link) NOEXCEPT BC_ASSERT_MSG(stranded(), "chaser_block"); } -void chaser_block::organize(const chain::block::cptr& block) NOEXCEPT +void chaser_block::organize(const chain::block::cptr& block, + result_handler&& handler) NOEXCEPT { boost::asio::post(strand(), std::bind(&chaser_block::do_organize, - this, block)); + this, block, std::move(handler))); } // private -void chaser_block::do_organize(const chain::block::cptr& block_ptr) NOEXCEPT +// Caller may capture block_ptr in handler closure for detailed logging. +void chaser_block::do_organize(const chain::block::cptr& block_ptr, + const result_handler& handler) NOEXCEPT { BC_ASSERT_MSG(stranded(), "chaser_block"); @@ -109,14 +112,25 @@ void chaser_block::do_organize(const chain::block::cptr& block_ptr) NOEXCEPT // Skip existing, fail orphan. // ------------------------------------------------------------------------ + if (closed()) + { + handler(network::error::service_stopped); + return; + } + // Block (header and txs) already exists. if (tree_.contains(hash) || query.is_block(hash)) + { + handler(error::success); return; + } // Peer processing should have precluded orphan submission. + // Results from running headers-first and then restarting to blocks-first. if (!tree_.contains(previous) && !query.is_block(previous)) { - stop(error::orphan_block); + LOGR("Orphan header [" << encode_hash(hash) << "]."); + handler(error::orphan_block); return; } @@ -132,10 +146,8 @@ void chaser_block::do_organize(const chain::block::cptr& block_ptr) NOEXCEPT if (chain::checkpoint::is_conflict(coin.checkpoints, hash, state_->height())) { - ////LOGR("Invalid block (checkpoint) [" << encode_hash(hash) - //// << "] from [" << authority() << "]."); - ////stop(network::error::protocol_violation); - ////return false; + handler(network::error::protocol_violation); + return; }; // Block validations are bypassed when under checkpoint/milestone. @@ -144,19 +156,15 @@ void chaser_block::do_organize(const chain::block::cptr& block_ptr) NOEXCEPT auto error = block.check(); if (error) { - ////LOGR("Invalid block (check) [" << encode_hash(hash) - //// << "] from [" << authority() << "] " << error.message()); - ////stop(network::error::protocol_violation); - ////return false; + handler(network::error::protocol_violation); + return; } error = block.check(context); if (error) { - ////LOGR("Invalid block (check(context)) [" << encode_hash(hash) - //// << "] from [" << authority() << "] " << error.message()); - ////stop(network::error::protocol_violation); - ////return false; + handler(network::error::protocol_violation); + return; } // Populate prevouts only, internal to block. @@ -175,10 +183,8 @@ void chaser_block::do_organize(const chain::block::cptr& block_ptr) NOEXCEPT // ******************************************************************** if (!query.populate(block)) { - ////LOGR("Invalid block (populate) [" << encode_hash(hash) - //// << "] from [" << authority() << "]."); - ////stop(network::error::protocol_violation); - ////return false; + handler(network::error::protocol_violation); + return; } // TODO: also requires input metadata population. @@ -186,20 +192,16 @@ void chaser_block::do_organize(const chain::block::cptr& block_ptr) NOEXCEPT coin.initial_subsidy()); if (error) { - ////LOGR("Invalid block (accept) [" << encode_hash(hash) - //// << "] from [" << authority() << "] " << error.message()); - ////stop(network::error::protocol_violation); - ////return false; + handler(network::error::protocol_violation); + return; } // Requires only prevout population. error = block.connect(context); if (error) { - ////LOGR("Invalid block (connect) [" << encode_hash(hash) - //// << "] from [" << authority() << "] " << error.message()); - ////stop(network::error::protocol_violation); - ////return false; + handler(network::error::protocol_violation); + return; } // ******************************************************************** @@ -214,6 +216,7 @@ void chaser_block::do_organize(const chain::block::cptr& block_ptr) NOEXCEPT if (!is_current(header, context.height)) { save(block_ptr, context); + handler(error::success); return; } @@ -223,14 +226,14 @@ void chaser_block::do_organize(const chain::block::cptr& block_ptr) NOEXCEPT header_links store_branch{}; if (!get_branch_work(work, point, tree_branch, store_branch, header)) { - stop(error::store_integrity); + handler(error::store_integrity); return; } bool strong{}; if (!get_is_strong(strong, work, point)) { - stop(error::store_integrity); + handler(error::store_integrity); return; } @@ -245,6 +248,7 @@ void chaser_block::do_organize(const chain::block::cptr& block_ptr) NOEXCEPT { // Block is new top of current weak branch. save(block_ptr, context); + handler(error::success); return; } @@ -255,7 +259,7 @@ void chaser_block::do_organize(const chain::block::cptr& block_ptr) NOEXCEPT auto top = query.get_top_candidate(); if (top < point) { - stop(error::store_integrity); + handler(error::store_integrity); return; } @@ -264,7 +268,7 @@ void chaser_block::do_organize(const chain::block::cptr& block_ptr) NOEXCEPT { if (!query.pop_candidate()) { - stop(error::store_integrity); + handler(error::store_integrity); return; } } @@ -274,7 +278,7 @@ void chaser_block::do_organize(const chain::block::cptr& block_ptr) NOEXCEPT { if (!query.push_candidate(link)) { - stop(error::store_integrity); + handler(error::store_integrity); return; } } @@ -284,7 +288,7 @@ void chaser_block::do_organize(const chain::block::cptr& block_ptr) NOEXCEPT { if (!push(key)) { - stop(error::store_integrity); + handler(error::store_integrity); return; } } @@ -293,7 +297,7 @@ void chaser_block::do_organize(const chain::block::cptr& block_ptr) NOEXCEPT const auto link = push(block_ptr, context); if (link.is_terminal()) { - stop(error::store_integrity); + handler(error::store_integrity); return; } @@ -302,6 +306,8 @@ void chaser_block::do_organize(const chain::block::cptr& block_ptr) NOEXCEPT notify(error::success, chase::block, { possible_narrow_cast(point) }); + + handler(error::success); } // protected @@ -355,8 +361,6 @@ bool chaser_block::get_branch_work(uint256_t& work, size_t& point, work += system::chain::header::proof(bits); } - // TODO: this is always zero at new store. - // TODO: this could be the result of is_candidate_block being false. // Height of the highest candidate header is the branch point. return query.get_height(point, link); } diff --git a/src/chasers/chaser_check.cpp b/src/chasers/chaser_check.cpp index d1541f9e..946e23e4 100644 --- a/src/chasers/chaser_check.cpp +++ b/src/chasers/chaser_check.cpp @@ -82,9 +82,10 @@ void chaser_check::do_handle_event(const code& ec, chase event_, } // TODO: handle the new strong branch (may issue 'checked'). -void chaser_check::handle_header(height_t branch_point) NOEXCEPT +void chaser_check::handle_header(height_t) NOEXCEPT { - LOGN("Handle candidate organization above height (" << branch_point << ")."); + BC_ASSERT_MSG(stranded(), "chaser_check"); + ////LOGN("Handle candidate organization above height (" << branch_point << ")."); // get_all_unassociated_above(branch_point) } diff --git a/src/chasers/chaser_connect.cpp b/src/chasers/chaser_connect.cpp index f10d60b5..4ad61d6a 100644 --- a/src/chasers/chaser_connect.cpp +++ b/src/chasers/chaser_connect.cpp @@ -78,10 +78,10 @@ void chaser_connect::do_handle_event(const code& ec, chase event_, } // TODO: handle the new checked blocks (may issue 'connected'). -void chaser_connect::handle_checked(header_t block) NOEXCEPT +void chaser_connect::handle_checked(header_t) NOEXCEPT { BC_ASSERT_MSG(stranded(), "chaser_connect"); - LOGN("Handle candidate organization above height (" << block << ")."); + ////LOGN("Handle candidate organization above height (" << block << ")."); } BC_POP_WARNING() diff --git a/src/chasers/chaser_header.cpp b/src/chasers/chaser_header.cpp index 99f6ed3a..bb0f0cf0 100644 --- a/src/chasers/chaser_header.cpp +++ b/src/chasers/chaser_header.cpp @@ -87,15 +87,18 @@ void chaser_header::do_handle_event(const code&, chase, link) NOEXCEPT BC_ASSERT_MSG(stranded(), "chaser_header"); } -void chaser_header::organize(const chain::header::cptr& header) NOEXCEPT +void chaser_header::organize(const chain::header::cptr& header, + result_handler&& handler) NOEXCEPT { boost::asio::post(strand(), std::bind(&chaser_header::do_organize, - this, header)); + this, header, std::move(handler))); } // private -void chaser_header::do_organize(const chain::header::cptr& header_ptr) NOEXCEPT +// Caller may capture header_ptr in handler closure for detailed logging. +void chaser_header::do_organize(const chain::header::cptr& header_ptr, + const result_handler& handler) NOEXCEPT { BC_ASSERT_MSG(stranded(), "chaser_header"); @@ -108,14 +111,23 @@ void chaser_header::do_organize(const chain::header::cptr& header_ptr) NOEXCEPT // Skip existing, fail orphan. // ------------------------------------------------------------------------ + if (closed()) + { + handler(network::error::service_stopped); + return; + } + // Header already exists. if (tree_.contains(hash) || query.is_header(hash)) + { + handler(error::success); return; + } // Peer processing should have precluded orphan submission. if (!tree_.contains(previous) && !query.is_header(previous)) { - stop(error::orphan_header); + handler(error::orphan_header); return; } @@ -130,10 +142,8 @@ void chaser_header::do_organize(const chain::header::cptr& header_ptr) NOEXCEPT if (chain::checkpoint::is_conflict(coin.checkpoints, hash, state_->height())) { - ////LOGR("Invalid header (checkpoint) [" << encode_hash(hash) - //// << "] from [" << authority() << "]."); - ////stop(network::error::protocol_violation); - ////return false; + handler(network::error::protocol_violation); + return; } // Header validations are not bypassed when under checkpoint/milestone. @@ -142,19 +152,14 @@ void chaser_header::do_organize(const chain::header::cptr& header_ptr) NOEXCEPT coin.proof_of_work_limit, coin.scrypt_proof_of_work); if (error) { - ////LOGR("Invalid header (check) [" << encode_hash(hash) - //// << "] from [" << authority() << "] " << error.message()); - ////stop(network::error::protocol_violation); - ////return false; + handler(network::error::protocol_violation); + return; } error = header.accept(context); if (error) { - ////LOGR("Invalid header (accept) [" << encode_hash(hash) - //// << "] from [" << authority() << "] " << error.message()); - ////stop(network::error::protocol_violation); - ////return false; + handler(network::error::protocol_violation); } // Compute relative work. @@ -164,6 +169,7 @@ void chaser_header::do_organize(const chain::header::cptr& header_ptr) NOEXCEPT if (!is_current(header, context.height)) { save(header_ptr, context); + handler(error::success); return; } @@ -173,14 +179,14 @@ void chaser_header::do_organize(const chain::header::cptr& header_ptr) NOEXCEPT header_links store_branch{}; if (!get_branch_work(work, point, tree_branch, store_branch, header)) { - stop(error::store_integrity); + handler(error::store_integrity); return; } bool strong{}; if (!get_is_strong(strong, work, point)) { - stop(error::store_integrity); + handler(error::store_integrity); return; } @@ -188,6 +194,7 @@ void chaser_header::do_organize(const chain::header::cptr& header_ptr) NOEXCEPT if (!strong) { save(header_ptr, context); + handler(error::success); return; } @@ -198,7 +205,7 @@ void chaser_header::do_organize(const chain::header::cptr& header_ptr) NOEXCEPT auto top = query.get_top_candidate(); if (top < point) { - stop(error::store_integrity); + handler(error::store_integrity); return; } @@ -207,7 +214,7 @@ void chaser_header::do_organize(const chain::header::cptr& header_ptr) NOEXCEPT { if (!query.pop_candidate()) { - stop(error::store_integrity); + handler(error::store_integrity); return; } } @@ -217,7 +224,7 @@ void chaser_header::do_organize(const chain::header::cptr& header_ptr) NOEXCEPT { if (!query.push_candidate(link)) { - stop(error::store_integrity); + handler(error::store_integrity); return; } } @@ -227,7 +234,7 @@ void chaser_header::do_organize(const chain::header::cptr& header_ptr) NOEXCEPT { if (!push(key)) { - stop(error::store_integrity); + handler(error::store_integrity); return; } } @@ -236,7 +243,7 @@ void chaser_header::do_organize(const chain::header::cptr& header_ptr) NOEXCEPT const auto link = push(header_ptr, context); if (link.is_terminal()) { - stop(error::store_integrity); + handler(error::store_integrity); return; } @@ -245,6 +252,8 @@ void chaser_header::do_organize(const chain::header::cptr& header_ptr) NOEXCEPT notify(error::success, chase::header, { possible_narrow_cast(point) }); + + handler(error::success); } // protected diff --git a/src/full_node.cpp b/src/full_node.cpp index c4cb4235..73e3798a 100644 --- a/src/full_node.cpp +++ b/src/full_node.cpp @@ -127,17 +127,24 @@ void full_node::do_close() NOEXCEPT p2p::do_close(); } +bool full_node::closed() const NOEXCEPT +{ + return closed(); +} + // Chasers. // ---------------------------------------------------------------------------- -void full_node::organize(const system::chain::header::cptr& header) NOEXCEPT +void full_node::organize(const system::chain::header::cptr& header, + result_handler&& handler) NOEXCEPT { - chaser_header_.organize(header); + chaser_header_.organize(header, std::move(handler)); } -void full_node::organize(const system::chain::block::cptr& block) NOEXCEPT +void full_node::organize(const system::chain::block::cptr& block, + result_handler&& handler) NOEXCEPT { - chaser_block_.organize(block); + chaser_block_.organize(block, std::move(handler)); } // Properties. diff --git a/src/protocols/protocol.cpp b/src/protocols/protocol.cpp index a996fc63..8f11f6a0 100644 --- a/src/protocols/protocol.cpp +++ b/src/protocols/protocol.cpp @@ -28,6 +28,8 @@ namespace libbitcoin { namespace node { +using namespace network; + protocol::~protocol() NOEXCEPT { } @@ -38,14 +40,22 @@ void protocol::performance(uint64_t channel, uint64_t speed, session_.performance(channel, speed, std::move(handler)); } -void protocol::organize(const system::chain::header::cptr& header) NOEXCEPT + +void protocol::handle_organize(const code& ec) NOEXCEPT +{ + stop(ec); +} + +void protocol::organize(const system::chain::header::cptr& header, + result_handler&& handler) NOEXCEPT { - session_.organize(header); + session_.organize(header, std::move(handler)); } -void protocol::organize(const system::chain::block::cptr& block) NOEXCEPT +void protocol::organize(const system::chain::block::cptr& block, + result_handler&& handler) NOEXCEPT { - session_.organize(block); + session_.organize(block, std::move(handler)); } const configuration& protocol::config() const NOEXCEPT diff --git a/src/protocols/protocol_block_in.cpp b/src/protocols/protocol_block_in.cpp index a30268ff..39d614ce 100644 --- a/src/protocols/protocol_block_in.cpp +++ b/src/protocols/protocol_block_in.cpp @@ -145,7 +145,7 @@ bool protocol_block_in::handle_receive_block(const code& ec, return false; } - organize(message->block_ptr); + organize(message->block_ptr, BIND1(handle_organize, _1)); top_ = { message->block_ptr->hash(), add1(top_.height()) }; LOGP("Block [" << encode_hash(top_.hash()) << "] at (" @@ -189,6 +189,8 @@ void protocol_block_in::complete() NOEXCEPT get_blocks protocol_block_in::create_get_inventory() const NOEXCEPT { + // This will bypass all blocks with candidate headers, resulting in block + // orphans if headers-first is run followed by a restart and blocks-first. return create_get_inventory(archive().get_candidate_hashes( get_blocks::heights(archive().get_top_candidate()))); } diff --git a/src/protocols/protocol_block_in_31800.cpp b/src/protocols/protocol_block_in_31800.cpp index ffb94197..3cfbd949 100644 --- a/src/protocols/protocol_block_in_31800.cpp +++ b/src/protocols/protocol_block_in_31800.cpp @@ -213,7 +213,7 @@ bool protocol_block_in_31800::handle_receive_block(const code& ec, return false; } - organize(message->block_ptr); + organize(message->block_ptr, BIND1(handle_organize, _1)); top_ = { message->block_ptr->hash(), add1(top_.height()) }; LOGP("Block [" << encode_hash(top_.hash()) << "] at (" diff --git a/src/protocols/protocol_header_in_31800.cpp b/src/protocols/protocol_header_in_31800.cpp index 17c979b6..1dc3ccd1 100644 --- a/src/protocols/protocol_header_in_31800.cpp +++ b/src/protocols/protocol_header_in_31800.cpp @@ -87,7 +87,7 @@ bool protocol_header_in_31800::handle_receive_headers(const code& ec, return false; } - organize(header_ptr); + organize(header_ptr, BIND1(handle_organize, _1)); top_ = { header_ptr->hash(), add1(top_.height()) }; LOGP("Header [" << encode_hash(top_.hash()) << "] at (" diff --git a/src/sessions/session.cpp b/src/sessions/session.cpp index ffb0a27c..1376cd97 100644 --- a/src/sessions/session.cpp +++ b/src/sessions/session.cpp @@ -47,14 +47,16 @@ void session::performance(uint64_t, uint64_t, result_handler&& handler) NOEXCEPT BC_POP_WARNING() } -void session::organize(const header::cptr& header) NOEXCEPT +void session::organize(const header::cptr& header, + result_handler&& handler) NOEXCEPT { - node_.organize(header); + node_.organize(header, std::move(handler)); } -void session::organize(const block::cptr& block) NOEXCEPT +void session::organize(const block::cptr& block, + result_handler&& handler) NOEXCEPT { - node_.organize(block); + node_.organize(block, std::move(handler)); } const configuration& session::config() const NOEXCEPT