Skip to content

Commit

Permalink
GH-984 Updated comments and clean up args for get_descriptor_for_code
Browse files Browse the repository at this point in the history
  • Loading branch information
heifner committed Nov 5, 2024
1 parent 5ae808a commit e5fa319
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 13 deletions.
2 changes: 1 addition & 1 deletion libraries/chain/apply_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1103,7 +1103,7 @@ bool apply_context::is_eos_vm_oc_whitelisted() const {
// Compute trx | baseline, OC for eosio.*
// Read only trx | OC
bool apply_context::should_use_eos_vm_oc()const {
return is_eos_vm_oc_whitelisted() // all cases use OC
return is_eos_vm_oc_whitelisted() // all whitelisted accounts use OC always
|| (is_applying_block() && !control.is_producer_node()) // validating/applying block
|| trx_context.is_read_only();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,15 @@ class code_cache_async : public code_cache_base {
code_cache_async(const std::filesystem::path& data_dir, const eosvmoc::config& eosvmoc_config, const chainbase::database& db);
~code_cache_async();

struct mode {
bool whitelisted = false;
bool high_priority = false;
bool write_window = true;
};
//If code is in cache: returns pointer & bumps to front of MRU list
//If code is not in cache, and not blacklisted, and not currently compiling: return nullptr and kick off compile
//otherwise: return nullptr
const code_descriptor* const get_descriptor_for_code(bool high_priority, const digest_type& code_id, const uint8_t& vm_version, bool is_write_window, get_cd_failure& failure);
const code_descriptor* const get_descriptor_for_code(mode m, const digest_type& code_id, const uint8_t& vm_version, get_cd_failure& failure);

private:
std::thread _monitor_reply_thread;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ struct config {
uint64_t get_cache_size() const { return cache_size; }
uint64_t get_threads() const { return threads; }

// empty optional means no rlimit
std::optional<rlim_t> get_cpu_limit() const { return !whitelisted ? cpu_limit : std::optional<rlim_t>{}; }
// empty optional means no rlimit
std::optional<rlim_t> get_vm_limit() const { return !whitelisted ? vm_limit : std::optional<rlim_t>{}; }

uint64_t get_stack_size_limit() const {
Expand Down
13 changes: 9 additions & 4 deletions libraries/chain/wasm_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,15 @@ namespace eosio { namespace chain {
const chain::eosvmoc::code_descriptor* cd = nullptr;
chain::eosvmoc::code_cache_base::get_cd_failure failure = chain::eosvmoc::code_cache_base::get_cd_failure::temporary;
try {
// Not high priority with producing a block since we want validators to have a higher probability of having
// already switched to oc by the time the producer has switched to oc.
const bool high_priority = context.is_eos_vm_oc_whitelisted() && context.is_applying_block();
cd = my->eosvmoc->cc.get_descriptor_for_code(high_priority, code_hash, vm_version, context.control.is_write_window(), failure);
// Ideally all validator nodes would switch to using oc before block producer nodes so that validators
// are never overwhelmed. Compile whitelisted account contracts first on non-produced blocks. This makes
// it more likely that validators will switch to the oc compiled contract before the block producer runs
// an action for the contract with oc.
chain::eosvmoc::code_cache_async::mode m;
m.whitelisted = context.is_eos_vm_oc_whitelisted();
m.high_priority = m.whitelisted && context.is_applying_block();
m.write_window = context.control.is_write_window();
cd = my->eosvmoc->cc.get_descriptor_for_code(m, code_hash, vm_version, failure);
if (test_disable_tierup)
cd = nullptr;
} catch (...) {
Expand Down
15 changes: 8 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 @@ -106,11 +106,11 @@ std::tuple<size_t, size_t> code_cache_async::consume_compile_thread_queue() {
}


const code_descriptor* const code_cache_async::get_descriptor_for_code(bool high_priority, const digest_type& code_id, const uint8_t& vm_version, bool is_write_window, get_cd_failure& failure) {
const code_descriptor* const code_cache_async::get_descriptor_for_code(mode m, const digest_type& code_id, const uint8_t& vm_version, get_cd_failure& failure) {
//if there are any outstanding compiles, process the result queue now
//When app is in write window, all tasks are running sequentially and read-only threads
//are not running. Safe to update cache entries.
if(is_write_window && _outstanding_compiles_and_poison.size()) {
if(m.write_window && _outstanding_compiles_and_poison.size()) {
auto [count_processed, bytes_remaining] = consume_compile_thread_queue();

if(count_processed)
Expand All @@ -127,7 +127,7 @@ const code_descriptor* const code_cache_async::get_descriptor_for_code(bool high
std::vector<wrapped_fd> fds_to_pass;
fds_to_pass.emplace_back(memfd_for_bytearray(codeobject->code));
auto msg = compile_wasm_message{ *nextup, _eosvmoc_config };
msg.eosvmoc_config.whitelisted = high_priority;
msg.eosvmoc_config.whitelisted = m.whitelisted;
FC_ASSERT(write_message_with_fds(_compile_monitor_write_socket, msg, fds_to_pass), "EOS VM failed to communicate to OOP manager");
--count_processed;
}
Expand All @@ -138,22 +138,23 @@ const code_descriptor* const code_cache_async::get_descriptor_for_code(bool high
//check for entry in cache
code_cache_index::index<by_hash>::type::iterator it = _cache_index.get<by_hash>().find(boost::make_tuple(code_id, vm_version));
if(it != _cache_index.get<by_hash>().end()) {
if (is_write_window)
if (m.write_window)
_cache_index.relocate(_cache_index.begin(), _cache_index.project<0>(it));
return &*it;
}
if(!is_write_window) {
if(!m.write_window) {
failure = get_cd_failure::temporary; // Compile might not be done yet
return nullptr;
}

const code_tuple ct = code_tuple{code_id, vm_version};

if(_blacklist.find(ct) != _blacklist.end()) {
if (!high_priority) {
if (!m.whitelisted) {
failure = get_cd_failure::permanent; // Compile will not start
return nullptr;
}
// whitelisted, remove from blacklist and allow to try compile again
_blacklist.erase(ct);
}
if(auto it = _outstanding_compiles_and_poison.find(ct); it != _outstanding_compiles_and_poison.end()) {
Expand All @@ -167,7 +168,7 @@ const code_descriptor* const code_cache_async::get_descriptor_for_code(bool high
}

if(_outstanding_compiles_and_poison.size() >= _threads) {
if (high_priority)
if (m.high_priority)
_queued_compiles.push_front(ct);
else
_queued_compiles.push_back(ct);
Expand Down

0 comments on commit e5fa319

Please sign in to comment.