Archive of the libbitcoin Slack #general channel.
[network].bind = 0.0.0.0:8333 type configuration settings to replace the simple port-only config for inbound connections. The above will bind to all NICs on IPv4, and [network].bind = [::]:8333 will bind all on ipv6. Otherwise individual NICs (including local host) can be explicitly bound. This provides a huge increase in flexibility and was pretty simple - one day implementation and test. This also included a change to the [network].self = 42.42.42.42:8333 setting, which is used to advertised one's own address. This is no a multivalued setting, so that multiple public addresses can be advertised to peers. Note that bound endpoints and public addresses are independent for both security and flexibility purposes.bn -s.header_in protocol and added it to node sessions using protocol attachment overloading. The store query engine is exposed by protocol base. Used network::message locator heights generation, passed to database::get hashes(heights) and was quickly generating a proper locator sequence (although with no candidate/confirmed blocks these always start at genesis). Set up a SEND(get_headers) and a SUBSCRIBE(headers) and was immediately iterating over the full chain, storing each header. The store is fully concurrent, so need to worry about bouncing store calls to a common strand. Set up a few log messages and watched it run.headers_in protocol, less comments, log messages, and assertions:
void protocol_header_in::start() NOEXCEPT
{
if (started())
return;
SUBSCRIBE_CHANNEL2(headers, handle_receive_headers, _1, _2);
SEND1(create_get_headers(), handle_send, _1);
protocol::start();
}
bool protocol_header_in::handle_receive_headers(const code& ec, const headers::cptr& message) NOEXCEPT
{
if (stopped(ec))
return false;
for (const auto& header: message->header_ptrs)
{
if (!query().set(*header, database::context{}))
{
stop(network::error::protocol_violation);
return false;
}
};
if (message->header_ptrs.size() == max_get_headers)
{
SEND1(create_get_headers({ message->header_ptrs.back()->hash() }), handle_send, _1);
}
return true;
}
get_headers protocol_header_in::create_get_headers() NOEXCEPT
{
return create_get_headers(query().get_hashes(get_blocks::heights(query().get_top_candidate())));
}
get_headers protocol_header_in::create_get_headers(hashes&& hashes) NOEXCEPT
{
return { std::move(hashes), null_hash };
}handle_send is a base protocol nop handler.protocol::start()) are guaranteed stranded invocation, so they can be coded as if on a single thread. Above is still early, as the headers need to populate an in-memory graph and reorg into the candidate chain based on strength. But the protocol won't be any more complicated.span event, which accepts a starting time_point and diffs that with current time at invocation so that duration of asynchronous operations can be easily logged as events.--initchain now spits this out:
Please wait while initializing "D:/Source/evoskuil/libbitcoin-node/bin/x64/Release/v143/static/bitcoin/" directory... create::create_file(header_head) create::create_file(header_body) create::create_file(point_head) create::create_file(point_body) create::create_file(input_head) create::create_file(input_body) create::create_file(output_head) create::create_file(output_body) create::create_file(puts_head) create::create_file(puts_body) create::create_file(tx_head) create::create_file(tx_body) create::create_file(txs_head) create::create_file(txs_body) create::create_file(address_head) create::create_file(address_body) create::create_file(candidate_head) create::create_file(candidate_body) create::create_file(confirmed_head) create::create_file(confirmed_body) create::create_file(strong_tx_head) create::create_file(strong_tx_body) create::create_file(bootstrap_head) create::create_file(bootstrap_body) create::create_file(buffer_head) create::create_file(buffer_body) create::create_file(neutrino_head) create::create_file(neutrino_body) create::create_file(validated_bk_head) create::create_file(validated_bk_body) create::create_file(validated_tx_head) create::create_file(validated_tx_body) create::open_file(header_head) create::open_file(header_body) create::open_file(point_head) create::open_file(point_body) create::open_file(input_head) create::open_file(input_body) create::open_file(output_head) create::open_file(output_body) create::open_file(puts_head) create::open_file(puts_body) create::open_file(tx_head) create::open_file(tx_body) create::open_file(txs_head) create::open_file(txs_body) create::open_file(address_head) create::open_file(address_body) create::open_file(candidate_head) create::open_file(candidate_body) create::open_file(confirmed_head) create::open_file(confirmed_body) create::open_file(strong_tx_head) create::open_file(strong_tx_body) create::open_file(bootstrap_head) create::open_file(bootstrap_body) create::open_file(buffer_head) create::open_file(buffer_body) create::open_file(neutrino_head) create::open_file(neutrino_body) create::open_file(validated_bk_head) create::open_file(validated_bk_body) create::open_file(validated_tx_head) create::open_file(validated_tx_body) create::load_file(header_head) create::load_file(header_body) create::load_file(point_head) create::load_file(point_body) create::load_file(input_head) create::load_file(input_body) create::load_file(output_head) create::load_file(output_body) create::load_file(puts_head) create::load_file(puts_body) create::load_file(tx_head) create::load_file(tx_body) create::load_file(txs_head) create::load_file(txs_body) create::load_file(address_head) create::load_file(address_body) create::load_file(candidate_head) create::load_file(candidate_body) create::load_file(confirmed_head) create::load_file(confirmed_body) create::load_file(strong_tx_head) create::load_file(strong_tx_body) create::load_file(bootstrap_head) create::load_file(bootstrap_body) create::load_file(buffer_head) create::load_file(buffer_body) create::load_file(neutrino_head) create::load_file(neutrino_body) create::load_file(validated_bk_head) create::load_file(validated_bk_body) create::load_file(validated_tx_head) create::load_file(validated_tx_body) create::create_table(header_table) create::create_table(point_table) create::create_table(input_table) create::create_table(output_table) create::create_table(puts_table) create::create_table(tx_table) create::create_table(txs_table) create::create_table(address_table) create::create_table(candidate_table) create::create_table(confirmed_table) create::create_table(strong_tx_table) create::create_table(bootstrap_table) create::create_table(buffer_table) create::create_table(neutrino_table) create::create_table(validated_bk_table) create::create_table(validated_tx_table) create::unload_file(header_head) create::unload_file(header_body) create::unload_file(point_head) create::unload_file(point_body) create::unload_file(input_head) create::unload_file(input_body) create::unload_file(output_head) create::unload_file(output_body) create::unload_file(puts_head) create::unload_file(puts_body) create::unload_file(tx_head) create::unload_file(tx_body) create::unload_file(txs_head) create::unload_file(txs_body) create::unload_file(address_head) create::unload_file(address_body) create::unload_file(candidate_head) create::unload_file(candidate_body) create::unload_file(confirmed_head) create::unload_file(confirmed_body) create::unload_file(strong_tx_head) create::unload_file(strong_tx_body) create::unload_file(bootstrap_head) create::unload_file(bootstrap_body) create::unload_file(buffer_head) create::unload_file(buffer_body) create::unload_file(neutrino_head) create::unload_file(neutrino_body) create::unload_file(validated_bk_head) create::unload_file(validated_bk_body) create::unload_file(validated_tx_head) create::unload_file(validated_tx_body) create::close_file(header_head) create::close_file(header_body) create::close_file(point_head) create::close_file(point_body) create::close_file(input_head) create::close_file(input_body) create::close_file(output_head) create::close_file(output_body) create::close_file(puts_head) create::close_file(puts_body) create::close_file(tx_head) create::close_file(tx_body) create::close_file(txs_head) create::close_file(txs_body) create::close_file(address_head) create::close_file(address_body) create::close_file(candidate_head) create::close_file(candidate_body) create::close_file(confirmed_head) create::close_file(confirmed_body) create::close_file(strong_tx_head) create::close_file(strong_tx_body) create::close_file(bootstrap_head) create::close_file(bootstrap_body) create::close_file(buffer_head) create::close_file(buffer_body) create::close_file(neutrino_head) create::close_file(neutrino_body) create::close_file(validated_bk_head) create::close_file(validated_bk_body) create::close_file(validated_tx_head) create::close_file(validated_tx_body) open::open_file(header_head) open::open_file(header_body) open::open_file(point_head) open::open_file(point_body) open::open_file(input_head) open::open_file(input_body) open::open_file(output_head) open::open_file(output_body) open::open_file(puts_head) open::open_file(puts_body) open::open_file(tx_head) open::open_file(tx_body) open::open_file(txs_head) open::open_file(txs_body) open::open_file(address_head) open::open_file(address_body) open::open_file(candidate_head) open::open_file(candidate_body) open::open_file(confirmed_head) open::open_file(confirmed_body) open::open_file(strong_tx_head) open::open_file(strong_tx_body) open::open_file(bootstrap_head) open::open_file(bootstrap_body) open::open_file(buffer_head) open::open_file(buffer_body) open::open_file(neutrino_head) open::open_file(neutrino_body) open::open_file(validated_bk_head) open::open_file(validated_bk_body) open::open_file(validated_tx_head) open::open_file(validated_tx_body) open::load_file(header_head) open::load_file(header_body) open::load_file(point_head) open::load_file(point_body) open::load_file(input_head) open::load_file(input_body) open::load_file(output_head) open::load_file(output_body) open::load_file(puts_head) open::load_file(puts_body) open::load_file(tx_head) open::load_file(tx_body) open::load_file(txs_head) open::load_file(txs_body) open::load_file(address_head) open::load_file(address_body) open::load_file(candidate_head) open::load_file(candidate_body) open::load_file(confirmed_head) open::load_file(confirmed_body) open::load_file(strong_tx_head) open::load_file(strong_tx_body) open::load_file(bootstrap_head) open::load_file(bootstrap_body) open::load_file(buffer_head) open::load_file(buffer_body) open::load_file(neutrino_head) open::load_file(neutrino_body) open::load_file(validated_bk_head) open::load_file(validated_bk_body) open::load_file(validated_tx_head) open::load_file(validated_tx_body) open::verify_table(header_table) open::verify_table(point_table) open::verify_table(input_table) open::verify_table(output_table) open::verify_table(puts_table) open::verify_table(tx_table) open::verify_table(txs_table) open::verify_table(address_table) open::verify_table(candidate_table) open::verify_table(confirmed_table) open::verify_table(strong_tx_table) open::verify_table(bootstrap_table) open::verify_table(buffer_table) open::verify_table(neutrino_table) open::verify_table(validated_bk_table) open::verify_table(validated_tx_table) initialize::genesis_block close::close_table(header_table) close::close_table(point_table) close::close_table(input_table) close::close_table(output_table) close::close_table(puts_table) close::close_table(tx_table) close::close_table(txs_table) close::close_table(address_table) close::close_table(candidate_table) close::close_table(confirmed_table) close::close_table(strong_tx_table) close::close_table(bootstrap_table) close::close_table(buffer_table) close::close_table(neutrino_table) close::close_table(validated_bk_table) close::close_table(validated_tx_table) close::unload_file(header_head) close::unload_file(header_body) close::unload_file(point_head) close::unload_file(point_body) close::unload_file(input_head) close::unload_file(input_body) close::unload_file(output_head) close::unload_file(output_body) close::unload_file(puts_head) close::unload_file(puts_body) close::unload_file(tx_head) close::unload_file(tx_body) close::unload_file(txs_head) close::unload_file(txs_body) close::unload_file(address_head) close::unload_file(address_body) close::unload_file(candidate_head) close::unload_file(candidate_body) close::unload_file(confirmed_head) close::unload_file(confirmed_body) close::unload_file(strong_tx_head) close::unload_file(strong_tx_body) close::unload_file(bootstrap_head) close::unload_file(bootstrap_body) close::unload_file(buffer_head) close::unload_file(buffer_body) close::unload_file(neutrino_head) close::unload_file(neutrino_body) close::unload_file(validated_bk_head) close::unload_file(validated_bk_body) close::unload_file(validated_tx_head) close::unload_file(validated_tx_body) close::close_file(header_head) close::close_file(header_body) close::close_file(point_head) close::close_file(point_body) close::close_file(input_head) close::close_file(input_body) close::close_file(output_head) close::close_file(output_body) close::close_file(puts_head) close::close_file(puts_body) close::close_file(tx_head) close::close_file(tx_body) close::close_file(txs_head) close::close_file(txs_body) close::close_file(address_head) close::close_file(address_body) close::close_file(candidate_head) close::close_file(candidate_body) close::close_file(confirmed_head) close::close_file(confirmed_body) close::close_file(strong_tx_head) close::close_file(strong_tx_body) close::close_file(bootstrap_head) close::close_file(bootstrap_body) close::close_file(buffer_head) close::close_file(buffer_body) close::close_file(neutrino_head) close::close_file(neutrino_body) close::close_file(validated_bk_head) close::close_file(validated_bk_body) close::close_file(validated_tx_head) close::close_file(validated_tx_body) Completed initialization.
> bn -c bn.cfg 2023-03-21T01:55:24Z.0 ====================== startup ======================= 2023-03-21T01:55:24Z.0 Using config file: "bn.cfg" 2023-03-21T01:55:24Z.0 Press CTRL-C to stop the node. 2023-03-21T01:55:24Z.0 Please wait while the store is starting... 2023-03-21T01:55:24Z.0 open::open_file(header_head) 2023-03-21T01:55:24Z.0 open::open_file(header_body) 2023-03-21T01:55:24Z.0 open::open_file(point_head) 2023-03-21T01:55:24Z.0 open::open_file(point_body) 2023-03-21T01:55:24Z.0 open::open_file(input_head) 2023-03-21T01:55:24Z.0 open::open_file(input_body) 2023-03-21T01:55:24Z.0 open::open_file(output_head) 2023-03-21T01:55:24Z.0 open::open_file(output_body) 2023-03-21T01:55:24Z.0 open::open_file(puts_head) 2023-03-21T01:55:24Z.0 open::open_file(puts_body) 2023-03-21T01:55:24Z.0 open::open_file(tx_head) 2023-03-21T01:55:24Z.0 open::open_file(tx_body) 2023-03-21T01:55:24Z.0 open::open_file(txs_head) 2023-03-21T01:55:24Z.0 open::open_file(txs_body) 2023-03-21T01:55:24Z.0 open::open_file(address_head) 2023-03-21T01:55:24Z.0 open::open_file(address_body) 2023-03-21T01:55:24Z.0 open::open_file(candidate_head) 2023-03-21T01:55:24Z.0 open::open_file(candidate_body) 2023-03-21T01:55:24Z.0 open::open_file(confirmed_head) 2023-03-21T01:55:24Z.0 open::open_file(confirmed_body) 2023-03-21T01:55:24Z.0 open::open_file(strong_tx_head) 2023-03-21T01:55:24Z.0 open::open_file(strong_tx_body) 2023-03-21T01:55:24Z.0 open::open_file(bootstrap_head) 2023-03-21T01:55:24Z.0 open::open_file(bootstrap_body) 2023-03-21T01:55:24Z.0 open::open_file(buffer_head) 2023-03-21T01:55:24Z.0 open::open_file(buffer_body) 2023-03-21T01:55:24Z.0 open::open_file(neutrino_head) 2023-03-21T01:55:24Z.0 open::open_file(neutrino_body) 2023-03-21T01:55:24Z.0 open::open_file(validated_bk_head) 2023-03-21T01:55:24Z.0 open::open_file(validated_bk_body) 2023-03-21T01:55:24Z.0 open::open_file(validated_tx_head) 2023-03-21T01:55:24Z.0 open::open_file(validated_tx_body) 2023-03-21T01:55:24Z.0 open::load_file(header_head) 2023-03-21T01:55:24Z.0 open::load_file(header_body) 2023-03-21T01:55:24Z.0 open::load_file(point_head) 2023-03-21T01:55:24Z.0 open::load_file(point_body) 2023-03-21T01:55:24Z.0 open::load_file(input_head) 2023-03-21T01:55:24Z.0 open::load_file(input_body) 2023-03-21T01:55:24Z.0 open::load_file(output_head) 2023-03-21T01:55:24Z.0 open::load_file(output_body) 2023-03-21T01:55:24Z.0 open::load_file(puts_head) 2023-03-21T01:55:24Z.0 open::load_file(puts_body) 2023-03-21T01:55:24Z.0 open::load_file(tx_head) 2023-03-21T01:55:24Z.0 open::load_file(tx_body) 2023-03-21T01:55:24Z.0 open::load_file(txs_head) 2023-03-21T01:55:24Z.0 open::load_file(txs_body) 2023-03-21T01:55:24Z.0 open::load_file(address_head) 2023-03-21T01:55:24Z.0 open::load_file(address_body) 2023-03-21T01:55:24Z.0 open::load_file(candidate_head) 2023-03-21T01:55:24Z.0 open::load_file(candidate_body) 2023-03-21T01:55:24Z.0 open::load_file(confirmed_head) 2023-03-21T01:55:24Z.0 open::load_file(confirmed_body) 2023-03-21T01:55:24Z.0 open::load_file(strong_tx_head) 2023-03-21T01:55:24Z.0 open::load_file(strong_tx_body) 2023-03-21T01:55:24Z.0 open::load_file(bootstrap_head) 2023-03-21T01:55:24Z.0 open::load_file(bootstrap_body) 2023-03-21T01:55:24Z.0 open::load_file(buffer_head) 2023-03-21T01:55:24Z.0 open::load_file(buffer_body) 2023-03-21T01:55:24Z.0 open::load_file(neutrino_head) 2023-03-21T01:55:24Z.0 open::load_file(neutrino_body) 2023-03-21T01:55:24Z.0 open::load_file(validated_bk_head) 2023-03-21T01:55:24Z.0 open::load_file(validated_bk_body) 2023-03-21T01:55:24Z.0 open::load_file(validated_tx_head) 2023-03-21T01:55:24Z.0 open::load_file(validated_tx_body) 2023-03-21T01:55:24Z.0 open::verify_table(header_table) 2023-03-21T01:55:24Z.0 open::verify_table(point_table) 2023-03-21T01:55:24Z.0 open::verify_table(input_table) 2023-03-21T01:55:24Z.0 open::verify_table(output_table) 2023-03-21T01:55:24Z.0 open::verify_table(puts_table) 2023-03-21T01:55:24Z.0 open::verify_table(tx_table) 2023-03-21T01:55:24Z.0 open::verify_table(txs_table) 2023-03-21T01:55:24Z.0 open::verify_table(address_table) 2023-03-21T01:55:24Z.0 open::verify_table(candidate_table) 2023-03-21T01:55:24Z.0 open::verify_table(confirmed_table) 2023-03-21T01:55:24Z.0 open::verify_table(strong_tx_table) 2023-03-21T01:55:24Z.0 open::verify_table(bootstrap_table) 2023-03-21T01:55:24Z.0 open::verify_table(buffer_table) 2023-03-21T01:55:24Z.0 open::verify_table(neutrino_table) 2023-03-21T01:55:24Z.0 open::verify_table(validated_bk_table) 2023-03-21T01:55:24Z.0 open::verify_table(validated_tx_table) 2023-03-21T01:55:24Z.0 Please wait while the network is starting... 2023-03-21T01:55:24Z.1 Loaded (10000) addresses. 2023-03-21T01:55:24Z.1 Bypassed seeding because outbound connections disabled. 2023-03-21T01:55:24Z.0 Node is started. 2023-03-21T01:55:24Z.1 Maintaining manual connection to [35.197.69.139:8333] 2023-03-21T01:55:24Z.1 Not configured for inbound connections. 2023-03-21T01:55:24Z.1 Not configured for outbound connections. 2023-03-21T01:55:24Z.0 Node is running. 2023-03-21T01:55:24Z.1 Outbound [35.197.69.139:8333] version (70016) /Satoshi:24.0.1/ 2023-03-21T01:55:24Z.3 Manual channel start [35.197.69.139:8333] success 2023-03-21T01:55:27Z.0 CONSOLE: 'q' 2023-03-21T01:55:27Z.0 Please wait while the network is stopping... 2023-03-21T01:55:27Z.3 Manual channel stop [35.197.69.139:8333] service stopped 2023-03-21T01:55:27Z.1 Saved (10000) addresses. 2023-03-21T01:55:27Z.0 Please wait while the store is stopping... 2023-03-21T01:55:27Z.0 close::close_table(header_table) 2023-03-21T01:55:27Z.0 close::close_table(point_table) 2023-03-21T01:55:27Z.0 close::close_table(input_table) 2023-03-21T01:55:27Z.0 close::close_table(output_table) 2023-03-21T01:55:27Z.0 close::close_table(puts_table) 2023-03-21T01:55:27Z.0 close::close_table(tx_table) 2023-03-21T01:55:27Z.0 close::close_table(txs_table) 2023-03-21T01:55:27Z.0 close::close_table(address_table) 2023-03-21T01:55:27Z.0 close::close_table(candidate_table) 2023-03-21T01:55:27Z.0 close::close_table(confirmed_table) 2023-03-21T01:55:27Z.0 close::close_table(strong_tx_table) 2023-03-21T01:55:27Z.0 close::close_table(bootstrap_table) 2023-03-21T01:55:27Z.0 close::close_table(buffer_table) 2023-03-21T01:55:27Z.0 close::close_table(neutrino_table) 2023-03-21T01:55:27Z.0 close::close_table(validated_bk_table) 2023-03-21T01:55:27Z.0 close::close_table(validated_tx_table) 2023-03-21T01:55:27Z.0 close::unload_file(header_head) 2023-03-21T01:55:27Z.0 close::unload_file(header_body) 2023-03-21T01:55:27Z.0 close::unload_file(point_head) 2023-03-21T01:55:28Z.0 close::unload_file(point_body) 2023-03-21T01:55:28Z.0 close::unload_file(input_head) 2023-03-21T01:55:29Z.0 close::unload_file(input_body) 2023-03-21T01:55:29Z.0 close::unload_file(output_head) 2023-03-21T01:55:29Z.0 close::unload_file(output_body) 2023-03-21T01:55:29Z.0 close::unload_file(puts_head) 2023-03-21T01:55:29Z.0 close::unload_file(puts_body) 2023-03-21T01:55:29Z.0 close::unload_file(tx_head) 2023-03-21T01:55:35Z.0 close::unload_file(tx_body) 2023-03-21T01:55:35Z.0 close::unload_file(txs_head) 2023-03-21T01:55:35Z.0 close::unload_file(txs_body) 2023-03-21T01:55:35Z.0 close::unload_file(address_head) 2023-03-21T01:55:35Z.0 close::unload_file(address_body) 2023-03-21T01:55:35Z.0 close::unload_file(candidate_head) 2023-03-21T01:55:35Z.0 close::unload_file(candidate_body) 2023-03-21T01:55:35Z.0 close::unload_file(confirmed_head) 2023-03-21T01:55:35Z.0 close::unload_file(confirmed_body) 2023-03-21T01:55:35Z.0 close::unload_file(strong_tx_head) 2023-03-21T01:55:35Z.0 close::unload_file(strong_tx_body) 2023-03-21T01:55:35Z.0 close::unload_file(bootstrap_head) 2023-03-21T01:55:35Z.0 close::unload_file(bootstrap_body) 2023-03-21T01:55:35Z.0 close::unload_file(buffer_head) 2023-03-21T01:55:35Z.0 close::unload_file(buffer_body) 2023-03-21T01:55:35Z.0 close::unload_file(neutrino_head) 2023-03-21T01:55:35Z.0 close::unload_file(neutrino_body) 2023-03-21T01:55:35Z.0 close::unload_file(validated_bk_head) 2023-03-21T01:55:35Z.0 close::unload_file(validated_bk_body) 2023-03-21T01:55:35Z.0 close::unload_file(validated_tx_head) 2023-03-21T01:55:35Z.0 close::unload_file(validated_tx_body) 2023-03-21T01:55:35Z.0 close::close_file(header_head) 2023-03-21T01:55:35Z.0 close::close_file(header_body) 2023-03-21T01:55:35Z.0 close::close_file(point_head) 2023-03-21T01:55:35Z.0 close::close_file(point_body) 2023-03-21T01:55:35Z.0 close::close_file(input_head) 2023-03-21T01:55:35Z.0 close::close_file(input_body) 2023-03-21T01:55:35Z.0 close::close_file(output_head) 2023-03-21T01:55:35Z.0 close::close_file(output_body) 2023-03-21T01:55:35Z.0 close::close_file(puts_head) 2023-03-21T01:55:35Z.0 close::close_file(puts_body) 2023-03-21T01:55:35Z.0 close::close_file(tx_head) 2023-03-21T01:55:35Z.0 close::close_file(tx_body) 2023-03-21T01:55:35Z.0 close::close_file(txs_head) 2023-03-21T01:55:35Z.0 close::close_file(txs_body) 2023-03-21T01:55:35Z.0 close::close_file(address_head) 2023-03-21T01:55:35Z.0 close::close_file(address_body) 2023-03-21T01:55:35Z.0 close::close_file(candidate_head) 2023-03-21T01:55:35Z.0 close::close_file(candidate_body) 2023-03-21T01:55:35Z.0 close::close_file(confirmed_head) 2023-03-21T01:55:35Z.0 close::close_file(confirmed_body) 2023-03-21T01:55:35Z.0 close::close_file(strong_tx_head) 2023-03-21T01:55:35Z.0 close::close_file(strong_tx_body) 2023-03-21T01:55:35Z.0 close::close_file(bootstrap_head) 2023-03-21T01:55:35Z.0 close::close_file(bootstrap_body) 2023-03-21T01:55:35Z.0 close::close_file(buffer_head) 2023-03-21T01:55:35Z.0 close::close_file(buffer_body) 2023-03-21T01:55:35Z.0 close::close_file(neutrino_head) 2023-03-21T01:55:35Z.0 close::close_file(neutrino_body) 2023-03-21T01:55:35Z.0 close::close_file(validated_bk_head) 2023-03-21T01:55:35Z.0 close::close_file(validated_bk_body) 2023-03-21T01:55:35Z.0 close::close_file(validated_tx_head) 2023-03-21T01:55:35Z.0 close::close_file(validated_tx_body) 2023-03-21T01:55:35Z.0 Node stopped successfully. 2023-03-21T01:55:35Z.0 ====================== shutdown ======================
2023-03-21T01:55:29Z.0 close::unload_file(tx_head)

