From e52e31a86097a071d55ff14856ca98c028184b1c Mon Sep 17 00:00:00 2001 From: Eric Voskuil Date: Mon, 21 Sep 2026 21:00:10 -0400 Subject: [PATCH] Replace the chase event enum parameter with typed event payloads. --- include/bitcoin/node/chase.hpp | 329 ++++++++++++++++-- include/bitcoin/node/chasers/chaser.hpp | 5 +- include/bitcoin/node/chasers/chaser_check.hpp | 3 +- .../bitcoin/node/chasers/chaser_confirm.hpp | 3 +- .../bitcoin/node/chasers/chaser_estimate.hpp | 3 +- .../bitcoin/node/chasers/chaser_organize.hpp | 21 +- .../bitcoin/node/chasers/chaser_snapshot.hpp | 3 +- .../bitcoin/node/chasers/chaser_storage.hpp | 3 +- .../bitcoin/node/chasers/chaser_template.hpp | 3 +- .../node/chasers/chaser_transaction.hpp | 3 +- .../bitcoin/node/chasers/chaser_validate.hpp | 3 +- include/bitcoin/node/define.hpp | 30 +- include/bitcoin/node/full_node.hpp | 9 +- .../node/impl/chasers/chaser_organize.ipp | 43 ++- .../protocols/protocol_block_in_31800.hpp | 3 +- .../node/protocols/protocol_block_out_106.hpp | 3 +- .../protocols/protocol_header_out_70012.hpp | 3 +- .../node/protocols/protocol_observer.hpp | 3 +- .../bitcoin/node/protocols/protocol_peer.hpp | 5 +- .../protocol_transaction_out_106.hpp | 3 +- .../protocol_transaction_out_70013.hpp | 3 +- include/bitcoin/node/sessions/session.hpp | 5 +- src/chasers/chaser.cpp | 9 +- src/chasers/chaser_check.cpp | 40 +-- src/chasers/chaser_confirm.cpp | 35 +- src/chasers/chaser_estimate.cpp | 18 +- src/chasers/chaser_snapshot.cpp | 13 +- src/chasers/chaser_storage.cpp | 9 +- src/chasers/chaser_template.cpp | 10 +- src/chasers/chaser_transaction.cpp | 9 +- src/chasers/chaser_validate.cpp | 37 +- src/full_node.cpp | 30 +- src/protocols/protocol_block_in_31800.cpp | 18 +- src/protocols/protocol_block_out_106.cpp | 10 +- src/protocols/protocol_header_out_70012.cpp | 10 +- src/protocols/protocol_observer.cpp | 7 +- src/protocols/protocol_peer.cpp | 9 +- .../protocol_transaction_out_106.cpp | 10 +- .../protocol_transaction_out_70013.cpp | 6 +- src/sessions/session.cpp | 9 +- 40 files changed, 496 insertions(+), 282 deletions(-) diff --git a/include/bitcoin/node/chase.hpp b/include/bitcoin/node/chase.hpp index 3a691ae2..faa11d8c 100644 --- a/include/bitcoin/node/chase.hpp +++ b/include/bitcoin/node/chase.hpp @@ -19,37 +19,49 @@ #ifndef LIBBITCOIN_NODE_CHASE_HPP #define LIBBITCOIN_NODE_CHASE_HPP +#include #include namespace libbitcoin { namespace node { +/// Event desubscriber key type. +using object_key = uint64_t; + +/// Event payload types. +using count_t = size_t; +using height_t = size_t; +using peer_t = uint64_t; +using object_t = object_key; +using header_t = database::header_link::integer; +using transaction_t = database::tx_link::integer; + enum class chase { /// Work shuffling. /// ----------------------------------------------------------------------- - /// Chasers directed to start operating (height_t). + /// Chasers directed to start operating. /// Issued by 'full_node' and handled by 'check', 'validate', 'confirm'. start, - /// Disk space is limited (count_t). - /// Issued by 'full_node' and handled by 'snapshot' and 'storage'. + /// Disk space is limited. + /// Issued by 'full_node' and handled by 'storage'. space, - /// Take a snapshot (height_t). + /// Take a snapshot. /// Issued by 'confirm' and handled by 'snapshot'. snap, - /// Chaser directed to attempt start from its current position (height_t). + /// Chaser directed to attempt start from its current position. /// Issued by 'organize' and handled by 'check', 'validate', 'confirm'. bump, - /// Channels (all) directed to stop with the given code (default). + /// Channels (all) directed to stop with the given code. /// Issued by 'full_node' and handled by 'observer'. suspend, - /// Chasers (all) directed to resume following suspend (default). + /// Chasers (all) directed to resume following suspend. /// Issued by 'full_node' and handled by 'check', 'validate', 'confirm'. resume, @@ -57,38 +69,38 @@ enum class chase /// Issued by 'storage' and handled by 'validate'. unfull, - /// Channel starved for work (object_t). - /// Issued by 'block_in_31800' and handled by 'session_outbound'. + /// Channel starved for work. + /// Issued by 'block_in_31800' and handled by 'check'. starved, - /// Channel (slow) directed to split work and stop (object_t). - /// Issued by 'session_outbound' and handled by 'block_in_31800'. + /// Channel (slow) directed to split work and stop. + /// Issued by 'check' and handled by 'block_in_31800'. split, - /// Channels (all with work) directed to split work and stop (peer_t). - /// Issued by 'session_outbound' and handled by 'block_in_31800'. + /// Channels (all with work) directed to split work and stop. + /// Issued by 'check' and handled by 'block_in_31800'. stall, - /// Channels (all with work) directed to drop work and stop (peer_t). + /// Channels (all with work) directed to drop work and stop. /// Issued by 'check' and handled by 'block_in_31800'. purge, - /// Channels (all) directed to write work count to the log (count_t). + /// Channels (all) directed to write work count to the log. /// Issued by 'executor' and handled by 'block_in_31800'. report, /// Candidate Chain. /// ----------------------------------------------------------------------- - /// A new candidate branch exists from given branch point (height_t). - /// Issued by 'block' and handled by 'confirm' and 'snapshot'. + /// A new candidate branch exists from given branch point. + /// Issued by 'block' and handled by none. blocks, - /// A new candidate branch exists from given branch point (height_t). + /// A new candidate branch exists from given branch point. /// Issued by 'header' and handled by 'check'. headers, - /// New candidate headers without txs exist (count_t). + /// New candidate headers without txs exist. /// Issued by 'check' and handled by 'block_in_31800'. download, @@ -96,85 +108,328 @@ enum class chase /// Issued by 'organize' and handled by 'check', 'validate', 'confirm'. regressed, - /// unchecked, unvalid or unconfirmable was handled (height_t). + /// unchecked, unvalid or unconfirmable was handled. /// Issued by 'organize' and handled by 'check', 'validate', 'confirm'. disorganized, /// Check/Identify. /// ----------------------------------------------------------------------- - /// A block has been downloaded, checked and stored (height_t). - /// Issued by 'block_in_31800', handled by 'check', 'validate', 'snapshot'. + /// A block has been downloaded, checked and stored. + /// Issued by 'block_in_31800', handled by 'check', 'validate'. /// Populate is bypassed for checkpoint/milestone blocks. checked, - /// A downloaded block has failed check (header_t). + /// A downloaded block has failed check. /// Issued by 'block_in_31800' and handled by 'organize'. unchecked, - /// A downloaded window is completed by check (height_t). + /// A downloaded window is completed by check. /// Issued by 'check' and handled by 'validate'. windowed, /// Accept/Connect. /// ----------------------------------------------------------------------- - /// A branch has become valid (height_t). - /// Issued by 'validate' and handled by 'check', 'confirm', 'snapshot'. + /// A branch has become valid. + /// Issued by 'validate' and handled by 'check', 'confirm'. valid, - /// A checked block has failed validation (header_t). + /// A checked block has failed validation. /// Issued by 'validate' and handled by 'organize'. unvalid, /// Confirm (block). /// ----------------------------------------------------------------------- - /// A connected block has become confirmable (header_t). - /// Issued by 'confirm' and handled by 'snapshot'. + /// A connected block has become confirmable. + /// Issued by 'confirm' and handled by none. confirmable, - /// A connected block has failed confirmability (header_t). + /// A connected block has failed confirmability. /// Issued by 'confirm' and handled by 'organize'. unconfirmable, /// Confirm (chain). /// ----------------------------------------------------------------------- - /// A current block has been organized (header_t). + /// A current block has been organized. /// Issued by 'confirm' and handled by 'protocol_header/block_out/estimator'. block, - /// The confirmed chain is no longer current (default). + /// The confirmed chain is no longer current. /// Issued by 'confirm' and handled by 'protocol_transaction_out'. stale, - /// A confirmable block has been confirmed (header_t). + /// A confirmable block has been confirmed. /// Issued by 'confirm' and handled by 'transaction'. organized, - /// A previously confirmed block has been unconfirmed (header_t). + /// A previously confirmed block has been unconfirmed. /// Issued by 'confirm' and handled by 'transaction'. reorganized, /// Mining. /// ----------------------------------------------------------------------- - /// A transaction has been added to the pool (transaction_t). + /// A transaction has been added to the pool. /// Issued by 'transaction' and handled by 'template'. transaction, - /// A candidate block (template) has been created (height_t). + /// A candidate block (template) has been created. /// Issued by 'template' and handled by [miners]. template_, /// Stop. /// ----------------------------------------------------------------------- - /// Service is stopping, accompanied by error::service_stopped (default). + /// Service is stopping, accompanied by error::service_stopped. stop }; +/// Event payloads, one per chase value, declared in chase order. +namespace chases { + +struct start +{ + static constexpr chase id{ chase::start }; +}; + +struct space +{ + static constexpr chase id{ chase::space }; +}; + +struct snap +{ + static constexpr chase id{ chase::snap }; + height_t height; +}; + +struct bump +{ + static constexpr chase id{ chase::bump }; + height_t height; +}; + +struct suspend +{ + static constexpr chase id{ chase::suspend }; +}; + +struct resume +{ + static constexpr chase id{ chase::resume }; +}; + +struct unfull +{ + static constexpr chase id{ chase::unfull }; +}; + +struct starved +{ + static constexpr chase id{ chase::starved }; + object_t channel; +}; + +struct split +{ + static constexpr chase id{ chase::split }; + object_t channel; +}; + +struct stall +{ + static constexpr chase id{ chase::stall }; + object_t channel; +}; + +struct purge +{ + static constexpr chase id{ chase::purge }; + height_t branch_point; +}; + +struct report +{ + static constexpr chase id{ chase::report }; + count_t sequence; +}; + +struct blocks +{ + static constexpr chase id{ chase::blocks }; + height_t branch_point; +}; + +struct headers +{ + static constexpr chase id{ chase::headers }; + height_t branch_point; +}; + +struct download +{ + static constexpr chase id{ chase::download }; + count_t count; +}; + +struct regressed +{ + static constexpr chase id{ chase::regressed }; + height_t branch_point; +}; + +struct disorganized +{ + static constexpr chase id{ chase::disorganized }; + height_t branch_point; +}; + +struct checked +{ + static constexpr chase id{ chase::checked }; + height_t height; +}; + +struct unchecked +{ + static constexpr chase id{ chase::unchecked }; + header_t link; +}; + +struct windowed +{ + static constexpr chase id{ chase::windowed }; + height_t height; +}; + +struct valid +{ + static constexpr chase id{ chase::valid }; + height_t height; +}; + +struct unvalid +{ + static constexpr chase id{ chase::unvalid }; + header_t link; +}; + +struct confirmable +{ + static constexpr chase id{ chase::confirmable }; + header_t link; +}; + +struct unconfirmable +{ + static constexpr chase id{ chase::unconfirmable }; + header_t link; +}; + +struct block +{ + static constexpr chase id{ chase::block }; + header_t link; +}; + +struct stale +{ + static constexpr chase id{ chase::stale }; +}; + +struct organized +{ + static constexpr chase id{ chase::organized }; + header_t link; +}; + +struct reorganized +{ + static constexpr chase id{ chase::reorganized }; + header_t link; +}; + +struct transaction +{ + static constexpr chase id{ chase::transaction }; + transaction_t link; +}; + +struct template_ +{ + static constexpr chase id{ chase::template_ }; + height_t height; +}; + +struct stop +{ + static constexpr chase id{ chase::stop }; +}; + +} // namespace chases + +/// Alternative position is the chase value, so the event carries its own type. +using event_value = std::variant +< + chases::start, + chases::space, + chases::snap, + chases::bump, + chases::suspend, + chases::resume, + chases::unfull, + chases::starved, + chases::split, + chases::stall, + chases::purge, + chases::report, + chases::blocks, + chases::headers, + chases::download, + chases::regressed, + chases::disorganized, + chases::checked, + chases::unchecked, + chases::windowed, + chases::valid, + chases::unvalid, + chases::confirmable, + chases::unconfirmable, + chases::block, + chases::stale, + chases::organized, + chases::reorganized, + chases::transaction, + chases::template_, + chases::stop +>; + +template +constexpr bool is_chase_ordered(std::index_sequence) NOEXCEPT +{ + return ((std::variant_alternative_t::id == + static_cast(Index)) && ...); +} + +static_assert(is_chase_ordered(std::make_index_sequence< + std::variant_size_v>{})); + +/// The event's chase value. +constexpr chase to_chase(const event_value& value) NOEXCEPT +{ + return static_cast(value.index()); +} + +/// The event's payload, guarded by the alternative ordering above. +template +constexpr const auto& to_payload(const event_value& value) NOEXCEPT +{ + return std::get(value); +} + } // namespace node } // namespace libbitcoin diff --git a/include/bitcoin/node/chasers/chaser.hpp b/include/bitcoin/node/chasers/chaser.hpp index ce4252da..c2b6bc64 100644 --- a/include/bitcoin/node/chasers/chaser.hpp +++ b/include/bitcoin/node/chasers/chaser.hpp @@ -101,11 +101,10 @@ class BCN_API chaser virtual object_key subscribe_chase(event_notifier&& handler) NOEXCEPT; /// Set event (does not require node strand). - virtual void notify(const code& ec, chase event_, - event_value value) const NOEXCEPT; + virtual void notify(const code& ec, event_value value) const NOEXCEPT; /// Set event to one subscriber (does not require node strand). - virtual void notify_one(object_key key, const code& ec, chase event_, + virtual void notify_one(object_key key, const code& ec, event_value value) const NOEXCEPT; /// Strand. diff --git a/include/bitcoin/node/chasers/chaser_check.hpp b/include/bitcoin/node/chasers/chaser_check.hpp index 3bf5dbd8..3c6e3bdf 100644 --- a/include/bitcoin/node/chasers/chaser_check.hpp +++ b/include/bitcoin/node/chasers/chaser_check.hpp @@ -60,8 +60,7 @@ class BCN_API chaser_check protected: virtual void handle_purged(const code& ec) NOEXCEPT; - virtual bool handle_chase(const code& ec, chase event_, - event_value value) NOEXCEPT; + virtual bool handle_chase(const code& ec, event_value value) NOEXCEPT; /// block tracking virtual void do_bump(height_t height) NOEXCEPT; diff --git a/include/bitcoin/node/chasers/chaser_confirm.hpp b/include/bitcoin/node/chasers/chaser_confirm.hpp index 8aec0191..8c83396a 100644 --- a/include/bitcoin/node/chasers/chaser_confirm.hpp +++ b/include/bitcoin/node/chasers/chaser_confirm.hpp @@ -44,8 +44,7 @@ class BCN_API chaser_confirm using header_links = database::header_links; using header_states = database::header_states; - virtual bool handle_chase(const code& ec, chase event_, - event_value value) NOEXCEPT; + virtual bool handle_chase(const code& ec, event_value value) NOEXCEPT; virtual void do_regressed(height_t branch_point) NOEXCEPT; virtual void do_validated(height_t height) NOEXCEPT; diff --git a/include/bitcoin/node/chasers/chaser_estimate.hpp b/include/bitcoin/node/chasers/chaser_estimate.hpp index a4ed0b49..832d117a 100644 --- a/include/bitcoin/node/chasers/chaser_estimate.hpp +++ b/include/bitcoin/node/chasers/chaser_estimate.hpp @@ -52,8 +52,7 @@ class BCN_API chaser_estimate bool initialized() const NOEXCEPT; protected: - virtual bool handle_chase(const code& ec, chase event_, - event_value value) NOEXCEPT; + virtual bool handle_chase(const code& ec, event_value value) NOEXCEPT; virtual void do_initialize(header_t link) NOEXCEPT; virtual void do_organized(header_t link) NOEXCEPT; diff --git a/include/bitcoin/node/chasers/chaser_organize.hpp b/include/bitcoin/node/chasers/chaser_organize.hpp index 81d30ce5..869807a5 100644 --- a/include/bitcoin/node/chasers/chaser_organize.hpp +++ b/include/bitcoin/node/chasers/chaser_organize.hpp @@ -90,8 +90,7 @@ class chaser_organize /// ----------------------------------------------------------------------- /// Handle chaser events. - virtual bool handle_chase(const code&, chase event_, - event_value value) NOEXCEPT; + virtual bool handle_chase(const code&, event_value value) NOEXCEPT; /// Organize a discovered Block, prioritized accepts a tied branch. virtual void do_organize(typename Block::cptr block, bool prioritized, @@ -120,32 +119,40 @@ class chaser_organize // Template differentiators. // ------------------------------------------------------------------------ + static constexpr bool is_block_ + { + is_same_type + }; + + using chase_object = iif; + static constexpr bool is_block() NOEXCEPT { - return is_same_type; + return is_block_; } + static constexpr auto error_duplicate() NOEXCEPT { return is_block() ? error::duplicate_block : error::duplicate_header; } + static constexpr auto error_orphan() NOEXCEPT { return is_block() ? error::orphan_block : error::orphan_header; } - static constexpr auto chase_object() NOEXCEPT - { - return is_block() ? chase::blocks : chase::headers; - } + static constexpr auto events_object_archived() NOEXCEPT { return is_block() ? events::block_archived : events::header_archived; } + static constexpr auto events_object_organized() NOEXCEPT { // Using header because block organization is in confirmation chaser. ////return is_block() ? events::block_organized : events::header_organized; return events::header_organized; } + static constexpr auto events_object_reorganized() NOEXCEPT { // Using header because block reorganized is in confirmation chaser. diff --git a/include/bitcoin/node/chasers/chaser_snapshot.hpp b/include/bitcoin/node/chasers/chaser_snapshot.hpp index 61ba3ff7..0333e5c7 100644 --- a/include/bitcoin/node/chasers/chaser_snapshot.hpp +++ b/include/bitcoin/node/chasers/chaser_snapshot.hpp @@ -46,8 +46,7 @@ class BCN_API chaser_snapshot ////virtual void do_valid(height_t height) NOEXCEPT; ////virtual void do_confirm(height_t height) NOEXCEPT; - virtual bool handle_chase(const code& ec, chase event_, - event_value value) NOEXCEPT; + virtual bool handle_chase(const code& ec, event_value value) NOEXCEPT; private: void take_snapshot(height_t height) NOEXCEPT; diff --git a/include/bitcoin/node/chasers/chaser_storage.hpp b/include/bitcoin/node/chasers/chaser_storage.hpp index 61211a8d..5b3fd42e 100644 --- a/include/bitcoin/node/chasers/chaser_storage.hpp +++ b/include/bitcoin/node/chasers/chaser_storage.hpp @@ -43,8 +43,7 @@ class BCN_API chaser_storage protected: virtual void do_reload() NOEXCEPT; virtual void do_space(size_t space) NOEXCEPT; - virtual bool handle_chase(const code& ec, chase event_, - event_value value) NOEXCEPT; + virtual bool handle_chase(const code& ec, event_value value) NOEXCEPT; private: void do_stopping(const code& ec) NOEXCEPT; diff --git a/include/bitcoin/node/chasers/chaser_template.hpp b/include/bitcoin/node/chasers/chaser_template.hpp index 7f21874e..16529511 100644 --- a/include/bitcoin/node/chasers/chaser_template.hpp +++ b/include/bitcoin/node/chasers/chaser_template.hpp @@ -39,8 +39,7 @@ class BCN_API chaser_template code start() NOEXCEPT override; protected: - virtual bool handle_chase(const code& ec, chase event_, - event_value value) NOEXCEPT; + virtual bool handle_chase(const code& ec, event_value value) NOEXCEPT; virtual void do_transaction(transaction_t value) NOEXCEPT; }; diff --git a/include/bitcoin/node/chasers/chaser_transaction.hpp b/include/bitcoin/node/chasers/chaser_transaction.hpp index 4cc6fe34..d9d0ab80 100644 --- a/include/bitcoin/node/chasers/chaser_transaction.hpp +++ b/include/bitcoin/node/chasers/chaser_transaction.hpp @@ -44,8 +44,7 @@ class BCN_API chaser_transaction bool test, submit_handler&& handler) NOEXCEPT; protected: - virtual bool handle_chase(const code& ec, chase event_, - event_value value) NOEXCEPT; + virtual bool handle_chase(const code& ec, event_value value) NOEXCEPT; virtual void do_submit(const system::chain::transactions_cptr& txs, bool test, const submit_handler& handler) NOEXCEPT; diff --git a/include/bitcoin/node/chasers/chaser_validate.hpp b/include/bitcoin/node/chasers/chaser_validate.hpp index e2d76eb8..786f98f2 100644 --- a/include/bitcoin/node/chasers/chaser_validate.hpp +++ b/include/bitcoin/node/chasers/chaser_validate.hpp @@ -55,8 +55,7 @@ class BCN_API chaser_validate BIND_TO(method, args)); } - virtual bool handle_chase(const code& ec, chase event_, - event_value value) NOEXCEPT; + virtual bool handle_chase(const code& ec, event_value value) NOEXCEPT; virtual void do_regressed(height_t branch_point) NOEXCEPT; virtual void do_checked(height_t height) NOEXCEPT; diff --git a/include/bitcoin/node/define.hpp b/include/bitcoin/node/define.hpp index 91e4f3a5..cdd799db 100644 --- a/include/bitcoin/node/define.hpp +++ b/include/bitcoin/node/define.hpp @@ -40,7 +40,6 @@ #endif /// For common types below. -#include #include namespace libbitcoin { @@ -64,41 +63,14 @@ typedef std::shared_ptr map_ptr; typedef std::function map_handler; -/// Event desubscriber key type. -using object_key = uint64_t; - -/// Event value types. -using count_t = size_t; -using height_t = size_t; -using peer_t = uint64_t; -using object_t = object_key; -using header_t = database::header_link::integer; -using transaction_t = database::tx_link::integer; - -/// std::variant types must be distinct, and xcode size_t is neither uint32_t -/// nor uint64_t, so this ensures we have the distinct set of necessary types. -using event_value = - iif, - std::variant, - iif, - std::variant, - std::variant>>; - /// Event desubscriber. -typedef network::desubscriber event_subscriber; +typedef network::desubscriber event_subscriber; typedef event_subscriber::handler event_notifier; typedef event_subscriber::completer event_completer; // Inventory messages. using type_id = network::messages::peer::inventory_item::type_id; -// NDEBUG MSVC -////static_assert(sizeof(uint64_t) == 8u); -////static_assert(sizeof(block_t) == 16u); -////static_assert(sizeof(xblock_t) == 32u); -////static_assert(sizeof(event_value) == 24u); -////static_assert(sizeof(xevent_value) == 40u); - } // namespace node } // namespace libbitcoin diff --git a/include/bitcoin/node/full_node.hpp b/include/bitcoin/node/full_node.hpp index 9eba4fa9..7a01dada 100644 --- a/include/bitcoin/node/full_node.hpp +++ b/include/bitcoin/node/full_node.hpp @@ -87,11 +87,10 @@ class BCN_API full_node /// ----------------------------------------------------------------------- /// Set chaser event. - virtual void notify(const code& ec, chase event_, - event_value value) NOEXCEPT; + virtual void notify(const code& ec, event_value value) NOEXCEPT; /// Set chaser event for the given subscriber only. - virtual void notify_one(object_key key, const code& ec, chase event_, + virtual void notify_one(object_key key, const code& ec, event_value value) NOEXCEPT; /// Call from chaser start() methods (requires strand). @@ -186,8 +185,8 @@ class BCN_API full_node private: void do_subscribe_chase(const event_notifier& handler, const event_completer& complete) NOEXCEPT; - void do_notify(const code& ec, chase event_, event_value value) NOEXCEPT; - void do_notify_one(object_key key, const code& ec, chase event_, + void do_notify(const code& ec, event_value value) NOEXCEPT; + void do_notify_one(object_key key, const code& ec, event_value value) NOEXCEPT; // These are thread safe. diff --git a/include/bitcoin/node/impl/chasers/chaser_organize.ipp b/include/bitcoin/node/impl/chasers/chaser_organize.ipp index 31df6e5d..c45b9c6f 100644 --- a/include/bitcoin/node/impl/chasers/chaser_organize.ipp +++ b/include/bitcoin/node/impl/chasers/chaser_organize.ipp @@ -61,7 +61,7 @@ code CLASS::start() NOEXCEPT << state_->height() << "]."); update_checkpoint(top); - SUBSCRIBE_CHASE(handle_chase, _1, _2, _3); + SUBSCRIBE_CHASE(handle_chase, _1, _2); return error::success; } @@ -89,23 +89,40 @@ void CLASS::prioritize(const system::hash_digest& hash, // ---------------------------------------------------------------------------- TEMPLATE -bool CLASS::handle_chase(const code&, chase event_, event_value value) NOEXCEPT +bool CLASS::handle_chase(const code&, event_value value) NOEXCEPT { if (closed()) return false; - switch (event_) + switch (to_chase(value)) { + // Roll back the candidate chain to confirmed top (via fork point). case chase::unchecked: + { + if (database_settings().mark_unconfirmable) + { + POST(do_disorganize, to_payload(value).link); + } + + break; + } case chase::unvalid: + { + if (database_settings().mark_unconfirmable) + { + POST(do_disorganize, to_payload(value).link); + } + + break; + } case chase::unconfirmable: { - if (!database_settings().mark_unconfirmable) - break; + if (database_settings().mark_unconfirmable) + { + POST(do_disorganize, + to_payload(value).link); + } - // Roll back the candidate chain to confirmed top (via fork point). - BC_ASSERT(std::holds_alternative(value)); - POST(do_disorganize, std::get(value)); break; } case chase::stop: @@ -273,7 +290,7 @@ void CLASS::do_organize(typename Block::cptr block, bool prioritized, // Reset chasers to the branch point. if (regress) { - notify(error::success, chase::regressed, branch_point); + notify(error::success, chases::regressed{ branch_point }); } // Push stored strong headers to candidate chain. @@ -322,14 +339,14 @@ void CLASS::do_organize(typename Block::cptr block, bool prioritized, // be skipped, resulting in stall until restart at which time the start // event will advance through all downloaded candidates and progress on // arrivals. This bumps validation once for current strong headers. - notify(error::success, chase::bump, add1(branch_point)); + notify(error::success, chases::bump{ add1(branch_point) }); bumped_ = true; } // chase::headers | chase::blocks // This prevents download stall, the check chaser races ahead. // Start block downloads, which upon completion bumps validation. - notify(error::success, chase_object(), branch_point); + notify(error::success, chase_object{ branch_point }); } // Logs from candidate block parent to the candidate (forward sequential). @@ -486,10 +503,10 @@ void CLASS::do_disorganize(header_t link) NOEXCEPT state_ = state; // Candidate is same as confirmed, reset chasers to new top. - notify(error::success, chase::disorganized, fork_point); + notify(error::success, chases::disorganized{ fork_point }); // Reset all connections to ensure that new connections exist. - notify(error::success, chase::suspend, {}); + notify(error::success, chases::suspend{}); } // Private setters diff --git a/include/bitcoin/node/protocols/protocol_block_in_31800.hpp b/include/bitcoin/node/protocols/protocol_block_in_31800.hpp index 4f1358be..7dd789bd 100644 --- a/include/bitcoin/node/protocols/protocol_block_in_31800.hpp +++ b/include/bitcoin/node/protocols/protocol_block_in_31800.hpp @@ -61,8 +61,7 @@ class BCN_API protocol_block_in_31800 virtual void do_get_downloads(count_t count) NOEXCEPT; /// Handle chaser events. - virtual bool handle_chase(const code& ec, chase event_, - event_value value) NOEXCEPT; + virtual bool handle_chase(const code& ec, event_value value) NOEXCEPT; /// Manage work splitting. bool is_idle() const NOEXCEPT override; diff --git a/include/bitcoin/node/protocols/protocol_block_out_106.hpp b/include/bitcoin/node/protocols/protocol_block_out_106.hpp index d58e31ea..53424f5c 100644 --- a/include/bitcoin/node/protocols/protocol_block_out_106.hpp +++ b/include/bitcoin/node/protocols/protocol_block_out_106.hpp @@ -59,8 +59,7 @@ class BCN_API protocol_block_out_106 virtual bool superseded() const NOEXCEPT; /// Handle chaser events. - virtual bool handle_chase(const code& ec, chase event_, - event_value value) NOEXCEPT; + virtual bool handle_chase(const code& ec, event_value value) NOEXCEPT; /// Process block announcement. virtual bool do_announce(header_t link) NOEXCEPT; diff --git a/include/bitcoin/node/protocols/protocol_header_out_70012.hpp b/include/bitcoin/node/protocols/protocol_header_out_70012.hpp index b97e8268..52d29ab1 100644 --- a/include/bitcoin/node/protocols/protocol_header_out_70012.hpp +++ b/include/bitcoin/node/protocols/protocol_header_out_70012.hpp @@ -47,8 +47,7 @@ class BCN_API protocol_header_out_70012 protected: /// Handle chaser events. - virtual bool handle_chase(const code& ec, chase event_, - event_value value) NOEXCEPT; + virtual bool handle_chase(const code& ec, event_value value) NOEXCEPT; /// Process block announcement. virtual bool do_announce(header_t link) NOEXCEPT; diff --git a/include/bitcoin/node/protocols/protocol_observer.hpp b/include/bitcoin/node/protocols/protocol_observer.hpp index b7423596..0522cbdd 100644 --- a/include/bitcoin/node/protocols/protocol_observer.hpp +++ b/include/bitcoin/node/protocols/protocol_observer.hpp @@ -57,8 +57,7 @@ class BCN_API protocol_observer protected: /// Handle chaser events. - virtual bool handle_chase(const code& ec, chase event_, - event_value value) NOEXCEPT; + virtual bool handle_chase(const code& ec, event_value value) NOEXCEPT; /// Accept incoming inventory message. virtual bool handle_receive_inventory(const code& ec, diff --git a/include/bitcoin/node/protocols/protocol_peer.hpp b/include/bitcoin/node/protocols/protocol_peer.hpp index 1f3504fc..36a0404d 100644 --- a/include/bitcoin/node/protocols/protocol_peer.hpp +++ b/include/bitcoin/node/protocols/protocol_peer.hpp @@ -95,11 +95,10 @@ class BCN_API protocol_peer using network::protocol_peer::notify; /// Set a chaser event. - virtual void notify(const code& ec, chase event_, - event_value value) const NOEXCEPT; + virtual void notify(const code& ec, event_value value) const NOEXCEPT; /// Set a chaser event. - virtual void notify_one(object_key key, const code& ec, chase event_, + virtual void notify_one(object_key key, const code& ec, event_value value) const NOEXCEPT; private: diff --git a/include/bitcoin/node/protocols/protocol_transaction_out_106.hpp b/include/bitcoin/node/protocols/protocol_transaction_out_106.hpp index fe4a01ef..06528d00 100644 --- a/include/bitcoin/node/protocols/protocol_transaction_out_106.hpp +++ b/include/bitcoin/node/protocols/protocol_transaction_out_106.hpp @@ -50,8 +50,7 @@ class BCN_API protocol_transaction_out_106 using inventory_items = network::messages::peer::inventory_items; /// Handle chaser events. - virtual bool handle_chase(const code& ec, chase event_, - event_value value) NOEXCEPT; + virtual bool handle_chase(const code& ec, event_value value) NOEXCEPT; /// Process tx announcement. virtual bool do_announce(transaction_t link) NOEXCEPT; diff --git a/include/bitcoin/node/protocols/protocol_transaction_out_70013.hpp b/include/bitcoin/node/protocols/protocol_transaction_out_70013.hpp index 687ee6a3..289c012f 100644 --- a/include/bitcoin/node/protocols/protocol_transaction_out_70013.hpp +++ b/include/bitcoin/node/protocols/protocol_transaction_out_70013.hpp @@ -44,8 +44,7 @@ class BCN_API protocol_transaction_out_70013 protected: /// Handle chaser events. - bool handle_chase(const code& ec, chase event_, - event_value value) NOEXCEPT override; + bool handle_chase(const code& ec, event_value value) NOEXCEPT override; /// Capture the peer's minimum fee rate for announcements. virtual bool handle_receive_fee_filter(const code& ec, diff --git a/include/bitcoin/node/sessions/session.hpp b/include/bitcoin/node/sessions/session.hpp index ebc3d85b..0dff8aa2 100644 --- a/include/bitcoin/node/sessions/session.hpp +++ b/include/bitcoin/node/sessions/session.hpp @@ -65,11 +65,10 @@ class BCN_API session /// ----------------------------------------------------------------------- /// Set a chaser event. - virtual void notify(const code& ec, chase event_, - event_value value) const NOEXCEPT; + virtual void notify(const code& ec, event_value value) const NOEXCEPT; /// Set chaser event for the given subscriber only. - virtual void notify_one(object_key key, const code& ec, chase event_, + virtual void notify_one(object_key key, const code& ec, event_value value) const NOEXCEPT; /// Subscribe to chaser events (requires node strand). diff --git a/src/chasers/chaser.cpp b/src/chasers/chaser.cpp index 7d6f7c35..3e0ea12c 100644 --- a/src/chasers/chaser.cpp +++ b/src/chasers/chaser.cpp @@ -93,16 +93,15 @@ object_key chaser::subscribe_chase(event_notifier&& handler) NOEXCEPT return node_.subscribe_chase(std::move(handler)); } -void chaser::notify(const code& ec, chase event_, - event_value value) const NOEXCEPT +void chaser::notify(const code& ec, event_value value) const NOEXCEPT { - node_.notify(ec, event_, value); + node_.notify(ec, value); } -void chaser::notify_one(object_key key, const code& ec, chase event_, +void chaser::notify_one(object_key key, const code& ec, event_value value) const NOEXCEPT { - node_.notify_one(key, ec, event_, value); + node_.notify_one(key, ec, value); } // Strand. diff --git a/src/chasers/chaser_check.cpp b/src/chasers/chaser_check.cpp index bb27cc7c..5ca4c019 100644 --- a/src/chasers/chaser_check.cpp +++ b/src/chasers/chaser_check.cpp @@ -99,7 +99,7 @@ code chaser_check::start() NOEXCEPT const auto added = set_unassociated(); LOGN("Fork point (" << requested_ << ") unassociated (" << added << ")."); - SUBSCRIBE_CHASE(handle_chase, _1, _2, _3); + SUBSCRIBE_CHASE(handle_chase, _1, _2); return error::success; } @@ -110,21 +110,19 @@ void chaser_check::stopping(const code& ec) NOEXCEPT chaser::stopping(ec); } -bool chaser_check::handle_chase(const code&, chase event_, - event_value value) NOEXCEPT +bool chaser_check::handle_chase(const code&, event_value value) NOEXCEPT { if (closed()) return false; - switch (event_) + switch (to_chase(value)) { // Performance. // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ case chase::starved: { // When a channel becomes starved notify other(s) to split work. - BC_ASSERT(std::holds_alternative(value)); - POST(do_starved, std::get(value)); + POST(do_starved, to_payload(value).channel); break; } // Track downloaded. @@ -138,30 +136,32 @@ bool chaser_check::handle_chase(const code&, chase event_, } case chase::checked: { - BC_ASSERT(std::holds_alternative(value)); - POST(do_checked, std::get(value)); + POST(do_checked, to_payload(value).height); break; } case chase::regressed: + { + POST(do_regressed, + to_payload(value).branch_point); + break; + } case chase::disorganized: { - BC_ASSERT(std::holds_alternative(value)); - POST(do_regressed, std::get(value)); + POST(do_regressed, + to_payload(value).branch_point); break; } // Track chain. // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ case chase::headers: { - BC_ASSERT(std::holds_alternative(value)); - POST(do_headers, std::get(value)); + POST(do_headers, to_payload(value).branch_point); break; } case chase::valid: ////case chase::prevalid: { - BC_ASSERT(std::holds_alternative(value)); - POST(do_advanced, std::get(value)); + POST(do_advanced, to_payload(value).height); break; } case chase::stop: @@ -239,12 +239,12 @@ void chaser_check::do_starved(object_t self) NOEXCEPT speeds_.erase(slowest); // Notify slow channel to split itself (in favor of 'self' channel). - notify_one(slow, error::success, chase::split, self); + notify_one(slow, error::success, chases::split{ self }); return; } // With no speeds recorded there may still be channels with work. - notify(error::success, chase::stall, self); + notify(error::success, chases::stall{ self }); } // update @@ -352,7 +352,7 @@ void chaser_check::do_regressed(height_t branch_point) NOEXCEPT set_position(branch_point); stop_tracking(); maps_.clear(); - notify(error::success, chase::purge, branch_point); + notify(error::success, chases::purge{ branch_point }); } // track downloaded in order (to move download window) @@ -396,7 +396,7 @@ void chaser_check::do_bump(height_t) NOEXCEPT // Notify validator that no more blocks are coming. if (height == requested_) - notify(error::success, chase::windowed, height); + notify(error::success, chases::windowed{ height }); } do_headers({}); @@ -410,7 +410,7 @@ void chaser_check::do_headers(height_t) NOEXCEPT BC_ASSERT(stranded()); if (const auto added = set_unassociated(); is_nonzero(added)) - notify(error::success, chase::download, added); + notify(error::success, chases::download{ added }); } // get/put hashes @@ -456,7 +456,7 @@ void chaser_check::do_put_hashes(const map_ptr& map, return; if (set_map(map)) - notify(error::success, chase::download, map->size()); + notify(error::success, chases::download{ map->size() }); handler(error::success); } diff --git a/src/chasers/chaser_confirm.cpp b/src/chasers/chaser_confirm.cpp index 4fe53701..2a164d29 100644 --- a/src/chasers/chaser_confirm.cpp +++ b/src/chasers/chaser_confirm.cpp @@ -53,7 +53,7 @@ code chaser_confirm::start() NOEXCEPT // Construct is too early to create the unstarted timer. stale_timer_ = std::make_shared(log, strand()); - SUBSCRIBE_CHASE(handle_chase, _1, _2, _3); + SUBSCRIBE_CHASE(handle_chase, _1, _2); return error::success; } @@ -74,8 +74,7 @@ void chaser_confirm::do_stopping(const code&) NOEXCEPT } } -bool chaser_confirm::handle_chase(const code&, chase event_, - event_value value) NOEXCEPT +bool chaser_confirm::handle_chase(const code&, event_value value) NOEXCEPT { if (closed()) return false; @@ -85,7 +84,7 @@ bool chaser_confirm::handle_chase(const code&, chase event_, if (suspended()) return true; - switch (event_) + switch (to_chase(value)) { case chase::resume: case chase::start: @@ -96,17 +95,19 @@ bool chaser_confirm::handle_chase(const code&, chase event_, } case chase::valid: { - // value is validated block height. - BC_ASSERT(std::holds_alternative(value)); - POST(do_validated, std::get(value)); + POST(do_validated, to_payload(value).height); break; } case chase::regressed: + { + POST(do_regressed, + to_payload(value).branch_point); + break; + } case chase::disorganized: { - // value is regression branch_point. - BC_ASSERT(std::holds_alternative(value)); - POST(do_regressed, std::get(value)); + POST(do_regressed, + to_payload(value).branch_point); break; } case chase::stop: @@ -297,7 +298,7 @@ void chaser_confirm::organize(header_states& fork, const header_links& popped, // Prevent stall by posting internal event, avoiding external handlers. // Posts new work, preventing recursion and releasing reorganization lock. - handle_chase(error::success, chase::bump, height_t{}); + handle_chase(error::success, chases::bump{}); } bool chaser_confirm::confirm_block(const header_link& link, size_t height, @@ -362,14 +363,14 @@ bool chaser_confirm::notify_block(const code& ec, size_t height, if (ec) { // UNCONFIRMABLE BLOCK (not a fault but discontinue) - notify(ec, chase::unconfirmable, link); + notify(ec, chases::unconfirmable{ link }); fire(events::block_unconfirmable, height); LOGR("Unconfirmable block [" << height << "] " << ec.message()); return false; } // CONFIRMABLE BLOCK - notify(error::success, chase::confirmable, link); + notify(error::success, chases::confirmable{ link }); fire(events::block_confirmed, height); LOGV("Block confirmed: " << height << (bypass ? " (bypass)" : "")); return true; @@ -387,7 +388,7 @@ bool chaser_confirm::set_reorganized(const header_link& link, if (!archive().pop_confirmed()) return false; - notify(error::success, chase::reorganized, link); + notify(error::success, chases::reorganized{ link }); fire(events::block_reorganized, confirmed_height); LOGV("Block reorganized: " << confirmed_height); return true; @@ -420,7 +421,7 @@ bool chaser_confirm::set_organized(const header_link& link, if (!query.push_confirmed(link, !is_under_checkpoint(confirmed_height))) return false; - notify(error::success, chase::organized, link); + notify(error::success, chases::organized{ link }); fire(events::block_organized, confirmed_height); LOGV("Block organized: " << confirmed_height); @@ -452,7 +453,7 @@ void chaser_confirm::announce(const header_link& link, height_t) NOEXCEPT // Announce newly-organized blocks when confirmed chain is current. if (is_current_chain(true)) { - notify(error::success, chase::block, link); + notify(error::success, chases::block{ link }); start_stale_timer(); } } @@ -489,7 +490,7 @@ void chaser_confirm::handle_stale_timer(const code& ec) NOEXCEPT return; } - notify(error::success, chase::stale, {}); + notify(error::success, chases::stale{}); } BC_POP_WARNING() diff --git a/src/chasers/chaser_estimate.cpp b/src/chasers/chaser_estimate.cpp index 254bdda2..46da0282 100644 --- a/src/chasers/chaser_estimate.cpp +++ b/src/chasers/chaser_estimate.cpp @@ -46,7 +46,7 @@ code chaser_estimate::start() NOEXCEPT { if (node_settings().fee_estimate_enabled()) { - SUBSCRIBE_CHASE(handle_chase, _1, _2, _3); + SUBSCRIBE_CHASE(handle_chase, _1, _2); } return error::success; @@ -108,8 +108,7 @@ bool chaser_estimate::initialized() const NOEXCEPT // ---------------------------------------------------------------------------- // protected -bool chaser_estimate::handle_chase(const code&, chase event_, - event_value value) NOEXCEPT +bool chaser_estimate::handle_chase(const code&, event_value value) NOEXCEPT { if (closed()) return false; @@ -118,7 +117,7 @@ bool chaser_estimate::handle_chase(const code&, chase event_, ////if (suspended()) //// return true; - switch (event_) + switch (to_chase(value)) { // chase::block is only sent when current. This is captured as a cheap // way to test currency for initialization. Once initialized it is not @@ -128,8 +127,7 @@ bool chaser_estimate::handle_chase(const code&, chase event_, { if (!initialized()) { - BC_ASSERT(std::holds_alternative(value)); - POST(do_initialize, std::get(value)); + POST(do_initialize, to_payload(value).link); } break; @@ -138,8 +136,8 @@ bool chaser_estimate::handle_chase(const code&, chase event_, { if (initialized()) { - BC_ASSERT(std::holds_alternative(value)); - POST(do_organized, std::get(value)); + POST(do_organized, + to_payload(value).link); } break; @@ -148,8 +146,8 @@ bool chaser_estimate::handle_chase(const code&, chase event_, { if (initialized()) { - BC_ASSERT(std::holds_alternative(value)); - POST(do_reorganized, std::get(value)); + POST(do_reorganized, + to_payload(value).link); } break; diff --git a/src/chasers/chaser_snapshot.cpp b/src/chasers/chaser_snapshot.cpp index 59c766a9..04df0e3f 100644 --- a/src/chasers/chaser_snapshot.cpp +++ b/src/chasers/chaser_snapshot.cpp @@ -65,15 +65,14 @@ code chaser_snapshot::start() NOEXCEPT ////if (enabled_confirm_) //// confirm_ = std::max(archive().get_top_confirmed(), checkpoint()); - SUBSCRIBE_CHASE(handle_chase, _1, _2, _3); + SUBSCRIBE_CHASE(handle_chase, _1, _2); return error::success; } // event handlers // ---------------------------------------------------------------------------- -bool chaser_snapshot::handle_chase(const code&, chase event_, - event_value value) NOEXCEPT +bool chaser_snapshot::handle_chase(const code&, event_value value) NOEXCEPT { if (closed()) return false; @@ -83,7 +82,7 @@ bool chaser_snapshot::handle_chase(const code&, chase event_, if (suspended()) return true; - switch (event_) + switch (to_chase(value)) { // blocks first and headers first (checked) messages ////case chase::blocks: @@ -119,14 +118,12 @@ bool chaser_snapshot::handle_chase(const code&, chase event_, if (pruned_.load(std::memory_order_relaxed)) break; - BC_ASSERT(std::holds_alternative(value)); - POST(do_prune, std::get(value)); + POST(do_prune, to_payload(value).link); break; } case chase::snap: { - BC_ASSERT(std::holds_alternative(value)); - POST(do_snap, std::get(value)); + POST(do_snap, to_payload(value).height); break; } default: diff --git a/src/chasers/chaser_storage.cpp b/src/chasers/chaser_storage.cpp index 5ab3a18e..40e2e9d9 100644 --- a/src/chasers/chaser_storage.cpp +++ b/src/chasers/chaser_storage.cpp @@ -50,7 +50,7 @@ code chaser_storage::start() NOEXCEPT // Construct is too early to create the unstarted timer. disk_timer_ = std::make_shared(log, strand(), seconds{1}); - SUBSCRIBE_CHASE(handle_chase, _1, _2, _3); + SUBSCRIBE_CHASE(handle_chase, _1, _2); return error::success; } @@ -73,13 +73,12 @@ void chaser_storage::do_stopping(const code&) NOEXCEPT // event handlers // ---------------------------------------------------------------------------- -bool chaser_storage::handle_chase(const code&, chase event_, - event_value) NOEXCEPT +bool chaser_storage::handle_chase(const code&, event_value value) NOEXCEPT { if (closed()) return false; - switch (event_) + switch (to_chase(value)) { case chase::space: { @@ -166,7 +165,7 @@ void chaser_storage::do_reload() NOEXCEPT else { // Recovery from disk full message sent in addition to chase::resume. - notify(error::success, chase::unfull, {}); + notify(error::success, chases::unfull{}); resume(); const auto span = duration_cast(logger::now() - start); diff --git a/src/chasers/chaser_template.cpp b/src/chasers/chaser_template.cpp index 3582a915..b235165b 100644 --- a/src/chasers/chaser_template.cpp +++ b/src/chasers/chaser_template.cpp @@ -43,15 +43,14 @@ chaser_template::chaser_template(full_node& node) NOEXCEPT // TODO: initialize template state. code chaser_template::start() NOEXCEPT { - SUBSCRIBE_CHASE(handle_chase, _1, _2, _3); + SUBSCRIBE_CHASE(handle_chase, _1, _2); return error::success; } // event handlers // ---------------------------------------------------------------------------- -bool chaser_template::handle_chase(const code&, chase event_, - event_value value) NOEXCEPT +bool chaser_template::handle_chase(const code&, event_value value) NOEXCEPT { if (closed()) return false; @@ -62,12 +61,11 @@ bool chaser_template::handle_chase(const code&, chase event_, return true; // TODO: also handle confirmed/unconfirmed. - switch (event_) + switch (to_chase(value)) { case chase::transaction: { - BC_ASSERT(std::holds_alternative(value)); - POST(do_transaction, std::get(value)); + POST(do_transaction, to_payload(value).link); break; } case chase::stop: diff --git a/src/chasers/chaser_transaction.cpp b/src/chasers/chaser_transaction.cpp index 9dcc6789..eb08c329 100644 --- a/src/chasers/chaser_transaction.cpp +++ b/src/chasers/chaser_transaction.cpp @@ -46,7 +46,7 @@ chaser_transaction::chaser_transaction(full_node& node) NOEXCEPT code chaser_transaction::start() NOEXCEPT { - SUBSCRIBE_CHASE(handle_chase, _1, _2, _3); + SUBSCRIBE_CHASE(handle_chase, _1, _2); POST(do_bump); return error::success; } @@ -54,13 +54,12 @@ code chaser_transaction::start() NOEXCEPT // event handlers // ---------------------------------------------------------------------------- -bool chaser_transaction::handle_chase(const code&, chase event_, - event_value) NOEXCEPT +bool chaser_transaction::handle_chase(const code&, event_value value) NOEXCEPT { if (closed()) return false; - switch (event_) + switch (to_chase(value)) { case chase::organized: case chase::reorganized: @@ -167,7 +166,7 @@ void chaser_transaction::do_submit(const transactions_cptr& txs, bool test, } fire(events::tx_archived, to_rate(tx)); - notify(error::success, chase::transaction, transaction_t{ link }); + notify(error::success, chases::transaction{ link }); } handler(error::success, {}); diff --git a/src/chasers/chaser_validate.cpp b/src/chasers/chaser_validate.cpp index 03101aed..06786311 100644 --- a/src/chasers/chaser_validate.cpp +++ b/src/chasers/chaser_validate.cpp @@ -66,16 +66,17 @@ code chaser_validate::start() NOEXCEPT if (const auto ec = start_batch()) return fault(ec); - SUBSCRIBE_CHASE(handle_chase, _1, _2, _3); + SUBSCRIBE_CHASE(handle_chase, _1, _2); return error::success; } -bool chaser_validate::handle_chase(const code&, chase event_, - event_value value) NOEXCEPT +bool chaser_validate::handle_chase(const code&, event_value value) NOEXCEPT { if (closed()) return false; + const auto event_ = to_chase(value); + // Latch recovering from disk full, before suspension is lifted. // Because in-flight blocks are lost, reset position when backlog clears. if (event_ == chase::unfull) @@ -113,27 +114,28 @@ bool chaser_validate::handle_chase(const code&, chase event_, } case chase::checked: { - // value is checked block height. - BC_ASSERT(std::holds_alternative(value)); - POST(do_checked, std::get(value)); + POST(do_checked, to_payload(value).height); break; } case chase::windowed: { - // value is last height in window. Called directly (not posted): - // the drain must never depend on scheduling, which saturated - // validations can exhaust for the entire window (strand for - // admission-side control, never for release-side). - BC_ASSERT(std::holds_alternative(value)); + // Called directly (not posted): the drain must never depend on + // scheduling, which saturated validations can exhaust for the + // entire window (strand for admission-side control, never for + // release-side). process_batch(is_residual()); break; } case chase::regressed: + { + POST(do_regressed, + to_payload(value).branch_point); + break; + } case chase::disorganized: { - // value is regression branch_point. - BC_ASSERT(std::holds_alternative(value)); - POST(do_regressed, std::get(value)); + POST(do_regressed, + to_payload(value).branch_point); break; } case chase::stop: @@ -267,7 +269,7 @@ void chaser_validate::complete_block(const code& ec, const header_link& link, if (is_zero(validate_backlog_.load()) && !stranded()) { // Prevent stall by posting internal event, avoiding external handlers. - handle_chase({}, chase::bump, height_t{}); + handle_chase({}, chases::bump{}); } // Node errors are fatal (or disk full recoverable). @@ -327,14 +329,15 @@ void chaser_validate::notify_block(const code& ec, size_t height, if (ec) { // INVALID BLOCK (not a fault but discontinue) - if (!startup) notify(ec, chase::unvalid, link); + if (!startup) notify(ec, chases::unvalid{ link }); fire(events::block_unconfirmable, height); LOGR("Invalid block [" << height << "] " << ec.message()); return; } // VALID BLOCK - if (!startup) notify(ec, chase::valid, possible_wide_cast(height)); + if (!startup) + notify(ec, chases::valid{ possible_wide_cast(height) }); fire(events::block_validated, height); LOGV("Block validated: " << height << (bypass ? " (bypass)" : "")); } diff --git a/src/full_node.cpp b/src/full_node.cpp index a538b38a..e031e657 100644 --- a/src/full_node.cpp +++ b/src/full_node.cpp @@ -115,7 +115,7 @@ void full_node::do_run(const result_handler& handler) NOEXCEPT // Bump sequential chasers to their starting heights. // This will kick off lagging validations even if not current. - do_notify(error::success, chase::start, height_t{}); + do_notify(error::success, chases::start{}); // Start services after network is running. net::do_run(handler); @@ -156,7 +156,7 @@ void full_node::do_close() NOEXCEPT chaser_snapshot_.stopping(network::error::service_stopped); chaser_storage_.stopping(network::error::service_stopped); - event_subscriber_.stop(network::error::service_stopped, chase::stop, {}); + event_subscriber_.stop(network::error::service_stopped, chases::stop{}); net::do_close(); } @@ -204,36 +204,34 @@ void full_node::put_hashes(const map_ptr& map, // Events. // ---------------------------------------------------------------------------- -void full_node::notify(const code& ec, chase event_, - event_value value) NOEXCEPT +void full_node::notify(const code& ec, event_value value) NOEXCEPT { boost::asio::post(strand(), std::bind(&full_node::do_notify, - this, ec, event_, value)); + this, ec, value)); } // private -void full_node::do_notify(const code& ec, chase event_, - event_value value) NOEXCEPT +void full_node::do_notify(const code& ec, event_value value) NOEXCEPT { BC_ASSERT(stranded()); - event_subscriber_.notify(ec, event_, value); + event_subscriber_.notify(ec, value); } -void full_node::notify_one(object_key key, const code& ec, chase event_, +void full_node::notify_one(object_key key, const code& ec, event_value value) NOEXCEPT { boost::asio::post(strand(), std::bind(&full_node::do_notify_one, - this, key, ec, event_, value)); + this, key, ec, value)); } // private -void full_node::do_notify_one(object_key key, const code& ec, chase event_, +void full_node::do_notify_one(object_key key, const code& ec, event_value value) NOEXCEPT { BC_ASSERT(stranded()); - event_subscriber_.notify_one(key, ec, event_, value); + event_subscriber_.notify_one(key, ec, value); } object_key full_node::subscribe_chase(event_notifier&& handler) NOEXCEPT @@ -263,7 +261,7 @@ void full_node::do_subscribe_chase(const event_notifier& handler, void full_node::unsubscribe_chase(object_key key) NOEXCEPT { - notify_one(key, network::error::service_stopped, chase::stop, {}); + notify_one(key, network::error::service_stopped, chases::stop{}); } // Suspensions. @@ -284,7 +282,7 @@ bool full_node::resume() NOEXCEPT } LOGS("Resuming network."); - notify(error::success, chase::resume, {}); + notify(error::success, chases::resume{}); return net::resume(); } @@ -293,7 +291,7 @@ void full_node::suspend(const code& ec) NOEXCEPT { LOGS("Suspending network, " << ec.message()); net::suspend(ec); - notify(error::suspended_channel, chase::suspend, {}); + notify(error::suspended_channel, chases::suspend{}); } void full_node::fault(const code& ec) NOEXCEPT @@ -302,7 +300,7 @@ void full_node::fault(const code& ec) NOEXCEPT { LOGF("Disk full [" << query_.get_space() << "] bytes required following, " << ec.message()); - notify(ec, chase::space, {}); + notify(ec, chases::space{}); } else if (query_.is_fault()) { diff --git a/src/protocols/protocol_block_in_31800.cpp b/src/protocols/protocol_block_in_31800.cpp index 803efa29..27994db6 100644 --- a/src/protocols/protocol_block_in_31800.cpp +++ b/src/protocols/protocol_block_in_31800.cpp @@ -49,7 +49,7 @@ void protocol_block_in_31800::start() NOEXCEPT return; // Events subscription is asynchronous, events may be missed. - subscribe_chase(BIND(handle_chase, _1, _2, _3)); + subscribe_chase(BIND(handle_chase, _1, _2)); SUBSCRIBE_CHANNEL(block, handle_receive_block, _1, _2); protocol_performer::start(); } @@ -95,14 +95,14 @@ bool protocol_block_in_31800::is_idle() const NOEXCEPT return map_->empty(); } -bool protocol_block_in_31800::handle_chase(const code&, chase event_, +bool protocol_block_in_31800::handle_chase(const code&, event_value value) NOEXCEPT { // Do not pass ec to stopped as it is not a call status. if (stopped()) return false; - switch (event_) + switch (to_chase(value)) { case chase::split: { @@ -131,14 +131,12 @@ bool protocol_block_in_31800::handle_chase(const code&, chase event_, // There are count blocks to download at/above given header. // chase::headers is only sent for current candidate chain, and this // chase::download is only sent as a consequence of chase::headers. - BC_ASSERT(std::holds_alternative(value)); - POST(do_get_downloads, std::get(value)); + POST(do_get_downloads, to_payload(value).count); break; } case chase::report: { - BC_ASSERT(std::holds_alternative(value)); - POST(do_report, std::get(value)); + POST(do_report, to_payload(value).sequence); break; } case chase::stop: @@ -324,7 +322,7 @@ bool protocol_block_in_31800::handle_receive_block(const code& ec, LOGR("Block failed check [" << encode_hash(hash) << ":" << height << "] from [" << opposite() << "] " << code.message()); - notify(error::success, chase::unchecked, link); + notify(error::success, chases::unchecked{ link }); fire(events::block_unconfirmable, height); stop(code); return false; @@ -351,7 +349,7 @@ bool protocol_block_in_31800::handle_receive_block(const code& ec, LOGP("Downloaded block [" << encode_hash(hash) << ":" << height << "] from [" << opposite() << "]."); - notify(ec, chase::checked, height); + notify(ec, chases::checked{ height }); fire(events::block_archived, height); count(block.serialized_size(true)); @@ -425,7 +423,7 @@ void protocol_block_in_31800::handle_get_hashes(const code& ec, if (map->empty()) { - notify(error::success, chase::starved, events_key()); + notify(error::success, chases::starved{ events_key() }); return; } diff --git a/src/protocols/protocol_block_out_106.cpp b/src/protocols/protocol_block_out_106.cpp index ed7699da..18b8d023 100644 --- a/src/protocols/protocol_block_out_106.cpp +++ b/src/protocols/protocol_block_out_106.cpp @@ -51,7 +51,7 @@ void protocol_block_out_106::start() NOEXCEPT return; // Events subscription is asynchronous, events may be missed. - subscribe_chase(BIND(handle_chase, _1, _2, _3)); + subscribe_chase(BIND(handle_chase, _1, _2)); SUBSCRIBE_CHANNEL(get_data, handle_receive_get_data, _1, _2); SUBSCRIBE_CHANNEL(get_blocks, handle_receive_get_blocks, _1, _2); protocol_peer::start(); @@ -68,20 +68,18 @@ void protocol_block_out_106::stopping(const code& ec) NOEXCEPT // handle events (block) // ---------------------------------------------------------------------------- -bool protocol_block_out_106::handle_chase(const code&, chase event_, +bool protocol_block_out_106::handle_chase(const code&, event_value value) NOEXCEPT { // Do not pass ec to stopped as it is not a call status. if (stopped() || superseded()) return false; - switch (event_) + switch (to_chase(value)) { case chase::block: { - // value is organized block pk. - BC_ASSERT(std::holds_alternative(value)); - POST(do_announce, std::get(value)); + POST(do_announce, to_payload(value).link); break; } default: diff --git a/src/protocols/protocol_header_out_70012.cpp b/src/protocols/protocol_header_out_70012.cpp index 49e23952..2e8f49a4 100644 --- a/src/protocols/protocol_header_out_70012.cpp +++ b/src/protocols/protocol_header_out_70012.cpp @@ -59,20 +59,18 @@ void protocol_header_out_70012::stopping(const code& ec) NOEXCEPT // handle events (block) // ---------------------------------------------------------------------------- -bool protocol_header_out_70012::handle_chase(const code&, chase event_, +bool protocol_header_out_70012::handle_chase(const code&, event_value value) NOEXCEPT { // Do not pass ec to stopped as it is not a call status. if (stopped()) return false; - switch (event_) + switch (to_chase(value)) { case chase::block: { - // value is organized block pk. - BC_ASSERT(std::holds_alternative(value)); - POST(do_announce, std::get(value)); + POST(do_announce, to_payload(value).link); break; } default: @@ -130,7 +128,7 @@ bool protocol_header_out_70012::handle_receive_send_headers(const code& ec, return false; // Events subscription is asynchronous, events may be missed. - subscribe_chase(BIND(handle_chase, _1, _2, _3)); + subscribe_chase(BIND(handle_chase, _1, _2)); return false; } diff --git a/src/protocols/protocol_observer.cpp b/src/protocols/protocol_observer.cpp index faf45e36..586047f0 100644 --- a/src/protocols/protocol_observer.cpp +++ b/src/protocols/protocol_observer.cpp @@ -43,7 +43,7 @@ void protocol_observer::start() NOEXCEPT return; // Events subscription is asynchronous, events may be missed. - subscribe_chase(BIND(handle_chase, _1, _2, _3)); + subscribe_chase(BIND(handle_chase, _1, _2)); if (relay_disallowed_) { @@ -66,14 +66,13 @@ void protocol_observer::stopping(const code& ec) NOEXCEPT // handle events (suspend) // ---------------------------------------------------------------------------- -bool protocol_observer::handle_chase(const code& ec, chase event_, - event_value) NOEXCEPT +bool protocol_observer::handle_chase(const code& ec, event_value value) NOEXCEPT { // Do not pass ec to stopped as it is not a call status. if (stopped()) return false; - switch (event_) + switch (to_chase(value)) { case chase::suspend: { diff --git a/src/protocols/protocol_peer.cpp b/src/protocols/protocol_peer.cpp index e67b88f4..259ac16c 100644 --- a/src/protocols/protocol_peer.cpp +++ b/src/protocols/protocol_peer.cpp @@ -81,16 +81,15 @@ bool protocol_peer::was_announced(const system::hash_digest& hash) const NOEXCEP // Events notification. // ---------------------------------------------------------------------------- -void protocol_peer::notify(const code& ec, chase event_, - event_value value) const NOEXCEPT +void protocol_peer::notify(const code& ec, event_value value) const NOEXCEPT { - session_->notify(ec, event_, value); + session_->notify(ec, value); } -void protocol_peer::notify_one(object_key key, const code& ec, chase event_, +void protocol_peer::notify_one(object_key key, const code& ec, event_value value) const NOEXCEPT { - session_->notify_one(key, ec, event_, value); + session_->notify_one(key, ec, value); } } // namespace node diff --git a/src/protocols/protocol_transaction_out_106.cpp b/src/protocols/protocol_transaction_out_106.cpp index a4a66553..370df746 100644 --- a/src/protocols/protocol_transaction_out_106.cpp +++ b/src/protocols/protocol_transaction_out_106.cpp @@ -44,7 +44,7 @@ void protocol_transaction_out_106::start() NOEXCEPT return; // Events subscription is asynchronous, events may be missed. - subscribe_chase(BIND(handle_chase, _1, _2, _3)); + subscribe_chase(BIND(handle_chase, _1, _2)); SUBSCRIBE_CHANNEL(get_data, handle_receive_get_data, _1, _2); protocol_peer::start(); @@ -62,20 +62,18 @@ void protocol_transaction_out_106::stopping(const code& ec) NOEXCEPT // handle events (transaction) // ---------------------------------------------------------------------------- -bool protocol_transaction_out_106::handle_chase(const code&, chase event_, +bool protocol_transaction_out_106::handle_chase(const code&, event_value value) NOEXCEPT { // Do not pass ec to stopped as it is not a call status. if (stopped()) return false; - switch (event_) + switch (to_chase(value)) { case chase::transaction: { - // value is organized tx pk. - BC_ASSERT(std::holds_alternative(value)); - POST(do_announce, std::get(value)); + POST(do_announce, to_payload(value).link); break; } default: diff --git a/src/protocols/protocol_transaction_out_70013.cpp b/src/protocols/protocol_transaction_out_70013.cpp index 4c45f0a9..859ea349 100644 --- a/src/protocols/protocol_transaction_out_70013.cpp +++ b/src/protocols/protocol_transaction_out_70013.cpp @@ -69,13 +69,13 @@ void protocol_transaction_out_70013::do_send_fee_filter() NOEXCEPT } bool protocol_transaction_out_70013::handle_chase(const code& ec, - chase event_, event_value value) NOEXCEPT + event_value value) NOEXCEPT { // Do not pass ec to stopped as it is not a call status. if (stopped()) return false; - switch (event_) + switch (to_chase(value)) { case chase::block: case chase::stale: @@ -89,7 +89,7 @@ bool protocol_transaction_out_70013::handle_chase(const code& ec, } } - return protocol_transaction_out_70001::handle_chase(ec, event_, value); + return protocol_transaction_out_70001::handle_chase(ec, value); } // Inbound (feefilter). diff --git a/src/sessions/session.cpp b/src/sessions/session.cpp index 9088b546..74c92c3f 100644 --- a/src/sessions/session.cpp +++ b/src/sessions/session.cpp @@ -77,16 +77,15 @@ void session::put_hashes(const map_ptr& map, // Events. // ---------------------------------------------------------------------------- -void session::notify(const code& ec, chase event_, - event_value value) const NOEXCEPT +void session::notify(const code& ec, event_value value) const NOEXCEPT { - node_.notify(ec, event_, value); + node_.notify(ec, value); } -void session::notify_one(object_key key, const code& ec, chase event_, +void session::notify_one(object_key key, const code& ec, event_value value) const NOEXCEPT { - node_.notify_one(key, ec, event_, value); + node_.notify_one(key, ec, value); } object_key session::subscribe_chase(event_notifier&& handler) NOEXCEPT