From 4f849abfa99cb10fe5ed588c10dd8032f8241086 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Sat, 16 Mar 2024 01:49:47 -0400 Subject: [PATCH 1/6] Comments. --- console/executor.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/console/executor.cpp b/console/executor.cpp index c1fae032..e0644cf3 100644 --- a/console/executor.cpp +++ b/console/executor.cpp @@ -1631,6 +1631,8 @@ void executor::subscribe_capture() logger(BN_NODE_BACKUP_STARTED); node_->pause(); + // TODO: put this on an automated trigger based on store write interval. + // TODO: store/query object(s) can retain total data allocated/written. const auto error = store_.snapshot([&](auto event, auto table) { logger(format(BN_BACKUP) % events_.at(event) % tables_.at(table)); From 28c9adaa4a9d3fa16ddaf264e79842c2217dceb1 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Sat, 16 Mar 2024 13:10:23 -0400 Subject: [PATCH 2/6] Style, use auto. --- include/bitcoin/node/chasers/chaser_organize.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/bitcoin/node/chasers/chaser_organize.hpp b/include/bitcoin/node/chasers/chaser_organize.hpp index e7ee531e..f5a061ff 100644 --- a/include/bitcoin/node/chasers/chaser_organize.hpp +++ b/include/bitcoin/node/chasers/chaser_organize.hpp @@ -101,7 +101,7 @@ class chaser_organize const organize_handler& handler) NOEXCEPT; private: - static constexpr size_t fork_bits = to_bits(sizeof(system::chain::forks)); + static constexpr auto fork_bits = to_bits(sizeof(system::chain::forks)); static constexpr bool is_block() NOEXCEPT { return is_same_type; From 56cf31dc0b1ed7a1fdc453ff28c1bbd4da36a851 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Sat, 16 Mar 2024 13:12:05 -0400 Subject: [PATCH 3/6] Finalize --flags logic. --- console/executor.cpp | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/console/executor.cpp b/console/executor.cpp index e0644cf3..39036509 100644 --- a/console/executor.cpp +++ b/console/executor.cpp @@ -286,35 +286,30 @@ void executor::measure_size() const // fork flag transitions. void executor::scan_flags() const { + constexpr auto fork_bits = to_bits(sizeof(chain::forks)); + const auto error = code{ error::store_integrity }.message(); const auto start = unix_time(); + const auto top = query_.get_top_candidate(); uint32_t flags{}; - size_t height{}; console(BN_OPERATION_INTERRUPT); - // TODO: change this to walk candidate/confirmed index. - while (!cancel_ && (++height < query_.header_records())) + for (size_t height{}; !cancel_ && height <= top; ++height) { - // Assumes height is header link. - auto link = possible_narrow_cast(height); - database::context ctx{}; - if (!query_.get_context(ctx, link)) - { - // total chain cost: 1 sec. - cancel_ = true; - console("get_context"); - } - else if (ctx.height != height) + const auto link = query_.to_candidate(height); + if (!query_.get_context(ctx, link) || (ctx.height != height)) { - cancel_ = true; - console("height"); + console(format("Error: %1%") % error); + return; } - + if (ctx.flags != flags) { - console(format("height %1% before %2% at %3%") % - height % flags % ctx.flags); + const binary prev{ fork_bits, to_big_endian(flags) }; + const binary next{ fork_bits, to_big_endian(ctx.flags) }; + console(format("Forked from [%1%] to [%2%] at [%3%:%4%]") % prev % + next % encode_hash(query_.get_header_key(link)) % height); flags = ctx.flags; } } @@ -322,8 +317,7 @@ void executor::scan_flags() const if (cancel_) console(BN_OPERATION_CANCELED); - console(format("scan_flags" BN_READ_ROW) % - height % (unix_time() - start)); + console(format("scan_flags" BN_READ_ROW) % top % (unix_time() - start)); } // hashmap bucket fill rates. From b6e55729936c95073de51ba28e7f0cd48647bed9 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Sat, 16 Mar 2024 14:55:51 -0400 Subject: [PATCH 4/6] Comments. --- console/executor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/console/executor.cpp b/console/executor.cpp index 39036509..0e013f23 100644 --- a/console/executor.cpp +++ b/console/executor.cpp @@ -283,7 +283,7 @@ void executor::measure_size() const query_.validated_bk_buckets() % validated_bk); } -// fork flag transitions. +// fork flag transitions (candidate chain). void executor::scan_flags() const { constexpr auto fork_bits = to_bits(sizeof(chain::forks)); From 17cce6f055f2574c7218a78fc8a4843ed81c879a Mon Sep 17 00:00:00 2001 From: evoskuil Date: Sat, 16 Mar 2024 17:25:58 -0400 Subject: [PATCH 5/6] Integrate --restore command line option. --- console/executor.cpp | 231 ++++++++++++++----------- console/executor.hpp | 5 +- console/localize.hpp | 52 +++--- include/bitcoin/node/configuration.hpp | 26 ++- src/parser.cpp | 36 ++-- 5 files changed, 205 insertions(+), 145 deletions(-) diff --git a/console/executor.cpp b/console/executor.cpp index 0e013f23..0bb7db7d 100644 --- a/console/executor.cpp +++ b/console/executor.cpp @@ -205,6 +205,43 @@ void executor::stopper(const auto& message) stopped_.get_future().wait(); } +// fork flag transitions (candidate chain). +void executor::scan_flags() const +{ + constexpr auto fork_bits = to_bits(sizeof(chain::forks)); + const auto error = code{ error::store_integrity }.message(); + const auto start = unix_time(); + const auto top = query_.get_top_candidate(); + uint32_t flags{}; + + console(BN_OPERATION_INTERRUPT); + + for (size_t height{}; !cancel_ && height <= top; ++height) + { + database::context ctx{}; + const auto link = query_.to_candidate(height); + if (!query_.get_context(ctx, link) || (ctx.height != height)) + { + console(format("Error: %1%") % error); + return; + } + + if (ctx.flags != flags) + { + const binary prev{ fork_bits, to_big_endian(flags) }; + const binary next{ fork_bits, to_big_endian(ctx.flags) }; + console(format("Forked from [%1%] to [%2%] at [%3%:%4%]") % prev % + next % encode_hash(query_.get_header_key(link)) % height); + flags = ctx.flags; + } + } + + if (cancel_) + console(BN_OPERATION_CANCELED); + + console(format("scan_flags" BN_READ_ROW) % top % (unix_time() - start)); +} + // file and logical sizes. void executor::measure_size() const { @@ -283,43 +320,6 @@ void executor::measure_size() const query_.validated_bk_buckets() % validated_bk); } -// fork flag transitions (candidate chain). -void executor::scan_flags() const -{ - constexpr auto fork_bits = to_bits(sizeof(chain::forks)); - const auto error = code{ error::store_integrity }.message(); - const auto start = unix_time(); - const auto top = query_.get_top_candidate(); - uint32_t flags{}; - - console(BN_OPERATION_INTERRUPT); - - for (size_t height{}; !cancel_ && height <= top; ++height) - { - database::context ctx{}; - const auto link = query_.to_candidate(height); - if (!query_.get_context(ctx, link) || (ctx.height != height)) - { - console(format("Error: %1%") % error); - return; - } - - if (ctx.flags != flags) - { - const binary prev{ fork_bits, to_big_endian(flags) }; - const binary next{ fork_bits, to_big_endian(ctx.flags) }; - console(format("Forked from [%1%] to [%2%] at [%3%:%4%]") % prev % - next % encode_hash(query_.get_header_key(link)) % height); - flags = ctx.flags; - } - } - - if (cancel_) - console(BN_OPERATION_CANCELED); - - console(format("scan_flags" BN_READ_ROW) % top % (unix_time() - start)); -} - // hashmap bucket fill rates. void executor::scan_buckets() const { @@ -1080,6 +1080,15 @@ bool executor::menu() if (config.version) return do_version(); + if (config.initchain) + return do_initchain(); + + if (config.restore) + return do_restore(); + + if (config.flags) + return do_flags(); + if (config.measure) return do_measure(); @@ -1089,18 +1098,12 @@ bool executor::menu() if (config.collisions) return do_collisions(); - if (config.flags) - return do_flags(); - if (config.read) return do_read(); if (config.write) return do_write(); - if (config.initchain) - return do_initchain(); - return do_run(); } @@ -1168,7 +1171,7 @@ bool executor::do_initchain() return false; } - console(BN_STORE_STARTING); + console(BN_DATABASE_STARTING); if (const auto ec = store_.open([&](auto event, auto table) { console(format(BN_OPEN) % events_.at(event) % tables_.at(table)); @@ -1218,7 +1221,7 @@ bool executor::do_initchain() query_.validated_tx_buckets() % query_.validated_bk_buckets()); - console(BN_STORE_STOPPING); + console(BN_DATABASE_STOPPING); if (const auto ec = store_.close([&](auto event, auto table) { console(format(BN_CLOSE) % events_.at(event) % tables_.at(table)); @@ -1233,8 +1236,35 @@ bool executor::do_initchain() return true; } -// --measure -bool executor::do_measure() +// --restore +bool executor::do_restore() +{ + log_.stop(); + const auto start = logger::now(); + const auto& configuration = metadata_.configured.file; + if (configuration.empty()) + console(BN_USING_DEFAULT_CONFIG); + else + console(format(BN_USING_CONFIG_FILE) % configuration); + + const auto& store = metadata_.configured.database.path; + console(format(BN_RESTORING_CHAIN) % store); + if (const auto ec = store_.restore([&](auto event, auto table) + { + console(format(BN_RESTORE) % events_.at(event) % tables_.at(table)); + })) + { + console(format(BN_RESTORE_FAILURE) % ec.message()); + return false; + } + + const auto span = duration_cast(logger::now() - start); + console(format(BN_RESTORE_COMPLETE) % span.count()); + return true; +} + +// --flags +bool executor::do_flags() { log_.stop(); const auto& configuration = metadata_.configured.file; @@ -1246,40 +1276,40 @@ bool executor::do_measure() const auto& store = metadata_.configured.database.path; if (!database::file::is_directory(store)) { - console(format(BN_UNINITIALIZED_STORE) % store); + console(format(BN_UNINITIALIZED_DATABASE) % store); return false; } // Open store. - console(BN_STORE_STARTING); + console(BN_DATABASE_STARTING); if (const auto ec = store_.open([&](auto, auto) { ////console(format(BN_OPEN) % events_.at(event) % tables_.at(table)); })) { - console(format(BN_STORE_START_FAIL) % ec.message()); + console(format(BN_DATABASE_START_FAIL) % ec.message()); return false; } - measure_size(); + scan_flags(); // Close store. - console(BN_STORE_STOPPING); + console(BN_DATABASE_STOPPING); if (const auto ec = store_.close([&](auto, auto) { ////console(format(BN_CLOSE) % events_.at(event) % tables_.at(table)); })) { - console(format(BN_STORE_STOP_FAIL) % ec.message()); + console(format(BN_DATABASE_STOP_FAIL) % ec.message()); return false; } - console(BN_STORE_STOPPED); + console(BN_DATABASE_STOPPED); return true; } -// --buckets -bool executor::do_buckets() +// --measure +bool executor::do_measure() { log_.stop(); const auto& configuration = metadata_.configured.file; @@ -1291,40 +1321,40 @@ bool executor::do_buckets() const auto& store = metadata_.configured.database.path; if (!database::file::is_directory(store)) { - console(format(BN_UNINITIALIZED_STORE) % store); + console(format(BN_UNINITIALIZED_DATABASE) % store); return false; } // Open store. - console(BN_STORE_STARTING); + console(BN_DATABASE_STARTING); if (const auto ec = store_.open([&](auto, auto) { ////console(format(BN_OPEN) % events_.at(event) % tables_.at(table)); })) { - console(format(BN_STORE_START_FAIL) % ec.message()); + console(format(BN_DATABASE_START_FAIL) % ec.message()); return false; } - scan_buckets(); + measure_size(); // Close store. - console(BN_STORE_STOPPING); + console(BN_DATABASE_STOPPING); if (const auto ec = store_.close([&](auto, auto) { ////console(format(BN_CLOSE) % events_.at(event) % tables_.at(table)); })) { - console(format(BN_STORE_STOP_FAIL) % ec.message()); + console(format(BN_DATABASE_STOP_FAIL) % ec.message()); return false; } - console(BN_STORE_STOPPED); + console(BN_DATABASE_STOPPED); return true; } -// --collisions -bool executor::do_collisions() +// --buckets +bool executor::do_buckets() { log_.stop(); const auto& configuration = metadata_.configured.file; @@ -1336,40 +1366,40 @@ bool executor::do_collisions() const auto& store = metadata_.configured.database.path; if (!database::file::is_directory(store)) { - console(format(BN_UNINITIALIZED_STORE) % store); + console(format(BN_UNINITIALIZED_DATABASE) % store); return false; } // Open store. - console(BN_STORE_STARTING); + console(BN_DATABASE_STARTING); if (const auto ec = store_.open([&](auto, auto) { ////console(format(BN_OPEN) % events_.at(event) % tables_.at(table)); })) { - console(format(BN_STORE_START_FAIL) % ec.message()); + console(format(BN_DATABASE_START_FAIL) % ec.message()); return false; } - scan_collisions(); + scan_buckets(); // Close store. - console(BN_STORE_STOPPING); + console(BN_DATABASE_STOPPING); if (const auto ec = store_.close([&](auto, auto) { ////console(format(BN_CLOSE) % events_.at(event) % tables_.at(table)); })) { - console(format(BN_STORE_STOP_FAIL) % ec.message()); + console(format(BN_DATABASE_STOP_FAIL) % ec.message()); return false; } - console(BN_STORE_STOPPED); + console(BN_DATABASE_STOPPED); return true; } -// --flags -bool executor::do_flags() +// --collisions[l] +bool executor::do_collisions() { log_.stop(); const auto& configuration = metadata_.configured.file; @@ -1381,39 +1411,39 @@ bool executor::do_flags() const auto& store = metadata_.configured.database.path; if (!database::file::is_directory(store)) { - console(format(BN_UNINITIALIZED_STORE) % store); + console(format(BN_UNINITIALIZED_DATABASE) % store); return false; } // Open store. - console(BN_STORE_STARTING); + console(BN_DATABASE_STARTING); if (const auto ec = store_.open([&](auto, auto) { ////console(format(BN_OPEN) % events_.at(event) % tables_.at(table)); })) { - console(format(BN_STORE_START_FAIL) % ec.message()); + console(format(BN_DATABASE_START_FAIL) % ec.message()); return false; } - scan_flags(); + scan_collisions(); // Close store. - console(BN_STORE_STOPPING); + console(BN_DATABASE_STOPPING); if (const auto ec = store_.close([&](auto, auto) { ////console(format(BN_CLOSE) % events_.at(event) % tables_.at(table)); })) { - console(format(BN_STORE_STOP_FAIL) % ec.message()); + console(format(BN_DATABASE_STOP_FAIL) % ec.message()); return false; } - console(BN_STORE_STOPPED); + console(BN_DATABASE_STOPPED); return true; } -// --read +// --read[x] bool executor::do_read() { log_.stop(); @@ -1426,39 +1456,39 @@ bool executor::do_read() const auto& store = metadata_.configured.database.path; if (!database::file::is_directory(store)) { - console(format(BN_UNINITIALIZED_STORE) % store); + console(format(BN_UNINITIALIZED_DATABASE) % store); return false; } // Open store. - console(BN_STORE_STARTING); + console(BN_DATABASE_STARTING); if (const auto ec = store_.open([&](auto, auto) { ////console(format(BN_OPEN) % events_.at(event) % tables_.at(table)); })) { - console(format(BN_STORE_START_FAIL) % ec.message()); + console(format(BN_DATABASE_START_FAIL) % ec.message()); return false; } read_test(); // Close store. - console(BN_STORE_STOPPING); + console(BN_DATABASE_STOPPING); if (const auto ec = store_.close([&](auto, auto) { ////console(format(BN_CLOSE) % events_.at(event) % tables_.at(table)); })) { - console(format(BN_STORE_STOP_FAIL) % ec.message()); + console(format(BN_DATABASE_STOP_FAIL) % ec.message()); return false; } - console(BN_STORE_STOPPED); + console(BN_DATABASE_STOPPED); return true; } -// --write[f] +// --write bool executor::do_write() { log_.stop(); @@ -1471,35 +1501,35 @@ bool executor::do_write() const auto& store = metadata_.configured.database.path; if (!database::file::is_directory(store)) { - console(format(BN_UNINITIALIZED_STORE) % store); + console(format(BN_UNINITIALIZED_DATABASE) % store); return false; } // Open store. - console(BN_STORE_STARTING); + console(BN_DATABASE_STARTING); if (const auto ec = store_.open([&](auto, auto) { ////console(format(BN_OPEN) % events_.at(event) % tables_.at(table)); })) { - console(format(BN_STORE_START_FAIL) % ec.message()); + console(format(BN_DATABASE_START_FAIL) % ec.message()); return false; } write_test(); // Close store. - console(BN_STORE_STOPPING); + console(BN_DATABASE_STOPPING); if (const auto ec = store_.close([&](auto, auto) { ////console(format(BN_CLOSE) % events_.at(event) % tables_.at(table)); })) { - console(format(BN_STORE_STOP_FAIL) % ec.message()); + console(format(BN_DATABASE_STOP_FAIL) % ec.message()); return false; } - console(BN_STORE_STOPPED); + console(BN_DATABASE_STOPPED); return true; } @@ -1626,7 +1656,6 @@ void executor::subscribe_capture() node_->pause(); // TODO: put this on an automated trigger based on store write interval. - // TODO: store/query object(s) can retain total data allocated/written. const auto error = store_.snapshot([&](auto event, auto table) { logger(format(BN_BACKUP) % events_.at(event) % tables_.at(table)); @@ -1763,7 +1792,7 @@ bool executor::do_run() const auto& store = metadata_.configured.database.path; if (!database::file::is_directory(store)) { - logger(format(BN_UNINITIALIZED_STORE) % store); + logger(format(BN_UNINITIALIZED_DATABASE) % store); stopper(BN_NODE_STOPPED); return false; } @@ -1772,13 +1801,13 @@ bool executor::do_run() capture_.start(); // Open store. - logger(BN_STORE_STARTING); + logger(BN_DATABASE_STARTING); if (const auto ec = store_.open([&](auto event, auto table) { logger(format(BN_OPEN) % events_.at(event) % tables_.at(table)); })) { - logger(format(BN_STORE_START_FAIL) % ec.message()); + logger(format(BN_DATABASE_START_FAIL) % ec.message()); stopper(BN_NODE_STOPPED); return false; } @@ -1877,13 +1906,13 @@ bool executor::do_run() query_.get_unassociated_count()); // Close store (flush to disk). - logger(BN_STORE_STOPPING); + logger(BN_DATABASE_STOPPING); if (const auto ec = store_.close([&](auto event, auto table) { logger(format(BN_CLOSE) % events_.at(event) % tables_.at(table)); })) { - logger(format(BN_STORE_STOP_FAIL) % ec.message()); + logger(format(BN_DATABASE_STOP_FAIL) % ec.message()); stopper(BN_NODE_STOPPED); return false; } diff --git a/console/executor.hpp b/console/executor.hpp index 0016ed33..c9e2ba5b 100644 --- a/console/executor.hpp +++ b/console/executor.hpp @@ -60,10 +60,11 @@ class executor bool do_settings(); bool do_version(); bool do_initchain(); + bool do_restore(); + bool do_flags(); bool do_measure(); bool do_buckets(); bool do_collisions(); - bool do_flags(); bool do_read(); bool do_write(); bool do_run(); @@ -76,8 +77,8 @@ class executor void subscribe_connect(); void subscribe_close(); - void measure_size() const; void scan_flags() const; + void measure_size() const; void scan_buckets() const; void scan_collisions() const; void read_test() const; diff --git a/console/localize.hpp b/console/localize.hpp index 3f0eaa5a..8a21b1ff 100644 --- a/console/localize.hpp +++ b/console/localize.hpp @@ -24,11 +24,16 @@ namespace libbitcoin { namespace node { +#define BN_OPERATION_INTERRUPT \ + "Press CTRL-C to cancel operation." +#define BN_OPERATION_CANCELED \ + "CTRL-C detected, canceling operation..." + // --settings #define BN_SETTINGS_MESSAGE \ "These are the configuration settings that can be set." #define BN_INFORMATION_MESSAGE \ - "Runs a full bitcoin node with additional client-server query protocol." + "Runs a full bitcoin node." // --initchain #define BN_INITIALIZING_CHAIN \ @@ -36,7 +41,7 @@ namespace node { #define BN_INITCHAIN_EXISTS \ "Failed because the directory %1% already exists." #define BN_INITCHAIN_CREATING \ - "Please wait while creating the store..." + "Please wait while creating the database..." #define BN_INITCHAIN_COMPLETE \ "Created and initialized empty chain in %1% ms." #define BN_INITCHAIN_DATABASE_CREATE_FAILURE \ @@ -46,14 +51,17 @@ namespace node { #define BN_INITCHAIN_DATABASE_INITIALIZE_FAILURE \ "Database failure to store genesis block." #define BN_INITCHAIN_DATABASE_OPEN_FAILURE \ - "Database failure to open, %1%." + "Database failed to open, %1%." #define BN_INITCHAIN_DATABASE_CLOSE_FAILURE \ - "Database failure to close, %1%." + "Database failed to close, %1%." -#define BN_OPERATION_INTERRUPT \ - "Press CTRL-C to cancel operation." -#define BN_OPERATION_CANCELED \ - "CTRL-C detected, canceling operation..." +// --restore +#define BN_RESTORING_CHAIN \ + "Please wait while restoring %1% from most recent snapshot..." +#define BN_RESTORE_FAILURE \ + "Database restore failed with error, '%1%'." +#define BN_RESTORE_COMPLETE \ + "Restored database in %1% ms." // --measure #define BN_MEASURE_RECORDS \ @@ -134,11 +142,13 @@ namespace node { "close::%1%(%2%)" #define BN_BACKUP \ "backup::%1%(%2%)" +#define BN_RESTORE \ + "restore::%1%(%2%)" #define BN_NODE_INTERRUPT \ "Press CTRL-C to stop the node." -#define BN_STORE_STARTING \ - "Please wait while the store is starting..." +#define BN_DATABASE_STARTING \ + "Please wait while the database is starting..." #define BN_NETWORK_STARTING \ "Please wait while the network is starting..." #define BN_NODE_START_FAIL \ @@ -154,18 +164,18 @@ namespace node { #define BN_NODE_RUNNING \ "Node is running." -#define BN_UNINITIALIZED_STORE \ - "The %1% store directory does not exist, run: bn --initchain" +#define BN_UNINITIALIZED_DATABASE \ + "The %1% database directory does not exist, run: bn --initchain" #define BN_UNINITIALIZED_CHAIN \ - "The %1% store is not initialized, delete and run: bn --initchain" -#define BN_STORE_START_FAIL \ - "Store failed to start with error, %1%." -#define BN_STORE_STOPPING \ - "Please wait while the store is stopping..." -#define BN_STORE_STOP_FAIL \ - "Store failed to stop with error, %1%." -#define BN_STORE_STOPPED \ - "Store stopped successfully." + "The %1% database is not initialized, delete and run: bn --initchain" +#define BN_DATABASE_START_FAIL \ + "Database failed to start with error, %1%." +#define BN_DATABASE_STOPPING \ + "Please wait while the database is stopping..." +#define BN_DATABASE_STOP_FAIL \ + "Database failed to stop with error, %1%." +#define BN_DATABASE_STOPPED \ + "Database stopped successfully." #define BN_NETWORK_STOPPING \ "Please wait while the network is stopping..." diff --git a/include/bitcoin/node/configuration.hpp b/include/bitcoin/node/configuration.hpp index 2b70890b..6b36df61 100644 --- a/include/bitcoin/node/configuration.hpp +++ b/include/bitcoin/node/configuration.hpp @@ -29,13 +29,16 @@ namespace node { // Not localizable. #define BN_HELP_VARIABLE "help" -#define BN_INITCHAIN_VARIABLE "initchain" #define BN_SETTINGS_VARIABLE "settings" #define BN_VERSION_VARIABLE "version" +#define BN_INITCHAIN_VARIABLE "initchain" +#define BN_RESTORE_VARIABLE "restore" + +#define BN_FLAGS_VARIABLE "flags" #define BN_MEASURE_VARIABLE "measure" #define BN_BUCKETS_VARIABLE "buckets" #define BN_COLLISIONS_VARIABLE "collisions" -#define BN_FLAGS_VARIABLE "flags" + #define BN_READ_VARIABLE "read" #define BN_WRITE_VARIABLE "write" @@ -53,21 +56,28 @@ class BCN_API configuration configuration(system::chain::selection context) NOEXCEPT; - /// Options. + /// Environment. + std::filesystem::path file; + + /// Information. bool help; - bool initchain; bool settings; bool version; + + /// Actions. + bool initchain; + bool restore; + + /// Chain scans. + bool flags; bool measure; bool buckets; bool collisions; - bool flags; + + /// Ad-hoc Testing. bool read; bool write; - /// Options and environment vars. - std::filesystem::path file; - /// Settings. log::settings log; node::settings node; diff --git a/src/parser.cpp b/src/parser.cpp index 76ff0885..42b6c3bc 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -138,18 +138,13 @@ options_metadata parser::load_options() THROWS value(&configured.file), "Specify path to a configuration settings file." ) + // Information. ( BN_HELP_VARIABLE ",h", value(&configured.help)-> default_value(false)->zero_tokens(), "Display command line options." ) - ( - BN_INITCHAIN_VARIABLE ",i", - value(&configured.initchain)-> - default_value(false)->zero_tokens(), - "Initialize blockchain in the configured directory." - ) ( BN_SETTINGS_VARIABLE ",s", value(&configured.settings)-> @@ -162,6 +157,26 @@ options_metadata parser::load_options() THROWS default_value(false)->zero_tokens(), "Display version information." ) + // Actions. + ( + BN_INITCHAIN_VARIABLE ",i", + value(&configured.initchain)-> + default_value(false)->zero_tokens(), + "Initialize store in configured directory." + ) + ( + BN_RESTORE_VARIABLE ",r", + value(&configured.restore)-> + default_value(false)->zero_tokens(), + "Restore from most recent snapshot." + ) + // Chain scans. + ( + BN_FLAGS_VARIABLE ",f", + value(&configured.flags)-> + default_value(false)->zero_tokens(), + "Compute and display all flag transitions." + ) ( BN_MEASURE_VARIABLE ",m", value(&configured.measure)-> @@ -180,14 +195,9 @@ options_metadata parser::load_options() THROWS default_value(false)->zero_tokens(), "Compute and display hashmap collision stats." ) + // Ad-hoc Testing. ( - BN_FLAGS_VARIABLE ",f", - value(&configured.flags)-> - default_value(false)->zero_tokens(), - "Compute and display all flag transitions." - ) - ( - BN_READ_VARIABLE ",r", + BN_READ_VARIABLE ",x", value(&configured.read)-> default_value(false)->zero_tokens(), "Read test and display performance." From 05450ab30838dbadc804181aa1a0a5adced56089 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Sat, 16 Mar 2024 18:46:33 -0400 Subject: [PATCH 6/6] Require flush lock for restore. --- console/executor.cpp | 6 +++++- console/localize.hpp | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/console/executor.cpp b/console/executor.cpp index 0bb7db7d..54a55889 100644 --- a/console/executor.cpp +++ b/console/executor.cpp @@ -1249,12 +1249,16 @@ bool executor::do_restore() const auto& store = metadata_.configured.database.path; console(format(BN_RESTORING_CHAIN) % store); + if (const auto ec = store_.restore([&](auto event, auto table) { console(format(BN_RESTORE) % events_.at(event) % tables_.at(table)); })) { - console(format(BN_RESTORE_FAILURE) % ec.message()); + if (ec == database::error::flush_lock) + console(BN_RESTORE_MISSING_FLUSH_LOCK); + else + console(format(BN_RESTORE_FAILURE) % ec.message()); return false; } diff --git a/console/localize.hpp b/console/localize.hpp index 8a21b1ff..4ce3fe86 100644 --- a/console/localize.hpp +++ b/console/localize.hpp @@ -58,6 +58,8 @@ namespace node { // --restore #define BN_RESTORING_CHAIN \ "Please wait while restoring %1% from most recent snapshot..." +#define BN_RESTORE_MISSING_FLUSH_LOCK \ + "Database is not corrupted, flush lock file is absent." #define BN_RESTORE_FAILURE \ "Database restore failed with error, '%1%'." #define BN_RESTORE_COMPLETE \