From 8ed4b58024f550e939f45e56a076cd60692b3ac7 Mon Sep 17 00:00:00 2001 From: arhag Date: Fri, 20 Sep 2019 22:42:37 -0400 Subject: [PATCH 1/2] set immutable chain_id during construction of controller; fixes a bug introduced in EOSIO/eos#7841 in which plugins like net_plugin were incorrectly using the default chain ID --- libraries/chain/controller.cpp | 49 ++++++---- .../chain/include/eosio/chain/controller.hpp | 6 +- .../chain/include/eosio/chain/snapshot.hpp | 4 + libraries/chain/snapshot.cpp | 12 ++- .../testing/include/eosio/testing/tester.hpp | 24 ++--- libraries/testing/tester.cpp | 22 +++-- plugins/chain_plugin/chain_plugin.cpp | 92 +++++++++---------- unittests/snapshot_tests.cpp | 2 +- 8 files changed, 118 insertions(+), 93 deletions(-) diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index 506065ba6d6..612249bc830 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -225,7 +225,7 @@ struct controller_impl { authorization_manager authorization; protocol_feature_manager protocol_features; controller::config conf; - chain_id_type chain_id; // read by thread_pool threads, value will not be changed after initialization/snapshot + const chain_id_type chain_id; // read by thread_pool threads, value will not be changed optional replay_head_time; db_read_mode read_mode = db_read_mode::SPECULATIVE; bool in_trx_requiring_checks = false; ///< if true, checks that are normally skipped on replay (e.g. auth checks) cannot be skipped @@ -281,7 +281,7 @@ struct controller_impl { apply_handlers[receiver][make_pair(contract,action)] = v; } - controller_impl( const controller::config& cfg, controller& s, protocol_feature_set&& pfs ) + controller_impl( const controller::config& cfg, controller& s, protocol_feature_set&& pfs, const fc::optional& expected_chain_id ) :self(s), db( cfg.state_dir, cfg.read_only ? database::read_only : database::read_write, @@ -296,9 +296,21 @@ struct controller_impl { authorization( s, db ), protocol_features( std::move(pfs) ), conf( cfg ), + chain_id( (db.revision() >= 1) ? db.get().chain_id + : ( expected_chain_id ? *expected_chain_id + : genesis_state().compute_chain_id() ) ), read_mode( cfg.read_mode ), thread_pool( "chain", cfg.thread_pool_size ) { + if( expected_chain_id && db.revision() >= 1 ) { + const auto& actual_chain_id = db.get().chain_id; + EOS_ASSERT( *expected_chain_id == actual_chain_id, + database_exception, + "Unexpected chain ID in state. Expected: ${expected}. Actual: ${actual}.", + ("expected", *expected_chain_id)("actual", actual_chain_id) + ); + } + fork_db.open( [this]( block_timestamp_type timestamp, const flat_set& cur_features, const vector& new_features ) @@ -546,6 +558,11 @@ struct controller_impl { void startup(std::function shutdown, const genesis_state& genesis) { EOS_ASSERT( db.revision() < 1, database_exception, "This version of controller::startup only works with a fresh state database." ); + const auto& genesis_chain_id = genesis.compute_chain_id(); + EOS_ASSERT( genesis_chain_id == chain_id, misc_exception, + "genesis state provided to startup does not match the chain ID that controller was constructed with", + ("genesis_chain_id", genesis_chain_id)("controller_chain_id", chain_id) + ); if( fork_db.head() ) { if( read_mode == db_read_mode::IRREVERSIBLE && fork_db.head()->id != fork_db.root()->id ) { @@ -575,7 +592,6 @@ struct controller_impl { EOS_ASSERT( db.revision() >= 1, database_exception, "This version of controller::startup does not work with a fresh state database." ); EOS_ASSERT( fork_db.head(), fork_database_exception, "No existing fork database despite existing chain state. Replay required." ); - chain_id = db.get().chain_id; uint32_t lib_num = fork_db.root()->block_num; auto first_block_num = blog.first_block_num(); if( blog.head() ) { @@ -836,13 +852,13 @@ struct controller_impl { resource_limits.add_to_snapshot(snapshot); } - static fc::optional extract_legacy_genesis_state( const snapshot_reader_ptr& snapshot, uint32_t version ) { + static fc::optional extract_legacy_genesis_state( snapshot_reader& snapshot, uint32_t version ) { fc::optional genesis; using v2 = legacy::snapshot_global_property_object_v2; if (std::clamp(version, v2::minimum_version, v2::maximum_version) == version ) { genesis.emplace(); - snapshot->read_section([&genesis=*genesis]( auto §ion ){ + snapshot.read_section([&genesis=*genesis]( auto §ion ){ section.read_row(genesis); }); } @@ -905,7 +921,7 @@ struct controller_impl { using v2 = legacy::snapshot_global_property_object_v2; if (std::clamp(header.version, v2::minimum_version, v2::maximum_version) == header.version ) { - fc::optional genesis = extract_legacy_genesis_state(snapshot, header.version); + fc::optional genesis = extract_legacy_genesis_state(*snapshot, header.version); EOS_ASSERT( genesis, snapshot_exception, "Snapshot indicates chain_snapshot_header version 2, but does not contain a genesis_state. " "It must be corrupted."); @@ -942,8 +958,10 @@ struct controller_impl { }); const auto& gpo = db.get(); - // ensure chain_id is populated from global_property_object's chain_id - chain_id = gpo.chain_id; + EOS_ASSERT( gpo.chain_id == chain_id, misc_exception, + "chain ID in snapshot does not match the chain ID that controller was constructed with", + ("snapshot_chain_id", gpo.chain_id)("controller_chain_id", chain_id) + ); } sha256 calculate_integrity_hash() const { @@ -1004,7 +1022,6 @@ struct controller_impl { }); genesis.initial_configuration.validate(); - chain_id = genesis.compute_chain_id(); db.create([&genesis,&chain_id=this->chain_id](auto& gpo ){ gpo.configuration = genesis.initial_configuration; gpo.chain_id = chain_id; @@ -2348,13 +2365,13 @@ const protocol_feature_manager& controller::get_protocol_feature_manager()const return my->protocol_features; } -controller::controller( const controller::config& cfg ) -:my( new controller_impl( cfg, *this, protocol_feature_set{} ) ) +controller::controller( const controller::config& cfg, const fc::optional& expected_chain_id ) +:my( new controller_impl( cfg, *this, protocol_feature_set{}, expected_chain_id ) ) { } -controller::controller( const config& cfg, protocol_feature_set&& pfs ) -:my( new controller_impl( cfg, *this, std::move(pfs) ) ) +controller::controller( const config& cfg, protocol_feature_set&& pfs, const fc::optional& expected_chain_id ) +:my( new controller_impl( cfg, *this, std::move(pfs), expected_chain_id ) ) { } @@ -3149,9 +3166,9 @@ fc::optional controller::convert_exception_to_error_code( const fc::ex return e_ptr->error_code; } -chain_id_type controller::extract_chain_id(const snapshot_reader_ptr& snapshot) { +chain_id_type controller::extract_chain_id(snapshot_reader& snapshot) { chain_snapshot_header header; - snapshot->read_section([&header]( auto §ion ){ + snapshot.read_section([&header]( auto §ion ){ section.read_row(header); header.validate(); }); @@ -3163,7 +3180,7 @@ chain_id_type controller::extract_chain_id(const snapshot_reader_ptr& snapshot) } chain_id_type chain_id; - snapshot->read_section([&chain_id]( auto §ion ){ + snapshot.read_section([&chain_id]( auto §ion ){ snapshot_global_property_object global_properties; section.read_row(global_properties); chain_id = global_properties.chain_id; diff --git a/libraries/chain/include/eosio/chain/controller.hpp b/libraries/chain/include/eosio/chain/controller.hpp index 959820d93c7..e4adf700c10 100644 --- a/libraries/chain/include/eosio/chain/controller.hpp +++ b/libraries/chain/include/eosio/chain/controller.hpp @@ -100,8 +100,8 @@ namespace eosio { namespace chain { incomplete = 3, ///< this is an incomplete block (either being produced by a producer or speculatively produced by a node) }; - explicit controller( const config& cfg ); - controller( const config& cfg, protocol_feature_set&& pfs ); + controller( const config& cfg, const fc::optional& expected_chain_id ); + controller( const config& cfg, protocol_feature_set&& pfs, const fc::optional& expected_chain_id ); ~controller(); void add_indices(); @@ -328,7 +328,7 @@ namespace eosio { namespace chain { return pretty_output; } - static chain_id_type extract_chain_id(const snapshot_reader_ptr& snapshot); + static chain_id_type extract_chain_id(snapshot_reader& snapshot); private: friend class apply_context; diff --git a/libraries/chain/include/eosio/chain/snapshot.hpp b/libraries/chain/include/eosio/chain/snapshot.hpp index 618e8d36088..69f89987912 100644 --- a/libraries/chain/include/eosio/chain/snapshot.hpp +++ b/libraries/chain/include/eosio/chain/snapshot.hpp @@ -279,6 +279,8 @@ namespace eosio { namespace chain { virtual void validate() const = 0; + virtual void return_to_header() = 0; + virtual ~snapshot_reader(){}; protected: @@ -316,6 +318,7 @@ namespace eosio { namespace chain { bool read_row( detail::abstract_snapshot_row_reader& row_reader ) override; bool empty ( ) override; void clear_section() override; + void return_to_header() override; private: const fc::variant& snapshot; @@ -352,6 +355,7 @@ namespace eosio { namespace chain { bool read_row( detail::abstract_snapshot_row_reader& row_reader ) override; bool empty ( ) override; void clear_section() override; + void return_to_header() override; private: bool validate_section() const; diff --git a/libraries/chain/snapshot.cpp b/libraries/chain/snapshot.cpp index e226a4f4886..66966ef6be5 100644 --- a/libraries/chain/snapshot.cpp +++ b/libraries/chain/snapshot.cpp @@ -30,6 +30,7 @@ void variant_snapshot_writer::finalize() { variant_snapshot_reader::variant_snapshot_reader(const fc::variant& snapshot) :snapshot(snapshot) +,cur_section(nullptr) ,cur_row(0) { } @@ -114,6 +115,10 @@ void variant_snapshot_reader::clear_section() { cur_row = 0; } +void variant_snapshot_reader::return_to_header() { + clear_section(); +} + ostream_snapshot_writer::ostream_snapshot_writer(std::ostream& snapshot) :snapshot(snapshot) ,header_pos(snapshot.tellp()) @@ -336,6 +341,11 @@ void istream_snapshot_reader::clear_section() { cur_row = 0; } +void istream_snapshot_reader::return_to_header() { + snapshot.seekg( header_pos ); + clear_section(); +} + integrity_hash_snapshot_writer::integrity_hash_snapshot_writer(fc::sha256::encoder& enc) :enc(enc) { @@ -358,4 +368,4 @@ void integrity_hash_snapshot_writer::finalize() { // no-op for structural details } -}} \ No newline at end of file +}} diff --git a/libraries/testing/include/eosio/testing/tester.hpp b/libraries/testing/include/eosio/testing/tester.hpp index 508fde8118b..60224544b23 100644 --- a/libraries/testing/include/eosio/testing/tester.hpp +++ b/libraries/testing/include/eosio/testing/tester.hpp @@ -163,13 +163,13 @@ namespace eosio { namespace testing { void close(); template - void open( protocol_feature_set&& pfs, Lambda lambda ); + void open( protocol_feature_set&& pfs, const fc::optional& expected_chain_id, Lambda lambda ); void open( protocol_feature_set&& pfs, const snapshot_reader_ptr& snapshot ); void open( protocol_feature_set&& pfs, const genesis_state& genesis ); - void open( protocol_feature_set&& pfs ); + void open( protocol_feature_set&& pfs, const fc::optional& expected_chain_id = {} ); void open( const snapshot_reader_ptr& snapshot ); void open( const genesis_state& genesis ); - void open(); + void open( const fc::optional& expected_chain_id = {} ); bool is_same_chain( base_tester& other ); virtual signed_block_ptr produce_block( fc::microseconds skip_time = fc::milliseconds(config::block_interval_ms) ) = 0; @@ -380,6 +380,13 @@ namespace eosio { namespace testing { void preactivate_protocol_features(const vector feature_digests); void preactivate_all_builtin_protocol_features(); + static genesis_state default_genesis() { + genesis_state genesis; + genesis.initial_timestamp = fc::time_point::from_iso_string("2020-01-01T00:00:00.000"); + genesis.initial_key = get_public_key( config::system_account_name, "active" ); + + return genesis; + } static std::pair default_config(const fc::temp_directory& tempdir) { controller::config cfg; @@ -391,17 +398,13 @@ namespace eosio { namespace testing { cfg.reversible_guard_size = 0; cfg.contracts_console = true; - genesis_state genesis; - genesis.initial_timestamp = fc::time_point::from_iso_string("2020-01-01T00:00:00.000"); - genesis.initial_key = get_public_key( config::system_account_name, "active" ); - for(int i = 0; i < boost::unit_test::framework::master_test_suite().argc; ++i) { if(boost::unit_test::framework::master_test_suite().argv[i] == std::string("--wavm")) cfg.wasm_runtime = chain::wasm_interface::vm_type::wavm; else if(boost::unit_test::framework::master_test_suite().argv[i] == std::string("--wabt")) cfg.wasm_runtime = chain::wasm_interface::vm_type::wabt; } - return {cfg, genesis}; + return {cfg, default_genesis()}; } protected: @@ -418,7 +421,6 @@ namespace eosio { namespace testing { std::map block_signing_private_keys; protected: controller::config cfg; - fc::optional genesis; map chain_transactions; map last_produced_block; unapplied_transaction_queue unapplied_transactions; @@ -529,7 +531,7 @@ namespace eosio { namespace testing { } static unique_ptr create_validating_node(controller::config vcfg, const genesis_state& genesis, bool use_genesis) { - unique_ptr validating_node = std::make_unique(vcfg, make_protocol_feature_set()); + unique_ptr validating_node = std::make_unique(vcfg, make_protocol_feature_set(), genesis.compute_chain_id()); validating_node->add_indices(); if (use_genesis) { validating_node->startup( []() { return false; }, genesis ); @@ -613,7 +615,7 @@ namespace eosio { namespace testing { hbh.producer == vn_hbh.producer; validating_node.reset(); - validating_node = std::make_unique(vcfg, make_protocol_feature_set()); + validating_node = std::make_unique(vcfg, make_protocol_feature_set(), control->get_chain_id()); validating_node->add_indices(); validating_node->startup( []() { return false; } ); diff --git a/libraries/testing/tester.cpp b/libraries/testing/tester.cpp index f8680771b8b..3baa63629c5 100644 --- a/libraries/testing/tester.cpp +++ b/libraries/testing/tester.cpp @@ -170,7 +170,7 @@ namespace eosio { namespace testing { void base_tester::init(controller::config config) { cfg = config; - open(); + open(default_genesis().compute_chain_id()); } void base_tester::init(controller::config config, protocol_feature_set&& pfs, const snapshot_reader_ptr& snapshot) { @@ -185,7 +185,7 @@ namespace eosio { namespace testing { void base_tester::init(controller::config config, protocol_feature_set&& pfs) { cfg = config; - open(std::move(pfs)); + open(std::move(pfs), default_genesis().compute_chain_id()); } void base_tester::execute_setup_policy(const setup_policy policy) { @@ -241,13 +241,13 @@ namespace eosio { namespace testing { open( make_protocol_feature_set(), genesis ); } - void base_tester::open() { - open( make_protocol_feature_set() ); + void base_tester::open( const fc::optional& expected_chain_id ) { + open( make_protocol_feature_set(), expected_chain_id ); } template - void base_tester::open( protocol_feature_set&& pfs, Lambda lambda ) { - control.reset( new controller(cfg, std::move(pfs)) ); + void base_tester::open( protocol_feature_set&& pfs, const fc::optional& expected_chain_id, Lambda lambda ) { + control.reset( new controller(cfg, std::move(pfs), expected_chain_id) ); control->add_indices(); lambda(); chain_transactions.clear(); @@ -266,19 +266,21 @@ namespace eosio { namespace testing { } void base_tester::open( protocol_feature_set&& pfs, const snapshot_reader_ptr& snapshot ) { - open(std::move(pfs), [&snapshot,&control=this->control]() { + const auto& snapshot_chain_id = controller::extract_chain_id( *snapshot ); + snapshot->return_to_header(); + open(std::move(pfs), snapshot_chain_id, [&snapshot,&control=this->control]() { control->startup([]() { return false; }, snapshot ); }); } void base_tester::open( protocol_feature_set&& pfs, const genesis_state& genesis ) { - open(std::move(pfs), [&genesis,&control=this->control]() { + open(std::move(pfs), genesis.compute_chain_id(), [&genesis,&control=this->control]() { control->startup( []() { return false; }, genesis ); }); } - void base_tester::open( protocol_feature_set&& pfs ) { - open(std::move(pfs), [&control=this->control]() { + void base_tester::open( protocol_feature_set&& pfs, const fc::optional& expected_chain_id ) { + open(std::move(pfs), expected_chain_id, [&control=this->control]() { control->startup( []() { return false; } ); }); } diff --git a/plugins/chain_plugin/chain_plugin.cpp b/plugins/chain_plugin/chain_plugin.cpp index 43a0d89f5c5..c6cc5b8997b 100644 --- a/plugins/chain_plugin/chain_plugin.cpp +++ b/plugins/chain_plugin/chain_plugin.cpp @@ -812,7 +812,7 @@ void chain_plugin::plugin_initialize(const variables_map& options) { wlog("The --import-reversible-blocks option should be used by itself."); } - fc::optional block_log_chain_id; + fc::optional expected_chain_id; if (options.count( "snapshot" )) { my->snapshot_path = options.at( "snapshot" ).as(); EOS_ASSERT( fc::exists(*my->snapshot_path), plugin_config_exception, @@ -821,9 +821,9 @@ void chain_plugin::plugin_initialize(const variables_map& options) { // recover genesis information from the snapshot // used for validation code below auto infile = std::ifstream(my->snapshot_path->generic_string(), (std::ios::in | std::ios::binary)); - auto reader = std::make_shared(infile); - reader->validate(); - chain_id_type chain_id = controller::extract_chain_id(reader); + istream_snapshot_reader reader(infile); + reader.validate(); + expected_chain_id = controller::extract_chain_id(reader); infile.close(); EOS_ASSERT( options.count( "genesis-timestamp" ) == 0, @@ -842,15 +842,21 @@ void chain_plugin::plugin_initialize(const variables_map& options) { auto log_genesis = block_log::extract_genesis_state(my->blocks_dir); if (log_genesis) { my->genesis = log_genesis; - EOS_ASSERT( my->genesis->compute_chain_id() == chain_id, + const auto& block_log_chain_id = my->genesis->compute_chain_id(); + EOS_ASSERT( expected_chain_id == block_log_chain_id, plugin_config_exception, - "snapshot chain id does not match the chain id from the genesis state in the block log."); - } - else { - block_log_chain_id = block_log::extract_chain_id(my->blocks_dir); - EOS_ASSERT( block_log_chain_id == chain_id, + "snapshot chain id does not match the chain id from the genesis state in the block log.", + ("snapshot_chain_id", expected_chain_id) + ("block_log_chain_id", block_log_chain_id) + ); + } else { + const auto& block_log_chain_id = block_log::extract_chain_id(my->blocks_dir); + EOS_ASSERT( expected_chain_id == block_log_chain_id, plugin_config_exception, - "snapshot chain id does not match the chain id in the block log."); + "snapshot chain id does not match the chain id in the block log.", + ("snapshot_chain_id", expected_chain_id) + ("block_log_chain_id", block_log_chain_id) + ); } } @@ -876,8 +882,9 @@ void chain_plugin::plugin_initialize(const variables_map& options) { } else { ilog( "Using genesis state provided in '${genesis}'", ("genesis", genesis_file.generic_string())); } - } - else { + + expected_chain_id = my->genesis->compute_chain_id(); + } else { EOS_ASSERT( options.count( "genesis-timestamp" ) == 0, plugin_config_exception, "--genesis-timestamp is only valid if also passed in with --genesis-json"); @@ -892,19 +899,20 @@ void chain_plugin::plugin_initialize(const variables_map& options) { " in blocks.log. It is not necessary to provide genesis state arguments when a blocks.log " "file already exists." ); - } - else { + } else { my->genesis = log_genesis; + expected_chain_id = my->genesis->compute_chain_id(); } - } - else { - block_log_chain_id = block_log::extract_chain_id( my->blocks_dir ); + } else { + const auto& block_log_chain_id = block_log::extract_chain_id( my->blocks_dir ); if (my->genesis) { - EOS_ASSERT( my->genesis->compute_chain_id() == *block_log_chain_id, plugin_config_exception, + EOS_ASSERT( expected_chain_id == block_log_chain_id, plugin_config_exception, "Genesis state, provided via command line arguments, has a chain_id that does not match the " "existing chain id in blocks.log. It is not necessary to provide genesis state arguments " "when a blocks.log file already exists." ); + } else { + expected_chain_id = block_log_chain_id; } } } @@ -924,38 +932,20 @@ void chain_plugin::plugin_initialize(const variables_map& options) { my->chain_config->db_hugepage_paths = options.at("database-hugepage-path").as>(); #endif - my->chain.emplace( *my->chain_config, std::move(pfs) ); - - if( !options.count( "snapshot" ) ) { - if( my->chain->db().revision() < 1 ) { // No existing blockchain state - EOS_ASSERT( my->genesis || !block_log_chain_id, plugin_config_exception, - "Genesis state is necessary to initialize fresh blockchain state but genesis state could not be " - "found in the blocks log. Please either load from snapshot or find a blocks log that starts " - "from genesis." - ); - if( my->genesis ) { - ilog( "Starting up fresh blockchain with provided genesis state." ); - } else { - ilog( "Starting up fresh blockchain with default genesis state." ); - my->genesis.emplace(); - } - } else { // Existing blockchain state - const auto& state_chain_id = my->chain->get_global_properties().chain_id; - if( my->genesis ) { - auto provided_chain_id = my->genesis->compute_chain_id(); - EOS_ASSERT( provided_chain_id == state_chain_id, plugin_config_exception, - "Existing state is for a different chain than the one specified by the provided genesis " - "state. Provided genesis state chain id: ${provided_chain_id}, existing state chain id: ${state_chain_id}", - ("provided_chain_id", provided_chain_id)("state_chain_id", state_chain_id) - ); - } else if( block_log_chain_id ) { - EOS_ASSERT( *block_log_chain_id == state_chain_id, block_log_exception, - "Existing state is for a different chain than the one specified in the blocks log." - " Block log chain id: ${block_log_chain_id}, existing state chain id: ${state_chain_id}", - ("block_log_chain_id", *block_log_chain_id)("state_chain_id", state_chain_id) + my->chain.emplace( *my->chain_config, std::move(pfs), expected_chain_id ); - ); - } + if( !options.count( "snapshot" ) && my->chain->db().revision() < 1 ) { + // No snapshot and no existing blockchain state + EOS_ASSERT( my->genesis || !expected_chain_id, plugin_config_exception, + "Genesis state is necessary to initialize fresh blockchain state but genesis state could not be " + "found in the blocks log. Please either load from snapshot or find a blocks log that starts " + "from genesis." + ); + if( my->genesis ) { + ilog( "Starting up fresh blockchain with provided genesis state." ); + } else { + ilog( "Starting up fresh blockchain with default genesis state." ); + my->genesis.emplace(); } } @@ -1142,7 +1132,7 @@ bool chain_plugin::recover_reversible_blocks( const fc::path& db_dir, uint32_t c ilog( "Reconstructing '${reversible_dir}' from backed up reversible directory", ("reversible_dir", reversible_dir) ); - optional old_reversible; + optional old_reversible; try { old_reversible = chainbase::database( backup_dir, database::read_only, 0, true ); diff --git a/unittests/snapshot_tests.cpp b/unittests/snapshot_tests.cpp index b6a0e85a704..3024a6716bb 100644 --- a/unittests/snapshot_tests.cpp +++ b/unittests/snapshot_tests.cpp @@ -497,7 +497,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_pending_schedule_snapshot, SNAPSHOT_SUITE, sn auto reader = SNAPSHOT_SUITE::get_reader(v2); snapshotted_tester v2_tester(chain.get_config(), reader, ordinal++); - auto chain_id = chain::controller::extract_chain_id(reader); + auto chain_id = chain::controller::extract_chain_id(*reader); BOOST_REQUIRE_EQUAL(chain_id, v2_tester.control->get_chain_id()); BOOST_REQUIRE_EQUAL(chain.control->get_chain_id(), v2_tester.control->get_chain_id()); verify_integrity_hash(*chain.control, *v2_tester.control); From 16d7e8461f7cfa613bfb9d2f4792e8849a224979 Mon Sep 17 00:00:00 2001 From: arhag Date: Sat, 21 Sep 2019 00:17:31 -0400 Subject: [PATCH 2/2] address review comments by @heifner --- libraries/chain/controller.cpp | 14 +++++++------- plugins/chain_plugin/chain_plugin.cpp | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index 612249bc830..a6aca78e3e0 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -559,8 +559,8 @@ struct controller_impl { void startup(std::function shutdown, const genesis_state& genesis) { EOS_ASSERT( db.revision() < 1, database_exception, "This version of controller::startup only works with a fresh state database." ); const auto& genesis_chain_id = genesis.compute_chain_id(); - EOS_ASSERT( genesis_chain_id == chain_id, misc_exception, - "genesis state provided to startup does not match the chain ID that controller was constructed with", + EOS_ASSERT( genesis_chain_id == chain_id, chain_id_type_exception, + "genesis state provided to startup corresponds to a chain ID (${genesis_chain_id}) that does not match the chain ID that controller was constructed with (${controller_chain_id})", ("genesis_chain_id", genesis_chain_id)("controller_chain_id", chain_id) ); @@ -597,7 +597,7 @@ struct controller_impl { if( blog.head() ) { EOS_ASSERT( first_block_num <= lib_num && lib_num <= blog.head()->block_num(), block_log_exception, - "block log does not contain last irreversible block", + "block log (ranging from ${block_log_first_num} to ${block_log_last_num}) does not contain the last irreversible block (${fork_db_lib})", ("block_log_first_num", first_block_num) ("block_log_last_num", blog.head()->block_num()) ("fork_db_lib", lib_num) @@ -640,7 +640,7 @@ struct controller_impl { // Also, even though blog.head() may still be nullptr, blog.first_block_num() is guaranteed to be lib_num + 1. EOS_ASSERT( db.revision() >= head->block_num, fork_database_exception, - "fork database head is inconsistent with state", + "fork database head (${head}) is inconsistent with state (${db})", ("db",db.revision())("head",head->block_num) ); if( db.revision() > head->block_num ) { @@ -671,7 +671,7 @@ struct controller_impl { reversible_blocks.remove( *itr ); EOS_ASSERT( itr == rbi.end() || itr->blocknum == lib_num + 1, reversible_blocks_exception, - "gap exists between last irreversible block and first reversible block", + "gap exists between last irreversible block (${lib}) and first reversible block (${first_reversible_block_num})", ("lib", lib_num)("first_reversible_block_num", itr->blocknum) ); @@ -958,8 +958,8 @@ struct controller_impl { }); const auto& gpo = db.get(); - EOS_ASSERT( gpo.chain_id == chain_id, misc_exception, - "chain ID in snapshot does not match the chain ID that controller was constructed with", + EOS_ASSERT( gpo.chain_id == chain_id, chain_id_type_exception, + "chain ID in snapshot (${snapshot_chain_id}) does not match the chain ID that controller was constructed with (${controller_chain_id})", ("snapshot_chain_id", gpo.chain_id)("controller_chain_id", chain_id) ); } diff --git a/plugins/chain_plugin/chain_plugin.cpp b/plugins/chain_plugin/chain_plugin.cpp index c6cc5b8997b..80628782d52 100644 --- a/plugins/chain_plugin/chain_plugin.cpp +++ b/plugins/chain_plugin/chain_plugin.cpp @@ -845,7 +845,7 @@ void chain_plugin::plugin_initialize(const variables_map& options) { const auto& block_log_chain_id = my->genesis->compute_chain_id(); EOS_ASSERT( expected_chain_id == block_log_chain_id, plugin_config_exception, - "snapshot chain id does not match the chain id from the genesis state in the block log.", + "snapshot chain ID (${snapshot_chain_id}) does not match the chain ID from the genesis state in the block log (${block_log_chain_id})", ("snapshot_chain_id", expected_chain_id) ("block_log_chain_id", block_log_chain_id) ); @@ -853,7 +853,7 @@ void chain_plugin::plugin_initialize(const variables_map& options) { const auto& block_log_chain_id = block_log::extract_chain_id(my->blocks_dir); EOS_ASSERT( expected_chain_id == block_log_chain_id, plugin_config_exception, - "snapshot chain id does not match the chain id in the block log.", + "snapshot chain ID (${snapshot_chain_id}) does not match the chain ID (${block_log_chain_id}) in the block log", ("snapshot_chain_id", expected_chain_id) ("block_log_chain_id", block_log_chain_id) );