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
4 changes: 2 additions & 2 deletions data/bs.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ connect_timeout_seconds = 5
channel_handshake_seconds = 30
# The time limit for obtaining seed addresses, defaults to 30.
channel_germination_seconds = 30
# The time between ping messages, defaults to 5.
channel_heartbeat_minutes = 5
# The time between ping messages, defaults to 10.
channel_heartbeat_minutes = 10
# The inactivity time limit for any connection, defaults to 30.
channel_inactivity_minutes = 30
# The age limit for any connection, defaults to 1440.
Expand Down
68 changes: 47 additions & 21 deletions src/protocols/bitcoind/protocol_bitcoind_blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ bool protocol_bitcoind_blockchain::handle_get_chain_tx_stats(const code& ec,
return false;

const auto& query = archive();
auto link = query.to_confirmed(query.get_top_confirmed());
auto link = query.to_top_confirmed();

// The block defaults to the confirmed top, and must be on the chain.
if (!blockhash.empty())
Expand Down Expand Up @@ -575,11 +575,11 @@ bool protocol_bitcoind_blockchain::handle_get_tx_out(const code& ec,
return true;
}

const auto top = query.get_top_confirmed();
const auto header_link = query.to_confirmed(top);
size_t top{};
const auto header_link = query.to_top_confirmed();
const auto output = query.get_output(output_link);
const auto tx_link = query.to_output_tx(output_link);
if (!output || tx_link.is_terminal() || header_link.is_terminal())
if (!output || tx_link.is_terminal() || !query.get_height(top, header_link))
{
send_error(error::bitcoind::internal_error);
return true;
Expand Down Expand Up @@ -844,11 +844,17 @@ void protocol_bitcoind_blockchain::do_scan_tx_out_set(
code ec{};
size_t txouts{};
database::unspent_coins coins{};
size_t top{};
const auto& query = archive();
const auto top = query.get_top_confirmed();
const auto link = query.to_confirmed(top);
const auto link = query.to_top_confirmed();
const auto bip30 = query.envelope().forks.bip30;

if (!query.get_height(top, link))
{
POST(fail, error::bitcoind::internal_error, gate);
return;
}

if (query.address_enabled())
{
// Indexed candidates avoid the full scan, so the scanned coin count
Expand Down Expand Up @@ -1103,11 +1109,16 @@ bool protocol_bitcoind_blockchain::handle_get_chain_states(const code& ec,
if (stopped(ec))
return false;

size_t candidate{};
const auto& query = archive();
const auto candidate = query.get_top_candidate();
const auto candidate_link = query.to_top_candidate();
if (!query.get_height(candidate, candidate_link))
{
send_error(error::bitcoind::internal_error);
return true;
}

auto link = query.to_confirmed(query.get_top_confirmed());
auto entry = chain_states_entry(query, link, 1.0, true);
auto entry = chain_states_entry(query, query.to_top_confirmed(), 1.0, true);
if (entry.empty())
{
send_error(error::bitcoind::internal_error);
Expand All @@ -1122,9 +1133,7 @@ bool protocol_bitcoind_blockchain::handle_get_chain_states(const code& ec,
size_t fork{};
const auto span = query.get_validated_fork(fork);
const auto validated = progress(fork + span.size(), candidate);

link = query.to_candidate(candidate);
entry = chain_states_entry(query, link, validated, false);
entry = chain_states_entry(query, candidate_link, validated, false);
if (entry.empty())
{
send_error(error::bitcoind::internal_error);
Expand All @@ -1151,9 +1160,14 @@ bool protocol_bitcoind_blockchain::handle_get_chain_tips(const code& ec,

// Two indexes only: confirmed (active) and candidate (strongest headers);
// weak/reorged branches live in the organizer tree and are not exposed.
size_t confirmed{};
const auto& query = archive();
const auto confirmed = query.get_top_confirmed();
const auto confirmed_link = query.to_confirmed(confirmed);
const auto confirmed_link = query.to_top_confirmed();
if (!query.get_height(confirmed, confirmed_link))
{
send_error(error::bitcoind::internal_error);
return true;
}

array_t tips
{
Expand All @@ -1167,15 +1181,21 @@ bool protocol_bitcoind_blockchain::handle_get_chain_tips(const code& ec,
};

// The candidate is a distinct top only where it forks above confirmed.
const auto candidate = query.get_top_candidate();
size_t candidate{};
const auto candidate_link = query.to_top_candidate();
if (!query.get_height(candidate, candidate_link))
{
send_error(error::bitcoind::internal_error);
return true;
}

const auto branchlen = floored_subtract(candidate, query.get_fork());
if (!is_zero(branchlen))
{
// Parent traversal is reorg-stable without the reorg lock. A hole in
// the branch makes it headers-only, otherwise valid-headers; candidate
// is the strongest valid chain so is never invalid or valid-fork.
database::header_links branch{};
const auto candidate_link = query.to_candidate(candidate);
if (query.get_ancestry(branch, candidate_link, branchlen))
{
const auto present = std::all_of(branch.cbegin(), branch.cend(),
Expand Down Expand Up @@ -1206,7 +1226,7 @@ bool protocol_bitcoind_blockchain::handle_get_deployment_info(const code& ec,
return false;

const auto& query = archive();
auto link = query.to_confirmed(query.get_top_confirmed());
auto link = query.to_top_confirmed();

// The block defaults to the confirmed top.
if (!blockhash.empty())
Expand Down Expand Up @@ -1364,8 +1384,7 @@ bool protocol_bitcoind_blockchain::handle_get_difficulty(const code& ec,
return false;

const auto& query = archive();
const auto top = query.get_top_confirmed();
const auto header = query.get_header(query.to_confirmed(top));
const auto header = query.get_header(query.to_top_confirmed());
if (!header)
{
send_error(error::bitcoind::internal_error);
Expand Down Expand Up @@ -1959,11 +1978,18 @@ bool protocol_bitcoind_blockchain::wait_done(

void protocol_bitcoind_blockchain::send_top() NOEXCEPT
{
size_t top{};
const auto& query = archive();
const auto top = query.get_top_confirmed();
const auto link = query.to_top_confirmed();
if (!query.get_height(top, link))
{
send_error(error::bitcoind::internal_error);
return;
}

send_result(object_t
{
{ "hash", encode_hash(query.get_header_key(query.to_confirmed(top))) },
{ "hash", encode_hash(query.get_header_key(link)) },
{ "height", top }
});
}
Expand Down
6 changes: 3 additions & 3 deletions src/protocols/bitcoind/protocol_bitcoind_mining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,11 +163,11 @@ bool protocol_bitcoind_mining::handle_get_mining_info(const code& ec,
if (stopped(ec))
return false;

size_t height{};
const auto& query = archive();
const auto height = query.get_top_confirmed();
const auto link = query.to_confirmed(height);
const auto link = query.to_top_confirmed();
const auto top = query.get_header(link);
if (!top)
if (!top || !query.get_height(height, link))
{
send_error(error::bitcoind::internal_error);
return true;
Expand Down
19 changes: 13 additions & 6 deletions src/protocols/bitcoind/protocol_bitcoind_rest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -692,11 +692,11 @@ bool protocol_bitcoind_rest::handle_get_chain_information(const code& ec,
if (stopped(ec))
return false;

size_t blocks{};
const auto& query = archive();
const auto blocks = query.get_top_confirmed();
const auto link = query.to_confirmed(blocks);
const auto link = query.to_top_confirmed();
const auto header = query.get_header(link);
if (!header)
if (!header || !query.get_height(blocks, link))
{
send_not_found();
return true;
Expand Down Expand Up @@ -764,8 +764,15 @@ bool protocol_bitcoind_rest::handle_get_utxos(const code& ec,
utxos.push_back({ possible_narrow_cast<uint32_t>(height), output });
}

const auto top = query.get_top_confirmed();
const auto top_hash = query.get_header_key(query.to_confirmed(top));
size_t top{};
const auto top_link = query.to_top_confirmed();
if (!query.get_height(top, top_link))
{
send_internal_server_error(database::error::integrity);
return true;
}

const auto top_hash = query.get_header_key(top_link);

// The bip64 bitmap flags each outpoint hit, lsb first within each byte.
data_chunk bitmap(ceilinged_divide(hits.size(), 8u), 0x00);
Expand Down Expand Up @@ -846,7 +853,7 @@ bool protocol_bitcoind_rest::handle_get_deployment_info(const code& ec,
return false;

const auto& query = archive();
auto link = query.to_confirmed(query.get_top_confirmed());
auto link = query.to_top_confirmed();

// bitcoind reports an unknown block as a bad request here.
if (hash.has_value())
Expand Down
6 changes: 3 additions & 3 deletions src/protocols/btcd/protocol_btcd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -312,10 +312,10 @@ bool protocol_btcd::handle_rescan(const code& ec,
return true;
}

const auto top = query.get_top_confirmed();
const auto confirmed = query.to_confirmed(top);
size_t top{};
const auto confirmed = query.to_top_confirmed();
const auto header = query.get_header(confirmed);
if (!header)
if (!header || !query.get_height(top, confirmed))
{
send_error(error::btcd::internal_error);
return true;
Expand Down
10 changes: 5 additions & 5 deletions src/protocols/btcd/protocol_btcd_utility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,7 @@ bool protocol_btcd::handle_get_difficulty(const code& ec,
return false;

const auto& query = archive();
const auto top = query.get_top_confirmed();
const auto header = query.get_header(query.to_confirmed(top));
const auto header = query.get_header(query.to_top_confirmed());
if (!header)
{
send_error(error::btcd::internal_error);
Expand Down Expand Up @@ -270,10 +269,11 @@ bool protocol_btcd::handle_get_info(const code& ec,
if (stopped(ec))
return false;

size_t top{};
const auto& query = archive();
const auto top = query.get_top_confirmed();
const auto header = query.get_header(query.to_confirmed(top));
if (!header)
const auto link = query.to_top_confirmed();
const auto header = query.get_header(link);
if (!header || !query.get_height(top, link))
{
send_error(error::btcd::internal_error);
return true;
Expand Down
8 changes: 3 additions & 5 deletions src/protocols/electrum/protocol_electrum_headers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -371,12 +371,10 @@ void protocol_electrum::handle_blockchain_headers_subscribe(const code& ec,
return;
}

size_t top{};
const auto& query = archive();
const auto top = query.get_top_confirmed();
const auto link = query.to_confirmed(top);

// This is unlikely but possible due to a race condition during reorg.
if (link.is_terminal())
const auto link = query.to_top_confirmed();
if (!query.get_height(top, link))
{
send_code(error::electrum::daemon_error);
return;
Expand Down
2 changes: 1 addition & 1 deletion src/protocols/native/protocol_native_block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,7 @@ bool protocol_native::handle_get_block_subscribe(const code& ec,

// Return top block hash upon block subscription.
const auto& query = archive();
const auto link = query.to_confirmed(query.get_top_confirmed());
const auto link = query.to_top_confirmed();
if (const auto hash = query.get_header_key(link); hash != null_hash)
{
switch (media)
Expand Down
8 changes: 4 additions & 4 deletions src/serializers/bitcoind_json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -295,15 +295,15 @@ bool chain_info(network::rpc::object_t& out,
const node::query& query, const system::settings& settings,
bool pruned, bool current) NOEXCEPT
{
const auto blocks = query.get_top_confirmed();
size_t blocks{};
const auto headers = query.get_top_candidate();
const auto link = query.to_confirmed(blocks);
const auto link = query.to_top_confirmed();
const auto header = query.get_header(link);

uint256_t work{};
database::context context{};
if (!header || !query.get_branch_work(work, link) ||
!query.get_context(context, link))
if (!header || !query.get_height(blocks, link) ||
!query.get_branch_work(work, link) || !query.get_context(context, link))
return false;

const auto bits = header->bits();
Expand Down
Loading