From f193441289f425aa260e01dcc28c6e9c30da4dab Mon Sep 17 00:00:00 2001 From: 766C6164 Date: Tue, 28 Mar 2023 15:19:12 -0400 Subject: [PATCH 1/4] Added subcommand to check for a clean shutdown --- programs/leap-util/actions/chain.cpp | 52 ++++++++++++++++++++++++++++ programs/leap-util/actions/chain.hpp | 2 ++ 2 files changed, 54 insertions(+) diff --git a/programs/leap-util/actions/chain.cpp b/programs/leap-util/actions/chain.cpp index ac7be37e78..ff31b0517e 100644 --- a/programs/leap-util/actions/chain.cpp +++ b/programs/leap-util/actions/chain.cpp @@ -47,6 +47,16 @@ void chain_actions::setup(CLI::App& app) { // properly return err code in main if(rc) throw(CLI::RuntimeError(rc)); }); + + auto* sstate = sub->add_subcommand("last-shutdown-state", "indicate whether last shutdown was clean or not"); + sstate->add_option("--state-dir,-o", opt->sstate_state_dir, "The location of the state directory (absolute path or relative to the current directory)")->capture_default_str(); + + sstate->callback([&]() { + int rc = run_subcommand_sstate(); + // properly return err code in main + if(rc) throw(CLI::RuntimeError(rc)); + }); + } int chain_actions::run_subcommand_build() { @@ -62,5 +72,47 @@ int chain_actions::run_subcommand_build() { std::cout << fc::json::to_pretty_string(chainbase::environment()) << std::endl; } + return 0; +} + +int chain_actions::run_subcommand_sstate() { + bfs::path state_dir = ""; + + // default state dir, if none specified + if(opt->sstate_state_dir.empty()) { + auto root = fc::app_path(); + auto default_data_dir = root / "eosio" / "nodeos" / "data" ; + state_dir = default_data_dir / config::default_state_dir_name; + } + else { + // adjust if path relative + state_dir = opt->sstate_state_dir; + if(state_dir.is_relative()) { + state_dir = bfs::current_path() / state_dir; + } + } + + auto shared_mem_path = state_dir / "shared_memory.bin"; + + if(!bfs::exists(shared_mem_path)) { + std::cerr << "Unable to read database status: file not found: " << shared_mem_path << std::endl; + return -1; + } + + char header[chainbase::header_size]; + std::ifstream hs(shared_mem_path.generic_string(), std::ifstream::binary); + hs.read(header, chainbase::header_size); + if(hs.fail()) { + std::cerr << "Unable to read database status: file invalid or corrupt" << shared_mem_path << std::endl; + return -1; + } + + chainbase::db_header* dbheader = reinterpret_cast(header); + if(dbheader->dirty) { + std::cout << "Database dirty flag is set, shutdown was not clean" << std::endl; + return -1; + } + + std::cout << "Database state is clean" << std::endl; return 0; } \ No newline at end of file diff --git a/programs/leap-util/actions/chain.hpp b/programs/leap-util/actions/chain.hpp index 9db4f42d8d..a3cbc18ce3 100644 --- a/programs/leap-util/actions/chain.hpp +++ b/programs/leap-util/actions/chain.hpp @@ -5,6 +5,7 @@ struct chain_options { bool build_just_print = false; std::string build_output_file = ""; + std::string sstate_state_dir = ""; }; class chain_actions : public sub_command { @@ -14,4 +15,5 @@ class chain_actions : public sub_command { // callbacks int run_subcommand_build(); + int run_subcommand_sstate(); }; \ No newline at end of file From 33334b1b43821bd5e7fb94f2260ed81b3acbb404 Mon Sep 17 00:00:00 2001 From: 766C6164 Date: Tue, 28 Mar 2023 16:40:07 -0400 Subject: [PATCH 2/4] Added check for chainbase version --- programs/leap-util/actions/chain.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/programs/leap-util/actions/chain.cpp b/programs/leap-util/actions/chain.cpp index ff31b0517e..9ac7ca6691 100644 --- a/programs/leap-util/actions/chain.cpp +++ b/programs/leap-util/actions/chain.cpp @@ -108,6 +108,11 @@ int chain_actions::run_subcommand_sstate() { } chainbase::db_header* dbheader = reinterpret_cast(header); + if(dbheader->id != chainbase::header_id) { + std::string what_str("\"" + state_dir.generic_string() + "\" database format not compatible with this version of chainbase."); + std::cerr << what_str << std::endl; + return -1; + } if(dbheader->dirty) { std::cout << "Database dirty flag is set, shutdown was not clean" << std::endl; return -1; From bba172f769fd47f7ca0416fee21172ad5984a4e4 Mon Sep 17 00:00:00 2001 From: 766C6164 Date: Thu, 30 Mar 2023 14:22:25 -0400 Subject: [PATCH 3/4] Dropped short argument form --- programs/leap-util/actions/chain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/leap-util/actions/chain.cpp b/programs/leap-util/actions/chain.cpp index 9ac7ca6691..7c91267b4c 100644 --- a/programs/leap-util/actions/chain.cpp +++ b/programs/leap-util/actions/chain.cpp @@ -49,7 +49,7 @@ void chain_actions::setup(CLI::App& app) { }); auto* sstate = sub->add_subcommand("last-shutdown-state", "indicate whether last shutdown was clean or not"); - sstate->add_option("--state-dir,-o", opt->sstate_state_dir, "The location of the state directory (absolute path or relative to the current directory)")->capture_default_str(); + sstate->add_option("--state-dir", opt->sstate_state_dir, "The location of the state directory (absolute path or relative to the current directory)")->capture_default_str(); sstate->callback([&]() { int rc = run_subcommand_sstate(); From b837affa1da67d4c48aa6cbc38df8a0f0a8396a4 Mon Sep 17 00:00:00 2001 From: 766C6164 Date: Thu, 30 Mar 2023 15:08:18 -0400 Subject: [PATCH 4/4] Moved state_dir option to chain-state subcommand --- programs/leap-util/actions/chain.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/programs/leap-util/actions/chain.cpp b/programs/leap-util/actions/chain.cpp index 7c91267b4c..974f681743 100644 --- a/programs/leap-util/actions/chain.cpp +++ b/programs/leap-util/actions/chain.cpp @@ -34,6 +34,7 @@ FC_REFLECT(chainbase::environment, (debug) (os) (arch) (boost_version) (compiler void chain_actions::setup(CLI::App& app) { auto* sub = app.add_subcommand("chain-state", "chain utility"); + sub->add_option("--state-dir", opt->sstate_state_dir, "The location of the state directory (absolute path or relative to the current directory)")->capture_default_str(); sub->require_subcommand(); sub->fallthrough(); @@ -48,15 +49,11 @@ void chain_actions::setup(CLI::App& app) { if(rc) throw(CLI::RuntimeError(rc)); }); - auto* sstate = sub->add_subcommand("last-shutdown-state", "indicate whether last shutdown was clean or not"); - sstate->add_option("--state-dir", opt->sstate_state_dir, "The location of the state directory (absolute path or relative to the current directory)")->capture_default_str(); - - sstate->callback([&]() { + sub->add_subcommand("last-shutdown-state", "indicate whether last shutdown was clean or not")->callback([&]() { int rc = run_subcommand_sstate(); // properly return err code in main if(rc) throw(CLI::RuntimeError(rc)); }); - } int chain_actions::run_subcommand_build() {