diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index d114a2b3a9..5fbc600603 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -2681,7 +2681,7 @@ struct controller_impl { #ifdef EOSIO_EOS_VM_OC_RUNTIME_ENABLED bool is_eos_vm_oc_enabled() const { - return ( conf.eosvmoc_tierup || conf.wasm_runtime == wasm_interface::vm_type::eos_vm_oc ); + return ( (conf.eosvmoc_tierup != wasm_interface::vm_oc_enable::oc_none) || conf.wasm_runtime == wasm_interface::vm_type::eos_vm_oc ); } #endif diff --git a/libraries/chain/include/eosio/chain/controller.hpp b/libraries/chain/include/eosio/chain/controller.hpp index 97bc488084..f90072bdb7 100644 --- a/libraries/chain/include/eosio/chain/controller.hpp +++ b/libraries/chain/include/eosio/chain/controller.hpp @@ -90,7 +90,7 @@ namespace eosio { namespace chain { wasm_interface::vm_type wasm_runtime = chain::config::default_wasm_runtime; eosvmoc::config eosvmoc_config; - bool eosvmoc_tierup = false; + wasm_interface::vm_oc_enable eosvmoc_tierup = wasm_interface::vm_oc_enable::oc_auto; db_read_mode read_mode = db_read_mode::HEAD; validation_mode block_validation_mode = validation_mode::FULL; diff --git a/libraries/chain/include/eosio/chain/wasm_interface.hpp b/libraries/chain/include/eosio/chain/wasm_interface.hpp index 8d832a17ff..440863cd54 100644 --- a/libraries/chain/include/eosio/chain/wasm_interface.hpp +++ b/libraries/chain/include/eosio/chain/wasm_interface.hpp @@ -40,7 +40,13 @@ namespace eosio { namespace chain { } } - wasm_interface(vm_type vm, bool eosvmoc_tierup, const chainbase::database& d, const std::filesystem::path data_dir, const eosvmoc::config& eosvmoc_config, bool profile); + enum class vm_oc_enable { + oc_auto, + oc_all, + oc_none + }; + + wasm_interface(vm_type vm, vm_oc_enable eosvmoc_tierup, const chainbase::database& d, const std::filesystem::path data_dir, const eosvmoc::config& eosvmoc_config, bool profile); ~wasm_interface(); // initialize exec per thread diff --git a/libraries/chain/include/eosio/chain/wasm_interface_private.hpp b/libraries/chain/include/eosio/chain/wasm_interface_private.hpp index 825861ac58..09160c4db7 100644 --- a/libraries/chain/include/eosio/chain/wasm_interface_private.hpp +++ b/libraries/chain/include/eosio/chain/wasm_interface_private.hpp @@ -41,7 +41,6 @@ namespace eosio { namespace chain { uint8_t vm_version = 0; }; struct by_hash; - struct by_first_block_num; struct by_last_block_num; #ifdef EOSIO_EOS_VM_OC_RUNTIME_ENABLED @@ -65,7 +64,7 @@ namespace eosio { namespace chain { }; #endif - wasm_interface_impl(wasm_interface::vm_type vm, bool eosvmoc_tierup, const chainbase::database& d, const std::filesystem::path data_dir, const eosvmoc::config& eosvmoc_config, bool profile) : db(d), wasm_runtime_time(vm) { + wasm_interface_impl(wasm_interface::vm_type vm, wasm_interface::vm_oc_enable eosvmoc_tierup, const chainbase::database& d, const std::filesystem::path data_dir, const eosvmoc::config& eosvmoc_config, bool profile) : db(d), wasm_runtime_time(vm) { #ifdef EOSIO_EOS_VM_RUNTIME_ENABLED if(vm == wasm_interface::vm_type::eos_vm) runtime_interface = std::make_unique>(); @@ -86,7 +85,7 @@ namespace eosio { namespace chain { EOS_THROW(wasm_exception, "${r} wasm runtime not supported on this platform and/or configuration", ("r", vm)); #ifdef EOSIO_EOS_VM_OC_RUNTIME_ENABLED - if(eosvmoc_tierup) { + if(eosvmoc_tierup != wasm_interface::vm_oc_enable::oc_none) { EOS_ASSERT(vm != wasm_interface::vm_type::eos_vm_oc, wasm_exception, "You can't use EOS VM OC as the base runtime when tier up is activated"); eosvmoc.emplace(data_dir, eosvmoc_config, d); } diff --git a/libraries/chain/wasm_interface.cpp b/libraries/chain/wasm_interface.cpp index c66a514eec..6ceff2e68f 100644 --- a/libraries/chain/wasm_interface.cpp +++ b/libraries/chain/wasm_interface.cpp @@ -32,7 +32,7 @@ namespace eosio { namespace chain { - wasm_interface::wasm_interface(vm_type vm, bool eosvmoc_tierup, const chainbase::database& d, const std::filesystem::path data_dir, const eosvmoc::config& eosvmoc_config, bool profile) + wasm_interface::wasm_interface(vm_type vm, vm_oc_enable eosvmoc_tierup, const chainbase::database& d, const std::filesystem::path data_dir, const eosvmoc::config& eosvmoc_config, bool profile) : my( new wasm_interface_impl(vm, eosvmoc_tierup, d, data_dir, eosvmoc_config, profile) ), vm( vm ) {} wasm_interface::~wasm_interface() {} diff --git a/plugins/chain_plugin/chain_plugin.cpp b/plugins/chain_plugin/chain_plugin.cpp index 1544853fbd..a83d7d31ff 100644 --- a/plugins/chain_plugin/chain_plugin.cpp +++ b/plugins/chain_plugin/chain_plugin.cpp @@ -114,6 +114,43 @@ void validate(boost::any& v, } } +std::ostream& operator<<(std::ostream& os, wasm_interface::vm_oc_enable t) { + if (t == wasm_interface::vm_oc_enable::oc_auto) { + os << "auto"; + } else if (t == wasm_interface::vm_oc_enable::oc_all) { + os << "all"; + } else if (t == wasm_interface::vm_oc_enable::oc_none) { + os << "none"; + } + + return os; +} + +void validate(boost::any& v, + const std::vector& values, + wasm_interface::vm_oc_enable* /* target_type */, + int) +{ + using namespace boost::program_options; + + // Make sure no previous assignment to 'v' was made. + validators::check_first_occurrence(v); + + // Extract the first string from 'values'. If there is more than + // one string, it's an error, and exception will be thrown. + std::string const& s = validators::get_single_string(values); + + if (s == "auto") { + v = boost::any(wasm_interface::vm_oc_enable::oc_auto); + } else if (s == "all" || s == "true" || s == "on") { + v = boost::any(wasm_interface::vm_oc_enable::oc_all); + } else if (s == "none" || s == "false" || s == "off") { + v = boost::any(wasm_interface::vm_oc_enable::oc_none); + } else { + throw validation_error(validation_error::invalid_option_value); + } +} + } // namespace chain using namespace eosio; @@ -203,6 +240,7 @@ chain_plugin::chain_plugin() app().register_config_type(); app().register_config_type(); app().register_config_type(); + app().register_config_type(); } chain_plugin::~chain_plugin() = default; @@ -227,7 +265,7 @@ void chain_plugin::set_program_options(options_description& cli, options_descrip #ifdef EOSIO_EOS_VM_OC_DEVELOPER wasm_runtime_opt += delim + "\"eos-vm-oc\""; - wasm_runtime_desc += "\"eos-vm-oc\" : Unsupported. Instead, use one of the other runtimes along with the option enable-eos-vm-oc.\n"; + wasm_runtime_desc += "\"eos-vm-oc\" : Unsupported. Instead, use one of the other runtimes along with the option eos-vm-oc-enable.\n"; #endif wasm_runtime_opt += ")\n" + wasm_runtime_desc; @@ -334,7 +372,11 @@ void chain_plugin::set_program_options(options_description& cli, options_descrip EOS_ASSERT(false, plugin_exception, ""); } }), "Number of threads to use for EOS VM OC tier-up") - ("eos-vm-oc-enable", bpo::bool_switch(), "Enable EOS VM OC tier-up runtime") + ("eos-vm-oc-enable", bpo::value()->default_value(chain::wasm_interface::vm_oc_enable::oc_auto), + "Enable EOS VM OC tier-up runtime ('auto', 'all', 'none').\n" + "'auto' - EOS VM OC tier-up is enabled for eosio.* accounts and read-only trxs.\n" + "'all' - EOS VM OC tier-up is enabled for all contract execution.\n" + "'none' - EOS VM OC tier-up is completely disabled.\n") #endif ("enable-account-queries", bpo::value()->default_value(false), "enable queries to find accounts by various metadata.") ("max-nonprivileged-inline-action-size", bpo::value()->default_value(config::default_max_nonprivileged_inline_action_size), "maximum allowed size (in bytes) of an inline action for a nonprivileged account") @@ -907,8 +949,7 @@ void chain_plugin_impl::plugin_initialize(const variables_map& options) { chain_config->eosvmoc_config.cache_size = options.at( "eos-vm-oc-cache-size-mb" ).as() * 1024u * 1024u; if( options.count("eos-vm-oc-compile-threads") ) chain_config->eosvmoc_config.threads = options.at("eos-vm-oc-compile-threads").as(); - if( options["eos-vm-oc-enable"].as() ) - chain_config->eosvmoc_tierup = true; + chain_config->eosvmoc_tierup = options["eos-vm-oc-enable"].as(); #endif account_queries_enabled = options.at("enable-account-queries").as();