From 6cb1237e718b7638e904d2d9f3337fa65e511da3 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Mon, 16 Oct 2023 12:45:41 -0500 Subject: [PATCH 1/3] GH-1406 code_cache not likely to be useful for replay, remove all state files for replay --- plugins/chain_plugin/chain_plugin.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/plugins/chain_plugin/chain_plugin.cpp b/plugins/chain_plugin/chain_plugin.cpp index 99612f7282..16855ed95f 100644 --- a/plugins/chain_plugin/chain_plugin.cpp +++ b/plugins/chain_plugin/chain_plugin.cpp @@ -432,14 +432,6 @@ void clear_directory_contents( const fc::path& p ) { } } -void clear_chainbase_files( const fc::path& p ) { - if( !fc::is_directory( p ) ) - return; - - fc::remove( p / "shared_memory.bin" ); - fc::remove( p / "shared_memory.meta" ); -} - namespace { // This can be removed when versions of eosio that support reversible chainbase state file no longer supported. void upgrade_from_reversible_to_fork_db(chain_plugin_impl* my) { @@ -732,7 +724,7 @@ void chain_plugin::plugin_initialize(const variables_map& options) { ilog( "Replay requested: deleting state database" ); if( options.at( "truncate-at-block" ).as() > 0 ) wlog( "The --truncate-at-block option does not work for a regular replay of the blockchain." ); - clear_chainbase_files( my->chain_config->state_dir ); + clear_directory_contents( my->chain_config->state_dir ); } else if( options.at( "truncate-at-block" ).as() > 0 ) { wlog( "The --truncate-at-block option can only be used with --hard-replay-blockchain." ); } From d6882ddf1cf484dfa4dbca6f6d49b7eef9217e42 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Mon, 16 Oct 2023 12:46:13 -0500 Subject: [PATCH 2/3] GH-1406 Re-create code cache on startup if it is corrupt --- .../runtimes/eos-vm-oc/code_cache.cpp | 43 +++++++++++++------ 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/libraries/chain/webassembly/runtimes/eos-vm-oc/code_cache.cpp b/libraries/chain/webassembly/runtimes/eos-vm-oc/code_cache.cpp index aba47f4ef2..f76fd79a58 100644 --- a/libraries/chain/webassembly/runtimes/eos-vm-oc/code_cache.cpp +++ b/libraries/chain/webassembly/runtimes/eos-vm-oc/code_cache.cpp @@ -224,14 +224,15 @@ const code_descriptor* const code_cache_sync::get_descriptor_for_code_sync(const code_cache_base::code_cache_base(const boost::filesystem::path data_dir, const eosvmoc::config& eosvmoc_config, const chainbase::database& db) : _db(db), - _cache_file_path(data_dir/"code_cache.bin") -{ + _cache_file_path(data_dir/"code_cache.bin") { static_assert(sizeof(allocator_t) <= header_offset, "header offset intersects with allocator"); bfs::create_directories(data_dir); - if(!bfs::exists(_cache_file_path)) { - EOS_ASSERT(eosvmoc_config.cache_size >= allocator_t::get_min_size(total_header_size), database_exception, "configured code cache size is too small"); + bool created_file = false; + auto create_code_cache_file = [&] { + EOS_ASSERT(eosvmoc_config.cache_size >= allocator_t::get_min_size(total_header_size), database_exception, + "configured code cache size is too small"); std::ofstream ofs(_cache_file_path.generic_string(), std::ofstream::trunc); EOS_ASSERT(ofs.good(), database_exception, "unable to create EOS VM Optimized Compiler code cache"); bfs::resize_file(_cache_file_path, eosvmoc_config.cache_size); @@ -239,19 +240,35 @@ code_cache_base::code_cache_base(const boost::filesystem::path data_dir, const e bip::mapped_region creation_region(creation_mapping, bip::read_write); new (creation_region.get_address()) allocator_t(eosvmoc_config.cache_size, total_header_size); new ((char*)creation_region.get_address() + header_offset) code_cache_header; + created_file = true; + }; + + if (!bfs::exists(_cache_file_path)) { + create_code_cache_file(); } code_cache_header cache_header; - { - char header_buff[total_header_size]; - std::ifstream hs(_cache_file_path.generic_string(), std::ifstream::binary); - hs.read(header_buff, sizeof(header_buff)); - EOS_ASSERT(!hs.fail(), bad_database_version_exception, "failed to read code cache header"); - memcpy((char*)&cache_header, header_buff + header_offset, sizeof(cache_header)); - } + while (true) { + try { + { + char header_buff[total_header_size]; + std::ifstream hs(_cache_file_path.generic_string(), std::ifstream::binary); + hs.read(header_buff, sizeof(header_buff)); + EOS_ASSERT(!hs.fail(), bad_database_version_exception, "failed to read code cache header"); + memcpy((char*)&cache_header, header_buff + header_offset, sizeof(cache_header)); + } - EOS_ASSERT(cache_header.id == header_id, bad_database_version_exception, "existing EOS VM OC code cache not compatible with this version"); - EOS_ASSERT(!cache_header.dirty, database_exception, "code cache is dirty"); + EOS_ASSERT(cache_header.id == header_id, bad_database_version_exception, "existing EOS VM OC code cache not compatible with this version"); + EOS_ASSERT(!cache_header.dirty, database_exception, "code cache is dirty"); + break; + } catch (const fc::exception&) { + if (created_file) + throw; + + ilog("EOS VM optimized Compiler code cache corrupt, recreating"); + create_code_cache_file(); + } + } set_on_disk_region_dirty(true); From 76f1c7a0332bb24c029d0d42ffb5c227c38cf3dd Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Tue, 17 Oct 2023 07:43:02 -0500 Subject: [PATCH 3/3] GH-1406 Remove while loop and use lambda instead --- .../runtimes/eos-vm-oc/code_cache.cpp | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/libraries/chain/webassembly/runtimes/eos-vm-oc/code_cache.cpp b/libraries/chain/webassembly/runtimes/eos-vm-oc/code_cache.cpp index f76fd79a58..31aa3f3c8b 100644 --- a/libraries/chain/webassembly/runtimes/eos-vm-oc/code_cache.cpp +++ b/libraries/chain/webassembly/runtimes/eos-vm-oc/code_cache.cpp @@ -243,31 +243,31 @@ code_cache_base::code_cache_base(const boost::filesystem::path data_dir, const e created_file = true; }; + code_cache_header cache_header; + auto check_code_cache = [&] { + char header_buff[total_header_size]; + std::ifstream hs(_cache_file_path.generic_string(), std::ifstream::binary); + hs.read(header_buff, sizeof(header_buff)); + EOS_ASSERT(!hs.fail(), bad_database_version_exception, "failed to read code cache header"); + memcpy((char*)&cache_header, header_buff + header_offset, sizeof(cache_header)); + + EOS_ASSERT(cache_header.id == header_id, bad_database_version_exception, "existing EOS VM OC code cache not compatible with this version"); + EOS_ASSERT(!cache_header.dirty, database_exception, "code cache is dirty"); + }; + if (!bfs::exists(_cache_file_path)) { create_code_cache_file(); } - code_cache_header cache_header; - while (true) { - try { - { - char header_buff[total_header_size]; - std::ifstream hs(_cache_file_path.generic_string(), std::ifstream::binary); - hs.read(header_buff, sizeof(header_buff)); - EOS_ASSERT(!hs.fail(), bad_database_version_exception, "failed to read code cache header"); - memcpy((char*)&cache_header, header_buff + header_offset, sizeof(cache_header)); - } + try { + check_code_cache(); + } catch (const fc::exception&) { + if (created_file) + throw; - EOS_ASSERT(cache_header.id == header_id, bad_database_version_exception, "existing EOS VM OC code cache not compatible with this version"); - EOS_ASSERT(!cache_header.dirty, database_exception, "code cache is dirty"); - break; - } catch (const fc::exception&) { - if (created_file) - throw; - - ilog("EOS VM optimized Compiler code cache corrupt, recreating"); - create_code_cache_file(); - } + ilog("EOS VM optimized Compiler code cache corrupt, recreating"); + create_code_cache_file(); + check_code_cache(); } set_on_disk_region_dirty(true);