2121
2222#include < map>
2323#include < memory>
24- #include < set>
2524#include < bitcoin/server/channels/channels.hpp>
2625#include < bitcoin/server/define.hpp>
2726#include < bitcoin/server/interfaces/interfaces.hpp>
@@ -206,12 +205,40 @@ class BCS_API protocol_electrum
206205 rpc_interface::mempool_get_info) NOEXCEPT;
207206
208207protected:
208+ using point = system::chain::point;
209+ using hash_digest = system::hash_digest;
210+ using history = database::history;
209211 using unspents = database::unspents;
210212 using histories = database::histories;
211- using hash_digest = system::hash_digest;
212213 enum class notify_t { address, scripthash, scriptpubkey };
213- typedef std::function<void (const code&, const hash_digest&,
214- const hash_digest&)> status_handler;
214+
215+ // Status hash optimization (~200 bytes).
216+ struct midstate
217+ {
218+ hash_digest status{};
219+ system::stream::out::fast stream{ status };
220+ system::hash::sha256::fast writer{ stream };
221+ };
222+
223+ // Subscription to address/scripthash/scruptpubkey.
224+ struct address_subscription
225+ {
226+ notify_t type{};
227+ midstate state{};
228+ database::address_link cursor{};
229+ };
230+
231+ // Subscription to outpoint.
232+ struct outpoint_subscription
233+ {
234+ database::history outpoint{};
235+ database::histories spenders{};
236+
237+ bool operator ==(const outpoint_subscription& other) const NOEXCEPT
238+ {
239+ return outpoint == other.outpoint && spenders == other.spenders ;
240+ }
241+ };
215242
216243 // / Common implementation for block_header/s.
217244 void blockchain_block_headers (size_t starting, size_t quantity,
@@ -259,18 +286,22 @@ class BCS_API protocol_electrum
259286 void scripthash_notify (const hash_digest& status, const hash_digest& hash,
260287 notify_t type) NOEXCEPT;
261288
289+ code get_scripthash_history (hash_digest& status, address_subscription& sub,
290+ const hash_digest& hash, size_t limit=max_size_t ) NOEXCEPT;
291+
262292 // / Outpoint.
263293 // / -----------------------------------------------------------------------
264294
265- void do_outpoint_subscribe (const system::chain::point& prevout,
266- const std::string& hint) NOEXCEPT;
295+ void do_outpoint_subscribe (const point& prevout) NOEXCEPT;
267296 void complete_outpoint_subscribe (const code& ec,
268- const system::chain::point& prevout,
269- const std::string& hint) NOEXCEPT;
270- void do_outpoint_unsubscribe (const system::chain::point& prevout) NOEXCEPT;
297+ const outpoint_subscription& sub, const point& prevout) NOEXCEPT;
298+ void do_outpoint_unsubscribe (const point& prevout) NOEXCEPT;
271299 void complete_outpoint_unsubscribe (bool found) NOEXCEPT;
272300 void outpoint_notify (const std::unique_ptr<interface::object_t >& status,
273- const system::chain::point& prevout) NOEXCEPT;
301+ const point& prevout) NOEXCEPT;
302+
303+ bool get_outpoint_history (outpoint_subscription& sub,
304+ const point& prevout) const NOEXCEPT;
274305
275306 // / Utilities.
276307 // / -----------------------------------------------------------------------
@@ -296,44 +327,28 @@ class BCS_API protocol_electrum
296327 BIND_SAFE (BIND_SHARED (method, args)));
297328 }
298329
299- // Status hash optimization (~200 bytes).
300- struct midstate
301- {
302- hash_digest status{};
303- system::stream::out::fast stream{ status };
304- system::hash::sha256::fast writer{ stream };
305- };
306-
307- // Subscription to address/scripthash/scruptpubkey.
308- struct subscription
309- {
310- notify_t type{};
311- midstate state{};
312- database::address_link cursor{};
313- };
314-
315330 // Aliases.
316331 using array_t = network::rpc::array_t ;
317332 using object_t = network::rpc::object_t ;
318333 using version_t = protocol_electrum_version;
319334 static constexpr electrum::version minimum = version_t ::minimum;
320335 static constexpr electrum::version maximum = version_t ::maximum;
321336
322- // Status utilities.
323- code get_scripthash_status (hash_digest& out, subscription& sub,
324- const hash_digest& hash, size_t limit=max_size_t ) NOEXCEPT;
325- bool get_outpoint_statuses (std::vector<interface::object_t >& out,
326- const system::chain::point& prevout) const NOEXCEPT;
327- bool get_outpoint_status (interface::object_t & out,
328- const system::chain::point& prevout) const NOEXCEPT;
329- bool send_outpoint_status (const system::chain::point& prevout,
330- const std::string& hint) NOEXCEPT;
331-
332337 // Transformations.
333338 static array_t transform (const unspents& unspents) NOEXCEPT;
334339 static array_t transform (const histories& histories) NOEXCEPT;
335340 static hash_digest to_status (const histories& histories) NOEXCEPT;
336341 static std::string to_method_name (notify_t type) NOEXCEPT;
342+ static bool is_valid_hint (const std::string& hint) NOEXCEPT;
343+ static object_t to_outpoint_status (size_t output_height) NOEXCEPT;
344+ static object_t to_outpoint_status (size_t output_height,
345+ const history& history) NOEXCEPT;
346+ static object_t to_outpoint_status (
347+ const outpoint_subscription& sub) NOEXCEPT;
348+ std::unique_ptr<object_t > make_status (
349+ size_t output_height) const NOEXCEPT;
350+ std::unique_ptr<object_t > make_status (size_t output_height,
351+ const history& history) const NOEXCEPT;
337352
338353 // Compute server.features.hosts value from config.
339354 object_t self_hosts () const NOEXCEPT;
@@ -367,8 +382,8 @@ class BCS_API protocol_electrum
367382 network::asio::strand notification_strand_;
368383
369384 // These are protected by notification strand.
370- std::set<system::chain:: point> outpoint_subscriptions_{};
371- std::map<hash_digest, subscription > address_subscriptions_{};
385+ std::map< point, outpoint_subscription > outpoint_subscriptions_{};
386+ std::map<hash_digest, address_subscription > address_subscriptions_{};
372387};
373388
374389} // namespace server
0 commit comments