diff --git a/include/bitcoin/server/define.hpp b/include/bitcoin/server/define.hpp index 0b8d0ce0..0b2c5e9c 100644 --- a/include/bitcoin/server/define.hpp +++ b/include/bitcoin/server/define.hpp @@ -37,9 +37,6 @@ #define BCS_INTERNAL BC_HELPER_DLL_LOCAL #endif -/// Prevent bogus vc++ warnings on protocol. -BC_DISABLE_WARNING(DIAMOND_INHERITANCE) - /// Augment limited xcode placeholder defines (10 vs. common 20). /// --------------------------------------------------------------------------- #if defined (HAVE_XCODE) diff --git a/include/bitcoin/server/interfaces/electrum.hpp b/include/bitcoin/server/interfaces/electrum.hpp index c262f3b0..ece3ab24 100644 --- a/include/bitcoin/server/interfaces/electrum.hpp +++ b/include/bitcoin/server/interfaces/electrum.hpp @@ -32,8 +32,8 @@ struct electrum_methods static constexpr std::tuple methods { /// Blockchain methods. - method<"blockchain.block.header", number_t, number_t>{ "height", "cp_height" }, - method<"blockchain.block.headers", number_t, number_t, number_t>{ "start_height", "count", "cp_height" }, + method<"blockchain.block.header", number_t, optional<0.0>>{ "height", "cp_height" }, + method<"blockchain.block.headers", number_t, number_t, optional<0.0>>{ "start_height", "count", "cp_height" }, method<"blockchain.headers.subscribe">{}, method<"blockchain.estimatefee", number_t, optional<""_t>>{ "number", "mode" }, method<"blockchain.relayfee">{}, diff --git a/include/bitcoin/server/protocols/protocol_electrum.hpp b/include/bitcoin/server/protocols/protocol_electrum.hpp index bae5e85c..238d0562 100644 --- a/include/bitcoin/server/protocols/protocol_electrum.hpp +++ b/include/bitcoin/server/protocols/protocol_electrum.hpp @@ -48,8 +48,13 @@ class BCS_API protocol_electrum } void start() NOEXCEPT override; + void stopping(const code& ec) NOEXCEPT override; protected: + /// Handlers (event subscription). + bool handle_event(const code&, node::chase event_, + node::event_value) NOEXCEPT; + /// Handlers (blockchain). void handle_blockchain_block_header(const code& ec, rpc_interface::blockchain_block_header, double height, diff --git a/src/protocols/protocol_electrum.cpp b/src/protocols/protocol_electrum.cpp index 4f6a5907..331d47b5 100644 --- a/src/protocols/protocol_electrum.cpp +++ b/src/protocols/protocol_electrum.cpp @@ -47,6 +47,9 @@ void protocol_electrum::start() NOEXCEPT if (started()) return; + // Events subscription is asynchronous, events may be missed. + subscribe_events(BIND(handle_event, _1, _2, _3)); + // Blockchain methods. SUBSCRIBE_RPC(handle_blockchain_block_header, _1, _2, _3, _4); SUBSCRIBE_RPC(handle_blockchain_block_headers, _1, _2, _3, _4, _5); @@ -78,17 +81,51 @@ void protocol_electrum::start() NOEXCEPT protocol_rpc::start(); } +void protocol_electrum::stopping(const code& ec) NOEXCEPT +{ + // Unsubscriber race is ok. + BC_ASSERT(stranded()); + unsubscribe_events(); + protocol_rpc::stopping(ec); +} + +// Handlers (event subscription). +// ---------------------------------------------------------------------------- + +bool protocol_electrum::handle_event(const code&, node::chase event_, + node::event_value) NOEXCEPT +{ + // Do not pass ec to stopped as it is not a call status. + if (stopped()) + return false; + + switch (event_) + { + case node::chase::suspend: + { + break; + } + default: + { + break; + } + } + + return true; +} + // Handlers (blockchain). // ---------------------------------------------------------------------------- +// electrum-protocol.readthedocs.io/en/latest/protocol-basics.html#block-headers void protocol_electrum::handle_blockchain_block_header(const code& ec, - rpc_interface::blockchain_block_header, double , - double ) NOEXCEPT + rpc_interface::blockchain_block_header, double height, + double cp_height) NOEXCEPT { - if (stopped(ec)) return; - send_code(error::not_implemented); + handle_blockchain_block_headers(ec, {}, height, 1, cp_height); } +// electrum-protocol.readthedocs.io/en/latest/protocol-basics.html#block-headers void protocol_electrum::handle_blockchain_block_headers(const code& ec, rpc_interface::blockchain_block_headers, double , double , double ) NOEXCEPT @@ -120,6 +157,8 @@ void protocol_electrum::handle_blockchain_headers_subscribe(const code& ec, header->to_data(writer); BC_ASSERT(writer); + // TODO: signal header subscription. + // TODO: idempotent subscribe to chase::organized via session/chaser/node. // TODO: upon notification send just the header notified by the link. // TODO: it is client responsibility to deal with reorgs and race gaps. @@ -269,6 +308,7 @@ void protocol_electrum::handle_server_features(const code& ec, send_code(error::not_implemented); } +// This is not actually a subscription method. void protocol_electrum::handle_server_peers_subscribe(const code& ec, rpc_interface::server_peers_subscribe) NOEXCEPT {