Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions include/bitcoin/server/interfaces/explore.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ struct explore_methods
/// ?format=data|text|json (via query string).
/// -----------------------------------------------------------------------

/// /v1/configuration {1}

/// /v1/top {1}

/// /v1/block/hash/[bkhash] {1}
Expand All @@ -118,8 +120,11 @@ struct explore_methods
/// /v1/block/hash/[bkhash]/header {1}
/// /v1/block/height/[height]/header {1}

/// /v1/block/hash/[bkhash]/fees {1}
/// /v1/block/height/[height]/fees {1}
/// /v1/block/hash/[bkhash]/header/context {1}
/// /v1/block/height/[height]/header/context {1}

/// /v1/block/hash/[bkhash]/details {1}
/// /v1/block/height/[height]/details {1}

/// /v1/block/hash/[bkhash]/filter/[type] {1}
/// /v1/block/height/[height]/filter/[type] {1}
Expand Down
164 changes: 102 additions & 62 deletions src/protocols/protocol_explore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,14 +248,13 @@ bool protocol_explore::handle_get_configuration(const code& ec,
return true;
}

const auto& query = archive();

value model{};
auto& object = model.emplace_object();
object.emplace("address", query.address_enabled());
object.emplace("filter", query.filter_enabled());

send_json(std::move(model), 25);
boost::json::object object{};
object["address"] = archive().address_enabled();
object["filter"] = archive().filter_enabled();
object["witness"] = network_settings().witness_node();
object["retarget"] = system_settings().forks.retarget;
object["difficult"] = system_settings().forks.difficult;
send_json(std::move(object), 32);
return true;
}

Expand Down Expand Up @@ -352,38 +351,62 @@ bool protocol_explore::handle_get_block_header_context(const code& ec,
if (stopped(ec))
return false;

// states:
// block_valid
// block_confirmable
// block_unconfirmable
// get_header_state->unvalidated can be no header or no txs.
////const auto state = query.get_header_state(link);
////if (state == database::error::unvalidated)
////{
//// send_not_found();
//// return true;
////}
if (media != json)
{
send_not_acceptable();
return true;
}

database::context context{};
const auto& query = archive();
const auto link = to_header(height, hash);
database::context context{};
if (query.get_context(context, link))
if (!query.get_context(context, link))
{
switch (media)
send_not_found();
return true;
}

boost::json::object object{};
object["hash"] = encode_hash(query.get_header_key(link));
object["height"] = context.height;
object["mtp"] = context.mtp;

// The "state" element implies transactions are associated.
if (query.is_associated(link))
{
const auto check = system_settings().top_checkpoint().height();
const auto bypass = context.height < check || query.is_milestone(link);
object["state"] = boost::json::object
{
case data:
send_chunk(to_little_endian_size(context.flags));
return true;
case text:
send_text(encode_base16(to_little_endian_size(context.flags)));
return true;
case json:
send_json(context.flags, two * sizeof(context.flags));
return true;
}
{ "wire", query.get_block_size(link) },
{ "count", query.get_tx_count(link) },
{ "validated", bypass || query.is_validated(link) },
{ "confirmed", check || query.is_confirmed_block(link) },
{ "confirmable", bypass || query.is_confirmable(link) },
{ "unconfirmable", !bypass && query.is_unconfirmable(link) }
};
}

send_not_found();
// All modern configurable forks.
object["forks"] = boost::json::object
{
{ "bip30", context.is_enabled(chain::flags::bip30_rule) },
{ "bip34", context.is_enabled(chain::flags::bip34_rule) },
{ "bip66", context.is_enabled(chain::flags::bip66_rule) },
{ "bip65", context.is_enabled(chain::flags::bip65_rule) },
{ "bip90", context.is_enabled(chain::flags::bip90_rule) },
{ "bip68", context.is_enabled(chain::flags::bip68_rule) },
{ "bip112", context.is_enabled(chain::flags::bip112_rule) },
{ "bip113", context.is_enabled(chain::flags::bip113_rule) },
{ "bip141", context.is_enabled(chain::flags::bip141_rule) },
{ "bip143", context.is_enabled(chain::flags::bip143_rule) },
{ "bip147", context.is_enabled(chain::flags::bip147_rule) },
{ "bip42", context.is_enabled(chain::flags::bip42_rule) },
{ "bip341", context.is_enabled(chain::flags::bip341_rule) },
{ "bip342", context.is_enabled(chain::flags::bip342_rule) }
};

send_json(std::move(object), 256);
return true;
}

Expand All @@ -394,48 +417,65 @@ bool protocol_explore::handle_get_block_details(const code& ec,
if (stopped(ec))
return false;

if (media != json)
{
send_not_acceptable();
return true;
}

database::context context{};
const auto& query = archive();
const auto link = to_header(height, hash);
const auto state = query.get_block_state(link);

// get_block_state->unassociated can be no header or no txs.
if (state == database::error::unassociated)
// Missing header.
if (!query.get_context(context, link))
{
send_not_found();
return true;
}

// states:
// unvalidated
// block_valid
// block_confirmable
// block_unconfirmable
const auto block = query.get_block(link, true);

// both txs table (can get from details)
//const auto size = query.get_block_size(link);
//const auto count = query.get_tx_count(link);
// Unassociated header.
if (!block)
{
send_not_found();
return true;
}

// TODO:
// query (whole block and all prevouts, same as get_block_fees)
// fees, claim, reward, subsidy, weight, size, count.
// Internal population (optimization).
block->populate();

if (const auto fees = query.get_block_fees(link); fees != max_uint64)
// False if missing prevouts (not ready).
if (!query.populate_without_metadata(*block))
{
switch (media)
{
case data:
send_chunk(to_little_endian_size(fees));
return true;
case text:
send_text(encode_base16(to_little_endian_size(fees)));
return true;
case json:
send_json(fees, two * sizeof(fees));
return true;
}
send_not_found();
return true;
}

send_not_found();
const auto fees = block->fees();
const auto& settings = system_settings();
const auto bip16 = context.is_enabled(chain::flags::bip16_rule);
const auto bip42 = context.is_enabled(chain::flags::bip42_rule);
const auto bip141 = context.is_enabled(chain::flags::bip141_rule);
const auto subsidy = chain::block::subsidy(context.height,
settings.subsidy_interval_blocks, settings.initial_subsidy(), bip42);

boost::json::object object{};
object["hash"] = encode_hash(block->hash());
object["height"] = context.height;
object["count"] = block->transactions();
object["sigops"] = block->signature_operations(bip16, bip141);
object["segregated"] = block->is_segregated();
object["nominal"] = block->serialized_size(false);
object["maximal"] = block->serialized_size(true);
object["weight"] = block->weight();
object["fees"] = fees;
object["subsidy"] = subsidy;
object["reward"] = ceilinged_add(fees, subsidy);
object["claim"] = block->claim();

send_json(std::move(object), 512);
return true;
}

Expand Down Expand Up @@ -1181,7 +1221,7 @@ bool protocol_explore::handle_get_address_balance(const code& ec,
}

void protocol_explore::do_get_address_balance(uint8_t media, bool turbo,
const system::hash_cptr& hash) NOEXCEPT
const hash_cptr& hash) NOEXCEPT
{
BC_ASSERT(!stranded());

Expand Down
Loading