bn --totals to count up inputs and outputs in the store. These are slabs storage (variable length, because of script/witness data) and therefore their count cannot be inferred from the table size (unlike the other tables). This scans at a rate of about 1 million txs per second, so will take about 13 minutes to scan the entire store once populated. I'll resync tonight and with the new counts will be able to complete the intended default sizing configuration for header buckets at 1.5 collision rate and body initial sizes to preclude resizing.--initchain and --totals command line tools, as well as emission to log for node execution. The naive sync against a single peer takes about 11 hours. Will run another tonight against the updated store sizing. Encountered no problems on the last run.
I did notice that the txs table link sizing is at 76% capacity, so should probably be updated to 5 bytes before the end of the year. Also simple and will be about a 1GB increase. Other tables are all below 20% capacity.header :521357 (1.50029) txs :521357 (1.50029) tx :544452363 (1.50038) point :539868003 (1.50037) input :1440664028 (1.50038)
is_confirmable(block) and set_strong(block) . The former verifies confirmability (in the confirmation chaser) and the latter confirms the block and all transactions. These are the only material actions in terms of checking spend state and performing confirmation. The former takes 30 minutes and the latter takes 19 minutes - for all blocks/txs/inputs/outputs in the .5TB store. IOW, short of some optimization within these queries (which may be possible), a lower bound on sync time on this machine is 49 minutes. That is below the bound of what is possible on a 1Gbit network connection, so not limiting for practical purposes.set_confirmable(block) and set_connected(tx). The former completes for all blocks in 2 seconds, and the latter for all 817.5 million txs in 9 minutes - and these are sequential tests. So these are in no way restrictive queries.is_confirmable is quite a complex query, spanning multiple tables.is_confirmable which should be 45 mines (not 30). So along with set_strong the total minimum sequential cost is 64 minutes. Still slightly below the minimum theoretical bandwidth cost at 1Gb/s.is_confirmable due to the complexity of the relational query. Starting with a block height, the block fk is obtained, then all tx fks, then for each tx, all input fks, then for each input, a search for all spenders of the prevout of that input (by tx-hash/index hash table search key), then each spender is navigated to its tx, then its block fk, then the strong_bk table is searched for block confirmation. There are 2.16 billion inputs. So completing this query in 45 minutes across the entire blockchain is pretty amazing. And I'm glad I didn't try to optimize it with additional tables, since it doesn't appear limiting.validated_tx table was well over capacity. The validated_bk table was well below. This explained why set_connected(tx) population run accelerated significantly after a certain value. The link had overflowed, resulting in logical failures (which are fast). I'm summing up logical results, but there are expected failures due to the simulation. So after updating the build, the set connected run took 28 mins vs 9. All still constant time. This is still well within criteria, especially given that these calls will run concurrently.chain_state computation into the headers protocol, and look at the performance cost of maintaining that state and adding it into header writes. There should really not be a material cost, as the chain state class never hits the store - it just rolls forward the small amount of history necessary to obtain chain state at and given block. Dummy values are already being written to the store, so there's no change to write cost. I'll follow this up with a full sync that builds on the store with prepopulated headers (and correct chain state). This will provide a store that is then fully capable of self-contained full chain validation.chain_state to simplify a bit, including integration with chain::header validation. Moved its initial population from the store into the database query engine (from where it was in the blockchain repo). Wrote some tests and integrated it into node::protocol_header_in. Now have full contextual header validation. Still under 30 secs to obtain, validate, store, and index as candidate each header in the strong header chain.chain_state. This class is designed to init off the store and then prevent the need to ever hit the store (excepting chain splits) to determine chain state. The state just rolls forward in a simple struct from block to block. This was previous implementation that I adapted, almost the same. This hides all fork activation code and various ugly things like that, exposing it as a simple set of flags. Also maintains median time past, height and previous block hash. This can be set up to populate in full from the store for each block (how Core does it) or to roll state forward. I did the former yesterday and added the latter today. I measured the performance difference, and the roll forward cuts the typical full header sync time down from 30 secs to 15 secs. Without any validation or chain state the best I saw was 7-8 secs. With full header validation and rolling chain_state I saw a lot of 11-12 secs. This is obviously inconsequential for initial block download, but it does have bearing on the cost of validating a new block when the header arrives (mining scenario). The total time for one header, including network is about .015 ms.transaction_in in a similar manner. Its chaser manages the tx pool. Then I'll add in the header/block/tx out protocols, which are even simpler than the incoming protocols. Then will move on to the chasers (header tree, concurrent block downloader/validator/confirmer, tx graph).protocol_block_in . Fixed a simple issue in prevout population. Will be cleaning this up a bit tomorrow and then will do some mainnet verification and and timing runs. Will need to do a small amount of work in witness parameterization and hash caching. At this point we are dangerously close to node v3 (which is blocks-first).