From bcf719a88d5c6cd454792c3b0a93b43bb20849d8 Mon Sep 17 00:00:00 2001 From: Eric Voskuil Date: Mon, 17 Aug 2026 15:33:32 -0400 Subject: [PATCH 1/3] Adapt to store change of address indexation via outs. --- console/executor_dumps.cpp | 14 +++---- console/executor_test_reader.cpp | 32 ++++++++++----- console/localize.hpp | 24 ++++++------ src/parser.cpp | 39 +++++++------------ test/protocols/btcd/btcd_setup_fixture.cpp | 2 +- .../electrum/electrum_setup_fixture.cpp | 2 +- 6 files changed, 55 insertions(+), 58 deletions(-) diff --git a/console/executor_dumps.cpp b/console/executor_dumps.cpp index d338bfe8..c2ff2733 100644 --- a/console/executor_dumps.cpp +++ b/console/executor_dumps.cpp @@ -110,8 +110,7 @@ void executor::dump_body_sizes() const query_.validated_bk_body_size() % query_.validated_tx_body_size() % query_.filter_bk_body_size() % - query_.filter_tx_body_size() % - query_.address_body_size()); + query_.filter_tx_body_size()); } void executor::dump_records() const @@ -129,8 +128,7 @@ void executor::dump_records() const query_.prevalid_records() % query_.duplicate_records() % query_.strong_tx_records() % - query_.filter_bk_records() % - query_.address_records()); + query_.filter_bk_records()); } void executor::dump_buckets() const @@ -140,14 +138,14 @@ void executor::dump_buckets() const query_.txs_buckets() % query_.tx_buckets() % query_.ins_buckets() % + query_.outs_buckets() % query_.prevout_buckets() % query_.duplicate_buckets() % query_.strong_tx_buckets() % query_.validated_bk_buckets() % query_.validated_tx_buckets() % query_.filter_bk_buckets() % - query_.filter_tx_buckets() % - query_.address_buckets()); + query_.filter_tx_buckets()); } void executor::dump_collisions() const @@ -158,8 +156,8 @@ void executor::dump_collisions() const (to_double(query_.ins_records()) / query_.ins_buckets()) % (to_double(query_.strong_tx_records()) / query_.strong_tx_buckets()) % (to_double(query_.tx_records()) / query_.validated_tx_buckets()) % - (query_.address_enabled() ? (to_double(query_.address_records()) / - query_.address_buckets()) : zero)); + (query_.address_enabled() ? (to_double(query_.outs_records()) / + query_.outs_buckets()) : zero)); } void executor::dump_progress() const diff --git a/console/executor_test_reader.cpp b/console/executor_test_reader.cpp index 88557f35..58ecd8f9 100644 --- a/console/executor_test_reader.cpp +++ b/console/executor_test_reader.cpp @@ -70,9 +70,9 @@ void executor::read_test(const hash_digest&) const void executor::read_test(const hash_digest&) const { - logger(format("Point table body searches: %1% / (%2% + %1%)") % - store_.point.positive_search_count() % - store_.point.negative_search_count()); + logger(format("Ins table body searches: %1% / (%2% + %1%)") % + store_.ins.positive_search_count() % + store_.ins.negative_search_count()); } void executor::read_test(const hash_digest&) const @@ -142,7 +142,7 @@ void executor::read_test(const hash_digest&) const return; ////size_t found{}; - auto address_it = store_.address.it(key); + auto address_it = store_.outs.it({ key }); if (address_it.get().is_terminal()) { // fault, missing address. @@ -154,14 +154,26 @@ void executor::read_test(const hash_digest&) const if (canceled()) break; - table::address::record address{}; - if (!store_.address.get(address_it.get(), address)) + // Outs is read unguarded, under the iterator's aggregate guard. + table::outs::get_output put{}; + if (!store_.outs.puts.get_raw(address_it.get(), put)) { - // fault, missing address. + // fault, missing outs. return; } - const auto out_fk = address.output_fk; + // The table search is loose, so candidates are verified here. + const auto out_fk = put.out_fk; + table::output::match_script_hash script{ {}, key }; + if (!store_.output.raw(store_.output.get_memory(), out_fk, script)) + { + // fault, missing output. + return; + } + + if (!script.match) + continue; + table::output::get_parent output{}; if (!store_.output.get(out_fk, output)) { @@ -204,8 +216,8 @@ void executor::read_test(const hash_digest&) const if (!points.empty()) { pt_fk = points.front(); - table::ins::record ins{}; - if (!store_.ins.get(pt_fk, ins)) + table::ins_sequence::record ins{}; + if (!store_.ins.sequence.get(pt_fk, ins)) { // fault, missing ins. return; diff --git a/console/localize.hpp b/console/localize.hpp index eb66bf82..f336bf06 100644 --- a/console/localize.hpp +++ b/console/localize.hpp @@ -123,8 +123,7 @@ " valid_bk :%17%\n" \ " valid_tx :%18%\n" \ " filter_bk :%19%\n" \ - " filter_tx :%20%\n" \ - " address :%21%" + " filter_tx :%20%" #define BS_INFORMATION_RECORDS \ "Table records...\n" \ " header :%1%\n" \ @@ -139,8 +138,7 @@ " prevalid :%10%\n" \ " duplicate :%11%\n" \ " strong_tx :%12%\n" \ - " filter_bk :%13%\n" \ - " address :%14%" + " filter_bk :%13%" #define BS_INFORMATION_SLABS \ "Table slabs..." #define BS_INFORMATION_SLABS_ROW \ @@ -155,14 +153,14 @@ " txs :%2%\n" \ " tx :%3%\n" \ " ins :%4%\n" \ - " prevout :%5%\n" \ - " duplicate :%6%\n" \ - " strong_tx :%7%\n" \ - " valid_bk :%8%\n" \ - " valid_tx :%9%\n" \ - " filter_bk :%10%\n" \ - " filter_tx :%11%\n" \ - " address :%12%" + " outs :%5%\n" \ + " prevout :%6%\n" \ + " duplicate :%7%\n" \ + " strong_tx :%8%\n" \ + " valid_bk :%9%\n" \ + " valid_tx :%10%\n" \ + " filter_bk :%11%\n" \ + " filter_tx :%12%" #define BS_INFORMATION_COLLISION_RATES \ "Collision rates...\n" \ " header :%1%\n" \ @@ -170,7 +168,7 @@ " ins :%3%\n" \ " strong_tx :%4%\n" \ " valid_tx :%5%\n" \ - " address :%6%" + " outs :%6%" #define BS_INFORMATION_PROGRESS_START \ "Thinking..." #define BS_INFORMATION_PROGRESS \ diff --git a/src/parser.cpp b/src/parser.cpp index 97507b3e..9bd45d42 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -104,10 +104,13 @@ parser::parser(system::chain::selection context, configured.database.tx.buckets = 469'222'525; configured.database.tx.size = 17'000'000'000; - // ins table set to 2.2LF @ ~900k. + // ins index (required) set to 2.2LF @ ~900k. configured.database.ins.buckets = 1'365'977'136; configured.database.ins.size = 34'250'000'000; - configured.database.outs.size = 3'700'000'000; + + // outs index (optional) set to 2.5LF @ ~950k. + configured.database.outs.buckets = 1'496'771'635; + configured.database.outs.size = 6'750'000'000; configured.database.input.size = 92'500'000'000; configured.database.output.size = 25'300'000'000; @@ -136,13 +139,11 @@ parser::parser(system::chain::selection context, configured.database.validated_bk.buckets = 950'001; configured.database.validated_bk.size = 1'700'000; + // Unused in v4 configured.database.validated_tx.buckets = 1; configured.database.validated_tx.size = 1; - // database (optionals) - - configured.database.address.buckets = 1; - configured.database.address.size = 1; + // database (optional tables) // also disabled by filter_tx configured.database.filter_bk.buckets = 0; @@ -1677,15 +1678,20 @@ options_metadata parser::load_settings() THROWS ) /* table.outs */ + ( + "table.outs.buckets", + value(&configured.database.outs.buckets), + "The number of buckets in the archive_outs table head, defaults to '1' (1 disables address index)." + ) ( "table.outs.size", value(&configured.database.outs.size), - "The minimum allocation of the archive_puts table body, defaults to '3700000000'." + "The minimum allocation of the archive_outs table body, defaults to '3700000000'." ) ( "table.outs.rate", value(&configured.database.outs.rate), - "The percentage expansion of the archive_puts table body, defaults to '5'." + "The percentage expansion of the archive_outs table body, defaults to '5'." ) /* table.tx */ @@ -1879,23 +1885,6 @@ options_metadata parser::load_settings() THROWS "The percentage expansion of the validated_tx table body, defaults to '5'." ) - /* table.address */ - ( - "table.address.buckets", - value(&configured.database.address.buckets), - "The number of buckets in the option_address table head, defaults to '1' (0|1 disables)." - ) - ( - "table.address.size", - value(&configured.database.address.size), - "The minimum allocation of the option_address table body, defaults to '1'." - ) - ( - "table.address.rate", - value(&configured.database.address.rate), - "The percentage expansion of the option_address table body, defaults to '5'." - ) - /* table.filter_bk */ ( "table.filter_bk.buckets", diff --git a/test/protocols/btcd/btcd_setup_fixture.cpp b/test/protocols/btcd/btcd_setup_fixture.cpp index 874f7a5a..942b681f 100644 --- a/test/protocols/btcd/btcd_setup_fixture.cpp +++ b/test/protocols/btcd/btcd_setup_fixture.cpp @@ -40,7 +40,7 @@ btcd_setup_fixture::btcd_setup_fixture(const initializer& setup, [&]() NOEXCEPT -> const database::settings& { if (!address_index) - config_.database.address.buckets = 0; + config_.database.outs.buckets = 0; config_.database.path = TEST_DIRECTORY; return config_.database; diff --git a/test/protocols/electrum/electrum_setup_fixture.cpp b/test/protocols/electrum/electrum_setup_fixture.cpp index 857a524a..e17cec40 100644 --- a/test/protocols/electrum/electrum_setup_fixture.cpp +++ b/test/protocols/electrum/electrum_setup_fixture.cpp @@ -36,7 +36,7 @@ electrum_setup_fixture::electrum_setup_fixture(const initializer& setup, [&]() NOEXCEPT -> const database::settings& { if (!address_index) - config_.database.address.buckets = 0; + config_.database.outs.buckets = 0; config_.database.path = TEST_DIRECTORY; return config_.database; From a68f849869180eefe6ae88e206697bbe9831abcf Mon Sep 17 00:00:00 2001 From: Eric Voskuil Date: Mon, 17 Aug 2026 17:26:01 -0400 Subject: [PATCH 2/3] Use zero based bucket config for hashmap disable (vs. 1). --- src/parser.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/parser.cpp b/src/parser.cpp index 9bd45d42..c9ddc6bf 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -140,7 +140,7 @@ parser::parser(system::chain::selection context, configured.database.validated_bk.size = 1'700'000; // Unused in v4 - configured.database.validated_tx.buckets = 1; + configured.database.validated_tx.buckets = 0; configured.database.validated_tx.size = 1; // database (optional tables) @@ -1681,7 +1681,7 @@ options_metadata parser::load_settings() THROWS ( "table.outs.buckets", value(&configured.database.outs.buckets), - "The number of buckets in the archive_outs table head, defaults to '1' (1 disables address index)." + "The number of buckets in the archive_outs table head, defaults to '1496771635' (0 disables address index)." ) ( "table.outs.size", @@ -1872,7 +1872,7 @@ options_metadata parser::load_settings() THROWS ( "table.validated_tx.buckets", value(&configured.database.validated_tx.buckets), - "The number of buckets in the validated_tx table head, defaults to '1'." + "The number of buckets in the validated_tx table head, defaults to '0' (0 disables)." ) ( "table.validated_tx.size", From 4e7d09505d30dd46dab653cdc386afb3e29f3e91 Mon Sep 17 00:00:00 2001 From: Eric Voskuil Date: Mon, 17 Aug 2026 19:08:57 -0400 Subject: [PATCH 3/3] Make default LF2.5 with address index enabled. --- src/parser.cpp | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/src/parser.cpp b/src/parser.cpp index c9ddc6bf..62d6b488 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -88,42 +88,43 @@ parser::parser(system::chain::selection context, ////configured.server.stratum_v1.safes.emplace_back(asio::address{}, 8443_u16); ////configured.server.stratum_v2.binds.emplace_back(asio::address{}, 8580_u16); - // SCALE: LF2.2 @ 850K. + // database + // load factors are set to 2.5 @ 950K. // Only used for electrum queries (255 is optimal otherwise). configured.database.interval_depth = 11; - // database (archive) + // archive - configured.database.header.buckets = 386'364; + configured.database.header.buckets = 385'181; configured.database.header.size = 21'000'000; configured.database.txs.buckets = 950'001; configured.database.txs.size = 1'050'000'000; - configured.database.tx.buckets = 469'222'525; + configured.database.tx.buckets = 543'948'678; configured.database.tx.size = 17'000'000'000; - // ins index (required) set to 2.2LF @ ~900k. - configured.database.ins.buckets = 1'365'977'136; + // ins (required) + configured.database.ins.buckets = 1'345'386'901; configured.database.ins.size = 34'250'000'000; - // outs index (optional) set to 2.5LF @ ~950k. + // outs (optional) configured.database.outs.buckets = 1'496'771'635; configured.database.outs.size = 6'750'000'000; configured.database.input.size = 92'500'000'000; configured.database.output.size = 25'300'000'000; - // database (indexes) + // indexes configured.database.candidate.size = 2'575'500; configured.database.confirmed.size = 2'575'500; - configured.database.strong_tx.buckets = 469'222'525; + configured.database.strong_tx.buckets = 543'948'678; configured.database.strong_tx.size = 2'900'000'000; - // database (caches) + // caches configured.database.ecdsa.size = 1; configured.database.schnorr.size = 1; @@ -139,11 +140,11 @@ parser::parser(system::chain::selection context, configured.database.validated_bk.buckets = 950'001; configured.database.validated_bk.size = 1'700'000; - // Unused in v4 + // unused in v4 configured.database.validated_tx.buckets = 0; configured.database.validated_tx.size = 1; - // database (optional tables) + // optional // also disabled by filter_tx configured.database.filter_bk.buckets = 0; @@ -1623,7 +1624,7 @@ options_metadata parser::load_settings() THROWS ( "table.header.buckets", value(&configured.database.header.buckets), - "The number of buckets in the archive_header table head, defaults to '386364'." + "The number of buckets in the archive_header table head, defaults to '385181'." ) ( "table.header.size", @@ -1664,7 +1665,7 @@ options_metadata parser::load_settings() THROWS ( "table.ins.buckets", value(&configured.database.ins.buckets), - "The number of buckets in the archive_ins table head, defaults to '1365977136'." + "The number of buckets in the archive_ins table head, defaults to '1345386901'." ) ( "table.ins.size", @@ -1698,7 +1699,7 @@ options_metadata parser::load_settings() THROWS ( "table.tx.buckets", value(&configured.database.tx.buckets), - "The number of buckets in the archive_tx table head, defaults to '469222525'." + "The number of buckets in the archive_tx table head, defaults to '543948678'." ) ( "table.tx.size", @@ -1715,7 +1716,7 @@ options_metadata parser::load_settings() THROWS ( "table.txs.buckets", value(&configured.database.txs.buckets), - "The number of buckets in the archive_txs table head, defaults to '900001'." + "The number of buckets in the archive_txs table head, defaults to '950001'." ) ( "table.txs.size", @@ -1756,7 +1757,7 @@ options_metadata parser::load_settings() THROWS ( "table.strong.buckets", value(&configured.database.strong_tx.buckets), - "The number of buckets in the index_strong table head, defaults to '469222525'." + "The number of buckets in the index_strong table head, defaults to '543948678'." ) ( "table.strong.size", @@ -1855,7 +1856,7 @@ options_metadata parser::load_settings() THROWS ( "table.validated_bk.buckets", value(&configured.database.validated_bk.buckets), - "The number of buckets in the validated_bk table head, defaults to '900001'." + "The number of buckets in the validated_bk table head, defaults to '950001'." ) ( "table.validated_bk.size",