@@ -84,16 +84,17 @@ void protocol_explore::start() NOEXCEPT
8484
8585 SUBSCRIBE_EXPLORE (handle_get_block, _1, _2, _3, _4, _5, _6, _7);
8686 SUBSCRIBE_EXPLORE (handle_get_block_header, _1, _2, _3, _4, _5, _6);
87+ SUBSCRIBE_EXPLORE (handle_get_block_header_context, _1, _2, _3, _4, _5, _6);
88+ SUBSCRIBE_EXPLORE (handle_get_block_details, _1, _2, _3, _4, _5, _6);
8789 SUBSCRIBE_EXPLORE (handle_get_block_txs, _1, _2, _3, _4, _5, _6);
88- SUBSCRIBE_EXPLORE (handle_get_block_fees, _1, _2, _3, _4, _5, _6);
8990 SUBSCRIBE_EXPLORE (handle_get_block_filter, _1, _2, _3, _4, _5, _6, _7);
9091 SUBSCRIBE_EXPLORE (handle_get_block_filter_hash, _1, _2, _3, _4, _5, _6, _7);
9192 SUBSCRIBE_EXPLORE (handle_get_block_filter_header, _1, _2, _3, _4, _5, _6, _7);
9293 SUBSCRIBE_EXPLORE (handle_get_block_tx, _1, _2, _3, _4, _5, _6, _7, _8);
9394
9495 SUBSCRIBE_EXPLORE (handle_get_tx, _1, _2, _3, _4, _5, _6);
9596 SUBSCRIBE_EXPLORE (handle_get_tx_header, _1, _2, _3, _4, _5);
96- SUBSCRIBE_EXPLORE (handle_get_tx_fee , _1, _2, _3, _4, _5);
97+ SUBSCRIBE_EXPLORE (handle_get_tx_details , _1, _2, _3, _4, _5);
9798
9899 SUBSCRIBE_EXPLORE (handle_get_inputs, _1, _2, _3, _4, _5, _6);
99100 SUBSCRIBE_EXPLORE (handle_get_input, _1, _2, _3, _4, _5, _6, _7);
@@ -318,56 +319,81 @@ bool protocol_explore::handle_get_block_header(const code& ec,
318319 return true ;
319320}
320321
321- bool protocol_explore::handle_get_block_txs (const code& ec,
322- interface::block_txs , uint8_t , uint8_t media,
322+ bool protocol_explore::handle_get_block_header_context (const code& ec,
323+ interface::block_header_context , uint8_t , uint8_t media,
323324 std::optional<hash_cptr> hash, std::optional<uint32_t > height) NOEXCEPT
324325{
325326 if (stopped (ec))
326327 return false ;
327328
329+ // states:
330+ // block_valid
331+ // block_confirmable
332+ // block_unconfirmable
333+ // get_header_state->unvalidated can be no header or no txs.
334+ // //const auto state = query.get_header_state(link);
335+ // //if (state == database::error::unvalidated)
336+ // //{
337+ // // send_not_found();
338+ // // return true;
339+ // //}
340+
328341 const auto & query = archive ();
329- if (const auto hashes = query.get_tx_keys (to_header (height, hash));
330- !hashes.empty ())
342+ const auto link = to_header (height, hash);
343+ database::context context{};
344+ if (query.get_context (context, link))
331345 {
332- const auto size = hashes.size () * hash_size;
333346 switch (media)
334347 {
335348 case data:
336- {
337- const auto data = pointer_cast<const uint8_t >(hashes.data ());
338- send_chunk (to_chunk ({ data, std::next (data, size) }));
349+ send_chunk (to_little_endian_size (context.flags ));
339350 return true ;
340- }
341351 case text:
342- {
343- const auto data = pointer_cast<const uint8_t >(hashes.data ());
344- send_text (encode_base16 ({ data, std::next (data, size) }));
352+ send_text (encode_base16 (to_little_endian_size (context.flags )));
345353 return true ;
346- }
347354 case json:
348- {
349- array out (hashes.size ());
350- std::ranges::transform (hashes, out.begin (),
351- [](const auto & hash) { return encode_hash (hash); });
352- send_json (out, two * size);
355+ send_json (context.flags , two * sizeof (context.flags ));
353356 return true ;
354- }
355357 }
356358 }
357359
358360 send_not_found ();
359361 return true ;
360362}
361363
362- bool protocol_explore::handle_get_block_fees (const code& ec,
363- interface::block_fees , uint8_t , uint8_t media,
364+ bool protocol_explore::handle_get_block_details (const code& ec,
365+ interface::block_details , uint8_t , uint8_t media,
364366 std::optional<hash_cptr> hash, std::optional<uint32_t > height) NOEXCEPT
365367{
366368 if (stopped (ec))
367369 return false ;
368370
369- if (const auto fees = archive ().get_block_fees (to_header (height, hash));
370- fees != max_uint64)
371+ const auto & query = archive ();
372+ const auto link = to_header (height, hash);
373+ const auto state = query.get_block_state (link);
374+
375+ // get_block_state->unassociated can be no header or no txs.
376+ if (state == database::error::unassociated)
377+ {
378+ send_not_found ();
379+ return true ;
380+ }
381+
382+ // states:
383+ // unvalidated
384+ // block_valid
385+ // block_confirmable
386+ // block_unconfirmable
387+
388+ // both txs table (can get from details)
389+ // const auto size = query.get_block_size(link);
390+ // const auto count = query.get_tx_count(link);
391+
392+ // TODO:
393+ // query (whole block and all prevouts, same as get_block_fees)
394+ // fees, claim, reward, subsidy, weight, size, count.
395+
396+ if (const auto fees = query.get_block_fees (link); fees != max_uint64)
371397 {
372398 switch (media)
373399 {
@@ -387,6 +413,47 @@ bool protocol_explore::handle_get_block_fees(const code& ec,
387413 return true ;
388414}
389415
416+ bool protocol_explore::handle_get_block_txs (const code& ec,
417+ interface::block_txs, uint8_t , uint8_t media,
418+ std::optional<hash_cptr> hash, std::optional<uint32_t > height) NOEXCEPT
419+ {
420+ if (stopped (ec))
421+ return false ;
422+
423+ const auto & query = archive ();
424+ if (const auto hashes = query.get_tx_keys (to_header (height, hash));
425+ !hashes.empty ())
426+ {
427+ const auto size = hashes.size () * hash_size;
428+ switch (media)
429+ {
430+ case data:
431+ {
432+ const auto data = pointer_cast<const uint8_t >(hashes.data ());
433+ send_chunk (to_chunk ({ data, std::next (data, size) }));
434+ return true ;
435+ }
436+ case text:
437+ {
438+ const auto data = pointer_cast<const uint8_t >(hashes.data ());
439+ send_text (encode_base16 ({ data, std::next (data, size) }));
440+ return true ;
441+ }
442+ case json:
443+ {
444+ array out (hashes.size ());
445+ std::ranges::transform (hashes, out.begin (),
446+ [](const auto & hash) { return encode_hash (hash); });
447+ send_json (out, two * size);
448+ return true ;
449+ }
450+ }
451+ }
452+
453+ send_not_found ();
454+ return true ;
455+ }
456+
390457bool protocol_explore::handle_get_block_filter (const code& ec,
391458 interface::block_filter, uint8_t , uint8_t media, uint8_t type,
392459 std::optional<hash_cptr> hash, std::optional<uint32_t > height) NOEXCEPT
@@ -595,12 +662,14 @@ bool protocol_explore::handle_get_tx_header(const code& ec,
595662 return true ;
596663}
597664
598- bool protocol_explore::handle_get_tx_fee (const code& ec, interface::tx_fee,
599- uint8_t , uint8_t media, const hash_cptr& hash) NOEXCEPT
665+ bool protocol_explore::handle_get_tx_details (const code& ec,
666+ interface::tx_details, uint8_t , uint8_t media,
667+ const hash_cptr& hash) NOEXCEPT
600668{
601669 if (stopped (ec))
602670 return false ;
603671
672+ // TODO: expand details to include tx.size and tx.weight.
604673 const auto & query = archive ();
605674 if (const auto fee = query.get_tx_fee (query.to_tx (*hash));
606675 fee != max_uint64)
0 commit comments