@@ -248,14 +248,13 @@ bool protocol_explore::handle_get_configuration(const code& ec,
248248 return true ;
249249 }
250250
251- const auto & query = archive ();
252-
253- value model{};
254- auto & object = model.emplace_object ();
255- object.emplace (" address" , query.address_enabled ());
256- object.emplace (" filter" , query.filter_enabled ());
257-
258- send_json (std::move (model), 25 );
251+ boost::json::object object{};
252+ object[" address" ] = archive ().address_enabled ();
253+ object[" filter" ] = archive ().filter_enabled ();
254+ object[" witness" ] = network_settings ().witness_node ();
255+ object[" retarget" ] = system_settings ().forks .retarget ;
256+ object[" difficult" ] = system_settings ().forks .difficult ;
257+ send_json (std::move (object), 32 );
259258 return true ;
260259}
261260
@@ -352,38 +351,62 @@ bool protocol_explore::handle_get_block_header_context(const code& ec,
352351 if (stopped (ec))
353352 return false ;
354353
355- // states:
356- // block_valid
357- // block_confirmable
358- // block_unconfirmable
359- // get_header_state->unvalidated can be no header or no txs.
360- // //const auto state = query.get_header_state(link);
361- // //if (state == database::error::unvalidated)
362- // //{
363- // // send_not_found();
364- // // return true;
365- // //}
354+ if (media != json)
355+ {
356+ send_not_acceptable ();
357+ return true ;
358+ }
366359
360+ database::context context{};
367361 const auto & query = archive ();
368362 const auto link = to_header (height, hash);
369- database::context context{};
370- if (query.get_context (context, link))
363+ if (!query.get_context (context, link))
371364 {
372- switch (media)
365+ send_not_found ();
366+ return true ;
367+ }
368+
369+ boost::json::object object{};
370+ object[" hash" ] = encode_hash (query.get_header_key (link));
371+ object[" height" ] = context.height ;
372+ object[" mtp" ] = context.mtp ;
373+
374+ // The "state" element implies transactions are associated.
375+ if (query.is_associated (link))
376+ {
377+ const auto check = system_settings ().top_checkpoint ().height ();
378+ const auto bypass = context.height < check || query.is_milestone (link);
379+ object[" state" ] = boost::json::object
373380 {
374- case data:
375- send_chunk (to_little_endian_size (context.flags ));
376- return true ;
377- case text:
378- send_text (encode_base16 (to_little_endian_size (context.flags )));
379- return true ;
380- case json:
381- send_json (context.flags , two * sizeof (context.flags ));
382- return true ;
383- }
381+ { " wire" , query.get_block_size (link) },
382+ { " count" , query.get_tx_count (link) },
383+ { " validated" , bypass || query.is_validated (link) },
384+ { " confirmed" , check || query.is_confirmed_block (link) },
385+ { " confirmable" , bypass || query.is_confirmable (link) },
386+ { " unconfirmable" , !bypass && query.is_unconfirmable (link) }
387+ };
384388 }
385389
386- send_not_found ();
390+ // All modern configurable forks.
391+ object[" forks" ] = boost::json::object
392+ {
393+ { " bip30" , context.is_enabled (chain::flags::bip30_rule) },
394+ { " bip34" , context.is_enabled (chain::flags::bip34_rule) },
395+ { " bip66" , context.is_enabled (chain::flags::bip66_rule) },
396+ { " bip65" , context.is_enabled (chain::flags::bip65_rule) },
397+ { " bip90" , context.is_enabled (chain::flags::bip90_rule) },
398+ { " bip68" , context.is_enabled (chain::flags::bip68_rule) },
399+ { " bip112" , context.is_enabled (chain::flags::bip112_rule) },
400+ { " bip113" , context.is_enabled (chain::flags::bip113_rule) },
401+ { " bip141" , context.is_enabled (chain::flags::bip141_rule) },
402+ { " bip143" , context.is_enabled (chain::flags::bip143_rule) },
403+ { " bip147" , context.is_enabled (chain::flags::bip147_rule) },
404+ { " bip42" , context.is_enabled (chain::flags::bip42_rule) },
405+ { " bip341" , context.is_enabled (chain::flags::bip341_rule) },
406+ { " bip342" , context.is_enabled (chain::flags::bip342_rule) }
407+ };
408+
409+ send_json (std::move (object), 256 );
387410 return true ;
388411}
389412
@@ -394,48 +417,65 @@ bool protocol_explore::handle_get_block_details(const code& ec,
394417 if (stopped (ec))
395418 return false ;
396419
420+ if (media != json)
421+ {
422+ send_not_acceptable ();
423+ return true ;
424+ }
425+
426+ database::context context{};
397427 const auto & query = archive ();
398428 const auto link = to_header (height, hash);
399- const auto state = query.get_block_state (link);
400429
401- // get_block_state->unassociated can be no header or no txs .
402- if (state == database::error::unassociated )
430+ // Missing header.
431+ if (!query. get_context (context, link) )
403432 {
404433 send_not_found ();
405434 return true ;
406435 }
407436
408- // states:
409- // unvalidated
410- // block_valid
411- // block_confirmable
412- // block_unconfirmable
437+ const auto block = query.get_block (link, true );
413438
414- // both txs table (can get from details)
415- // const auto size = query.get_block_size(link);
416- // const auto count = query.get_tx_count(link);
439+ // Unassociated header.
440+ if (!block)
441+ {
442+ send_not_found ();
443+ return true ;
444+ }
417445
418- // TODO:
419- // query (whole block and all prevouts, same as get_block_fees)
420- // fees, claim, reward, subsidy, weight, size, count.
446+ // Internal population (optimization).
447+ block->populate ();
421448
422- if (const auto fees = query.get_block_fees (link); fees != max_uint64)
449+ // False if missing prevouts (not ready).
450+ if (!query.populate_without_metadata (*block))
423451 {
424- switch (media)
425- {
426- case data:
427- send_chunk (to_little_endian_size (fees));
428- return true ;
429- case text:
430- send_text (encode_base16 (to_little_endian_size (fees)));
431- return true ;
432- case json:
433- send_json (fees, two * sizeof (fees));
434- return true ;
435- }
452+ send_not_found ();
453+ return true ;
436454 }
437455
438- send_not_found ();
456+ const auto fees = block->fees ();
457+ const auto & settings = system_settings ();
458+ const auto bip16 = context.is_enabled (chain::flags::bip16_rule);
459+ const auto bip42 = context.is_enabled (chain::flags::bip42_rule);
460+ const auto bip141 = context.is_enabled (chain::flags::bip141_rule);
461+ const auto subsidy = chain::block::subsidy (context.height ,
462+ settings.subsidy_interval_blocks , settings.initial_subsidy (), bip42);
463+
464+ boost::json::object object{};
465+ object[" hash" ] = encode_hash (block->hash ());
466+ object[" height" ] = context.height ;
467+ object[" count" ] = block->transactions ();
468+ object[" sigops" ] = block->signature_operations (bip16, bip141);
469+ object[" segregated" ] = block->is_segregated ();
470+ object[" nominal" ] = block->serialized_size (false );
471+ object[" maximal" ] = block->serialized_size (true );
472+ object[" weight" ] = block->weight ();
473+ object[" fees" ] = fees;
474+ object[" subsidy" ] = subsidy;
475+ object[" reward" ] = ceilinged_add (fees, subsidy);
476+ object[" claim" ] = block->claim ();
477+
478+ send_json (std::move (object), 512 );
439479 return true ;
440480}
441481
@@ -1181,7 +1221,7 @@ bool protocol_explore::handle_get_address_balance(const code& ec,
11811221}
11821222
11831223void protocol_explore::do_get_address_balance (uint8_t media, bool turbo,
1184- const system:: hash_cptr& hash) NOEXCEPT
1224+ const hash_cptr& hash) NOEXCEPT
11851225{
11861226 BC_ASSERT (!stranded ());
11871227
0 commit comments