2121#include < algorithm>
2222#include < optional>
2323#include < ranges>
24+ #include < set>
2425#include < utility>
2526#include < bitcoin/node/define.hpp>
2627#include < bitcoin/node/parse/parse.hpp>
@@ -40,6 +41,27 @@ using namespace network::messages::peer;
4041using namespace std ::placeholders;
4142using namespace boost ::json;
4243
44+ using point_set = std::set<chain::point>;
45+ using outpoint_set = std::set<chain::outpoint>;
46+
47+ DEFINE_JSON_TO_TAG (point_set)
48+ {
49+ point_set out{};
50+ for (const auto & point : value.as_array ())
51+ out.insert (value_to<chain::point>(point));
52+
53+ return out;
54+ }
55+
56+ DEFINE_JSON_TO_TAG (outpoint_set)
57+ {
58+ outpoint_set out{};
59+ for (const auto & outpoint : value.as_array ())
60+ out.insert (value_to<chain::outpoint>(outpoint));
61+
62+ return out;
63+ }
64+
4365// Avoiding namespace conflict.
4466using object_type = network::rpc::object_t ;
4567
@@ -70,7 +92,7 @@ void protocol_explore::start() NOEXCEPT
7092 SUBSCRIBE_EXPLORE (handle_get_block_tx, _1, _2, _3, _4, _5, _6, _7, _8);
7193
7294 SUBSCRIBE_EXPLORE (handle_get_tx, _1, _2, _3, _4, _5, _6);
73- SUBSCRIBE_EXPLORE (handle_get_tx_block , _1, _2, _3, _4, _5);
95+ SUBSCRIBE_EXPLORE (handle_get_tx_header , _1, _2, _3, _4, _5);
7496 SUBSCRIBE_EXPLORE (handle_get_tx_fee, _1, _2, _3, _4, _5);
7597
7698 SUBSCRIBE_EXPLORE (handle_get_inputs, _1, _2, _3, _4, _5, _6);
@@ -94,6 +116,7 @@ void protocol_explore::start() NOEXCEPT
94116void protocol_explore::stopping (const code& ec) NOEXCEPT
95117{
96118 BC_ASSERT (stranded ());
119+ stopping_.store (true );
97120 dispatcher_.stop (ec);
98121 protocol_html::stopping (ec);
99122}
@@ -532,37 +555,40 @@ bool protocol_explore::handle_get_tx(const code& ec, interface::tx, uint8_t,
532555 return true ;
533556}
534557
535- bool protocol_explore::handle_get_tx_block (const code& ec, interface::tx_block ,
558+ bool protocol_explore::handle_get_tx_header (const code& ec, interface::tx_header ,
536559 uint8_t , uint8_t media, const hash_cptr& hash) NOEXCEPT
537560{
538561 if (stopped (ec))
539562 return false ;
540563
541564 const auto & query = archive ();
542- const auto block = query.to_confirmed_block (*hash);
543- if (block .is_terminal ())
565+ const auto link = query.to_confirmed_block (*hash);
566+ if (link .is_terminal ())
544567 {
545568 send_not_found ();
546569 return true ;
547570 }
548571
549- const auto key = query.get_header_key (block );
550- if (key == null_hash )
572+ const auto header = query.get_header (link );
573+ if (!header )
551574 {
552575 send_internal_server_error (database::error::integrity);
553576 return true ;
554577 }
555578
579+ constexpr auto size = chain::header::serialized_size ();
556580 switch (media)
557581 {
558582 case data:
559- send_chunk (to_chunk (key ));
583+ send_chunk (to_bin (*header, size ));
560584 return true ;
561585 case text:
562- send_text (encode_base16 (key ));
586+ send_text (to_hex (*header, size ));
563587 return true ;
564588 case json:
565- send_json (value_from (encode_hash (key)), two * hash_size);
589+ auto model = value_from (header);
590+ inject (model, {}, link);
591+ send_json (std::move (model), two * size);
566592 return true ;
567593 }
568594
@@ -893,12 +919,9 @@ bool protocol_explore::handle_get_output_spenders(const code& ec,
893919 return true ;
894920 }
895921
896- // TODO: dedup and lexical sort.
897- chain::points out (points.size ());
898- std::ranges::transform (points, out.begin (), [&](const auto & link) NOEXCEPT
899- {
900- return query.get_spender (link);
901- });
922+ point_set out{};
923+ for (const auto & point: points)
924+ out.insert (query.get_spender (point));
902925
903926 const auto size = out.size () * chain::point::serialized_size ();
904927 switch (media)
@@ -931,8 +954,10 @@ bool protocol_explore::handle_get_address(const code& ec, interface::address,
931954 return true ;
932955 }
933956
957+ // TODO: post queries to thread (both stopping() and this are stranded).
958+
934959 database::output_links outputs{};
935- if (!query.to_address_outputs (outputs, *hash))
960+ if (!query.to_address_outputs (stopping_, outputs, *hash))
936961 {
937962 send_internal_server_error (database::error::integrity);
938963 return true ;
@@ -944,14 +969,11 @@ bool protocol_explore::handle_get_address(const code& ec, interface::address,
944969 return true ;
945970 }
946971
947- // TODO: dedup and lexical sort.
948- chain::points out (outputs.size ());
949- std::ranges::transform (outputs, out.begin (), [&](const auto & link) NOEXCEPT
950- {
951- return query.get_spent (link);
952- });
972+ outpoint_set out{};
973+ for (const auto & output: outputs)
974+ out.insert (query.get_spent (output));
953975
954- const auto size = out.size () * chain::point ::serialized_size ();
976+ const auto size = out.size () * chain::outpoint ::serialized_size ();
955977 switch (media)
956978 {
957979 case data:
0 commit comments