Skip to content

Commit

Permalink
Merge pull request #1787 from AntelopeIO/GH-1406-code-cache-5.0
Browse files Browse the repository at this point in the history
[4.0 -> 5.0] Recreate EOS VM OC code cache if corrupt
  • Loading branch information
heifner authored Oct 17, 2023
2 parents 92fa264 + 34e097f commit c03e460
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 16 deletions.
30 changes: 23 additions & 7 deletions libraries/chain/webassembly/runtimes/eos-vm-oc/code_cache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,13 +226,13 @@ const code_descriptor* const code_cache_sync::get_descriptor_for_code_sync(const

code_cache_base::code_cache_base(const std::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");

std::filesystem::create_directories(data_dir);

if(!std::filesystem::exists(_cache_file_path)) {
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");
Expand All @@ -241,19 +241,35 @@ code_cache_base::code_cache_base(const std::filesystem::path& data_dir, const eo
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;
};

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 (!std::filesystem::exists(_cache_file_path)) {
create_code_cache_file();
}

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");
try {
check_code_cache();
} catch (const fc::exception&) {
if (created_file)
throw;

ilog("EOS VM optimized Compiler code cache corrupt, recreating");
create_code_cache_file();
check_code_cache();
}

set_on_disk_region_dirty(true);

Expand Down
10 changes: 1 addition & 9 deletions plugins/chain_plugin/chain_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -459,14 +459,6 @@ void clear_directory_contents( const std::filesystem::path& p ) {
}
}

void clear_chainbase_files( const std::filesystem::path& p ) {
if( !std::filesystem::is_directory( p ) )
return;

std::filesystem::remove( p / "shared_memory.bin" );
std::filesystem::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) {
Expand Down Expand Up @@ -758,7 +750,7 @@ void chain_plugin_impl::plugin_initialize(const variables_map& options) {
ilog( "Replay requested: deleting state database" );
if( options.at( "truncate-at-block" ).as<uint32_t>() > 0 )
wlog( "The --truncate-at-block option does not work for a regular replay of the blockchain." );
clear_chainbase_files( chain_config->state_dir );
clear_directory_contents( chain_config->state_dir );
} else if( options.at( "truncate-at-block" ).as<uint32_t>() > 0 ) {
wlog( "The --truncate-at-block option can only be used with --hard-replay-blockchain." );
}
Expand Down

0 comments on commit c03e460

Please sign in to comment.