Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Commit

Permalink
Merge pull request #8360 from EOSIO/wasm-config
Browse files Browse the repository at this point in the history
Make wasm constraints configurable
  • Loading branch information
arhag authored Apr 27, 2020
2 parents 4bdc44f + 5d06cfc commit c356876
Show file tree
Hide file tree
Showing 55 changed files with 1,784 additions and 326 deletions.
5 changes: 5 additions & 0 deletions libraries/chain/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ else()
endif()

if("eos-vm-oc" IN_LIST EOSIO_WASM_RUNTIMES)
enable_language(ASM)
set(CHAIN_EOSVMOC_SOURCES webassembly/runtimes/eos-vm-oc/code_cache.cpp
webassembly/runtimes/eos-vm-oc/executor.cpp
webassembly/runtimes/eos-vm-oc/memory.cpp
Expand All @@ -28,9 +29,12 @@ if("eos-vm-oc" IN_LIST EOSIO_WASM_RUNTIMES)
webassembly/runtimes/eos-vm-oc/compile_trampoline.cpp
webassembly/runtimes/eos-vm-oc/ipc_helpers.cpp
webassembly/runtimes/eos-vm-oc/gs_seg_helpers.c
webassembly/runtimes/eos-vm-oc/stack.cpp
webassembly/runtimes/eos-vm-oc/switch_stack_linux.s
webassembly/runtimes/eos-vm-oc.cpp
webassembly/runtimes/eos-vm-oc/default_real_main.cpp)


if(LLVM_VERSION VERSION_LESS 7.1 AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
enable_language(ASM-LLVMWAR)
list(APPEND CHAIN_EOSVMOC_SOURCES webassembly/runtimes/eos-vm-oc/llvmWARshim.llvmwar)
Expand Down Expand Up @@ -97,6 +101,7 @@ add_library( eosio_chain
wasm_interface.cpp
wasm_eosio_validation.cpp
wasm_eosio_injection.cpp
wasm_config.cpp
apply_context.cpp
abi_serializer.cpp
asset.cpp
Expand Down
17 changes: 15 additions & 2 deletions libraries/chain/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ struct controller_impl {
set_activation_handler<builtin_protocol_feature_t::wtmsig_block_signatures>();
set_activation_handler<builtin_protocol_feature_t::action_return_value>();
set_activation_handler<builtin_protocol_feature_t::kv_database>();
set_activation_handler<builtin_protocol_feature_t::configurable_wasm_limits>();

self.irreversible_block.connect([this](const block_state_ptr& bsp) {
wasmif.current_lib(bsp->block_num);
Expand Down Expand Up @@ -965,7 +966,8 @@ struct controller_impl {
section.read_row(legacy_global_properties, db);

db.create<global_property_object>([&legacy_global_properties,&gs_chain_id](auto& gpo ){
gpo.initalize_from(legacy_global_properties, gs_chain_id, kv_config{});
gpo.initalize_from(legacy_global_properties, gs_chain_id, kv_config{},
genesis_state::default_initial_wasm_configuration);
});
});
return; // early out to avoid default processing
Expand All @@ -977,7 +979,8 @@ struct controller_impl {
section.read_row(legacy_global_properties, db);

db.create<global_property_object>([&legacy_global_properties](auto& gpo ){
gpo.initalize_from(legacy_global_properties, kv_config{});
gpo.initalize_from(legacy_global_properties, kv_config{},
genesis_state::default_initial_wasm_configuration);
});
});
return; // early out to avoid default processing
Expand Down Expand Up @@ -1082,6 +1085,8 @@ struct controller_impl {
db.create<global_property_object>([&genesis,&chain_id=this->chain_id](auto& gpo ){
gpo.configuration = genesis.initial_configuration;
gpo.kv_configuration = kv_config{};
// TODO: Update this when genesis protocol features are enabled.
gpo.wasm_configuration = genesis_state::default_initial_wasm_configuration;
gpo.chain_id = chain_id;
});

Expand Down Expand Up @@ -3549,6 +3554,14 @@ void controller_impl::on_activation<builtin_protocol_feature_t::kv_database>() {
} );
}

template<>
void controller_impl::on_activation<builtin_protocol_feature_t::configurable_wasm_limits>() {
db.modify( db.get<protocol_state_object>(), [&]( auto& ps ) {
add_intrinsic_to_whitelist( ps.whitelisted_intrinsics, "set_wasm_parameters_packed" );
add_intrinsic_to_whitelist( ps.whitelisted_intrinsics, "get_wasm_parameters_packed" );
} );
}


/// End of protocol feature activation handlers

Expand Down
1 change: 1 addition & 0 deletions libraries/chain/include/eosio/chain/chain_snapshot.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ struct chain_snapshot_header {
* - forwards compatible with versions 2 and 3
* - kv database
* - DISK resource
* - Configurable wasm limits
*/

static constexpr uint32_t minimum_compatible_version = 2;
Expand Down
12 changes: 12 additions & 0 deletions libraries/chain/include/eosio/chain/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,18 @@ const static uint32_t default_max_kv_key_size = 1024;
const static uint32_t default_max_kv_value_size = 1024*1024; // Large enough to hold most contracts
const static uint32_t default_max_kv_iterators = 1024;

const static uint32_t default_max_wasm_mutable_global_bytes = 1024;
const static uint32_t default_max_wasm_table_elements = 1024;
const static uint32_t default_max_wasm_section_elements = 8192;
const static uint32_t default_max_wasm_linear_memory_init = 64*1024;
const static uint32_t default_max_wasm_func_local_bytes = 8192;
const static uint32_t default_max_wasm_nested_structures = 1024;
const static uint32_t default_max_wasm_symbol_bytes = 8192;
const static uint32_t default_max_wasm_module_bytes = 20*1024*1024;
const static uint32_t default_max_wasm_code_bytes = 20*1024*1024;
const static uint32_t default_max_wasm_pages = 528;
const static uint32_t default_max_wasm_call_depth = 251;

const static uint32_t min_net_usage_delta_between_base_and_max_for_trx = 10*1024;
// Should be large enough to allow recovery from badly set blockchain parameters without a hard fork
// (unless net_usage_leeway is set to 0 and so are the net limits of all accounts that can help with resetting blockchain parameters).
Expand Down
2 changes: 2 additions & 0 deletions libraries/chain/include/eosio/chain/exceptions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,8 @@ namespace eosio { namespace chain {
3160013, "The key or value is too large" )
FC_DECLARE_DERIVED_EXCEPTION( kv_unknown_parameters_version, contract_exception,
3160014, "Unknown kv_parameters version" )
FC_DECLARE_DERIVED_EXCEPTION( wasm_config_unknown_version, contract_exception,
3160015, "Unknown wasm_config version" )

FC_DECLARE_DERIVED_EXCEPTION( producer_exception, chain_exception,
3170000, "Producer exception" )
Expand Down
15 changes: 15 additions & 0 deletions libraries/chain/include/eosio/chain/genesis_state.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <eosio/chain/chain_config.hpp>
#include <eosio/chain/wasm_config.hpp>
#include <eosio/chain/types.hpp>

#include <fc/crypto/sha256.hpp>
Expand Down Expand Up @@ -37,6 +38,20 @@ struct genesis_state {
.max_authority_depth = config::default_max_auth_depth,
};

static constexpr wasm_config default_initial_wasm_configuration {
.max_mutable_global_bytes = config::default_max_wasm_mutable_global_bytes,
.max_table_elements = config::default_max_wasm_table_elements,
.max_section_elements = config::default_max_wasm_section_elements,
.max_linear_memory_init = config::default_max_wasm_linear_memory_init,
.max_func_local_bytes = config::default_max_wasm_func_local_bytes,
.max_nested_structures = config::default_max_wasm_nested_structures,
.max_symbol_bytes = config::default_max_wasm_symbol_bytes,
.max_module_bytes = config::default_max_wasm_module_bytes,
.max_code_bytes = config::default_max_wasm_code_bytes,
.max_pages = config::default_max_wasm_pages,
.max_call_depth = config::default_max_wasm_call_depth
};

time_point initial_timestamp;
public_key_type initial_key;

Expand Down
16 changes: 11 additions & 5 deletions libraries/chain/include/eosio/chain/global_property_object.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <eosio/chain/chain_config.hpp>
#include <eosio/chain/chain_snapshot.hpp>
#include <eosio/chain/kv_config.hpp>
#include <eosio/chain/wasm_config.hpp>
#include <eosio/chain/producer_schedule.hpp>
#include <eosio/chain/incremental_merkle.hpp>
#include <eosio/chain/snapshot.hpp>
Expand Down Expand Up @@ -58,21 +59,24 @@ namespace eosio { namespace chain {
chain_config configuration;
chain_id_type chain_id;
kv_config kv_configuration;
wasm_config wasm_configuration;

void initalize_from( const legacy::snapshot_global_property_object_v2& legacy, const chain_id_type& chain_id_val, const kv_config& kv_config_val ) {
void initalize_from( const legacy::snapshot_global_property_object_v2& legacy, const chain_id_type& chain_id_val, const kv_config& kv_config_val, const wasm_config& wasm_config_val ) {
proposed_schedule_block_num = legacy.proposed_schedule_block_num;
proposed_schedule = producer_authority_schedule(legacy.proposed_schedule).to_shared(proposed_schedule.producers.get_allocator());
configuration = legacy.configuration;
chain_id = chain_id_val;
kv_configuration = kv_config_val;
wasm_configuration = wasm_config_val;
}

void initalize_from( const legacy::snapshot_global_property_object_v3& legacy, const kv_config& kv_config_val ) {
void initalize_from( const legacy::snapshot_global_property_object_v3& legacy, const kv_config& kv_config_val, const wasm_config& wasm_config_val ) {
proposed_schedule_block_num = legacy.proposed_schedule_block_num;
proposed_schedule = legacy.proposed_schedule.to_shared(proposed_schedule.producers.get_allocator());
configuration = legacy.configuration;
chain_id = legacy.chain_id;
kv_configuration = kv_config_val;
wasm_configuration = wasm_config_val;
}
};

Expand All @@ -92,6 +96,7 @@ namespace eosio { namespace chain {
chain_config configuration;
chain_id_type chain_id;
kv_config kv_configuration;
wasm_config wasm_configuration;
};

namespace detail {
Expand All @@ -101,7 +106,7 @@ namespace eosio { namespace chain {
using snapshot_type = snapshot_global_property_object;

static snapshot_global_property_object to_snapshot_row( const global_property_object& value, const chainbase::database& ) {
return {value.proposed_schedule_block_num, producer_authority_schedule::from_shared(value.proposed_schedule), value.configuration, value.chain_id, value.kv_configuration};
return {value.proposed_schedule_block_num, producer_authority_schedule::from_shared(value.proposed_schedule), value.configuration, value.chain_id, value.kv_configuration, value.wasm_configuration};
}

static void from_snapshot_row( snapshot_global_property_object&& row, global_property_object& value, chainbase::database& ) {
Expand All @@ -110,6 +115,7 @@ namespace eosio { namespace chain {
value.configuration = row.configuration;
value.chain_id = row.chain_id;
value.kv_configuration = row.kv_configuration;
value.wasm_configuration = row.wasm_configuration;
}
};
}
Expand Down Expand Up @@ -144,7 +150,7 @@ CHAINBASE_SET_INDEX_TYPE(eosio::chain::dynamic_global_property_object,
eosio::chain::dynamic_global_property_multi_index)

FC_REFLECT(eosio::chain::global_property_object,
(proposed_schedule_block_num)(proposed_schedule)(configuration)(chain_id)(kv_configuration)
(proposed_schedule_block_num)(proposed_schedule)(configuration)(chain_id)(kv_configuration)(wasm_configuration)
)

FC_REFLECT(eosio::chain::legacy::snapshot_global_property_object_v2,
Expand All @@ -156,7 +162,7 @@ FC_REFLECT(eosio::chain::legacy::snapshot_global_property_object_v3,
)

FC_REFLECT(eosio::chain::snapshot_global_property_object,
(proposed_schedule_block_num)(proposed_schedule)(configuration)(chain_id)(kv_configuration)
(proposed_schedule_block_num)(proposed_schedule)(configuration)(chain_id)(kv_configuration)(wasm_configuration)
)

FC_REFLECT(eosio::chain::dynamic_global_property_object,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ enum class builtin_protocol_feature_t : uint32_t {
wtmsig_block_signatures,
action_return_value,
kv_database,
configurable_wasm_limits,
};

struct protocol_feature_subjective_restrictions {
Expand Down
55 changes: 55 additions & 0 deletions libraries/chain/include/eosio/chain/wasm_config.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#pragma once

#include <eosio/chain/wasm_eosio_constraints.hpp>
#include <cstdint>
#include <fc/reflect/reflect.hpp>

namespace eosio { namespace chain {

struct wasm_config {
std::uint32_t max_mutable_global_bytes;
std::uint32_t max_table_elements;
std::uint32_t max_section_elements;
std::uint32_t max_linear_memory_init;
std::uint32_t max_func_local_bytes;
std::uint32_t max_nested_structures;
std::uint32_t max_symbol_bytes;
std::uint32_t max_module_bytes;
std::uint32_t max_code_bytes;
std::uint32_t max_pages;
std::uint32_t max_call_depth;
void validate() const;
};

inline constexpr bool operator==(const wasm_config& lhs, const wasm_config& rhs) {
return lhs.max_mutable_global_bytes == rhs.max_mutable_global_bytes &&
lhs.max_table_elements == rhs.max_table_elements &&
lhs.max_section_elements == rhs.max_section_elements &&
lhs.max_linear_memory_init == rhs.max_linear_memory_init &&
lhs.max_func_local_bytes == rhs.max_func_local_bytes &&
lhs.max_nested_structures == rhs.max_nested_structures &&
lhs.max_symbol_bytes == rhs.max_symbol_bytes &&
lhs.max_module_bytes == rhs.max_module_bytes &&
lhs.max_code_bytes == rhs.max_code_bytes &&
lhs.max_pages == rhs.max_pages &&
lhs.max_call_depth == rhs.max_call_depth;
}
inline constexpr bool operator!=(const wasm_config& lhs, const wasm_config& rhs) {
return !(lhs == rhs);
}

}}

FC_REFLECT(eosio::chain::wasm_config,
(max_mutable_global_bytes)
(max_table_elements)
(max_section_elements)
(max_linear_memory_init)
(max_func_local_bytes)
(max_nested_structures)
(max_symbol_bytes)
(max_module_bytes)
(max_code_bytes)
(max_pages)
(max_call_depth)
)
24 changes: 6 additions & 18 deletions libraries/chain/include/eosio/chain/wasm_eosio_injection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,6 @@ namespace eosio { namespace chain { namespace wasm_injections {
static void initializer();
};

struct max_memory_injection_visitor {
static void inject( IR::Module& m );
static void initializer();
};

struct blacklist_injection_visitor {
static void inject( IR::Module& m );
static void initializer();
Expand Down Expand Up @@ -271,16 +266,11 @@ namespace eosio { namespace chain { namespace wasm_injections {
static constexpr bool kills = true;
static constexpr bool post = false;
static int32_t global_idx;
static void init() {
global_idx = -1;
static void init( Module& mod) {
mod.globals.defs.push_back({{ValueType::i32, true}, {(I32)eosio::chain::wasm_constraints::maximum_call_depth}});
global_idx = mod.globals.size()-1;
}
static void accept( wasm_ops::instr* inst, wasm_ops::visitor_arg& arg ) {
if ( global_idx == -1 ) {
arg.module->globals.defs.push_back({{ValueType::i32, true}, {(I32) eosio::chain::wasm_constraints::maximum_call_depth}});
}

global_idx = arg.module->globals.size()-1;

int32_t assert_idx;
injector_utils::add_import<ResultType::none>(*(arg.module), "call_depth_assert", assert_idx);

Expand Down Expand Up @@ -782,19 +772,18 @@ namespace eosio { namespace chain { namespace wasm_injections {
// Otherwise you'll just get softfloat injection
template<bool full_injection>
class wasm_binary_injection {
using standard_module_injectors = module_injectors< max_memory_injection_visitor >;

public:
wasm_binary_injection( IR::Module& mod ) : _module( &mod ) {
_module_injectors.init();
// initialize static fields of injectors
injector_utils::init( mod );
checktime_injection::init();
call_depth_check_and_insert_checktime::init();
if constexpr (full_injection) {
call_depth_check_and_insert_checktime::init( mod );
}
}

void inject() {
_module_injectors.inject( *_module );
// inject checktime first
if constexpr (full_injection)
injector_utils::add_import<ResultType::none>( *_module, u8"checktime", checktime_injection::chktm_idx );
Expand Down Expand Up @@ -844,7 +833,6 @@ namespace eosio { namespace chain { namespace wasm_injections {
}
private:
IR::Module* _module;
standard_module_injectors _module_injectors;
};

}}} // namespace wasm_constraints, chain, eosio
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <eosio/chain/wasm_eosio_injection.hpp>
#include <eosio/chain/transaction_context.hpp>
#include <eosio/chain/code_object.hpp>
#include <eosio/chain/global_property_object.hpp>
#include <eosio/chain/exceptions.hpp>
#include <fc/scoped_exit.hpp>

Expand Down Expand Up @@ -48,7 +49,10 @@ namespace eosio { namespace chain {

#ifdef EOSIO_EOS_VM_OC_RUNTIME_ENABLED
struct eosvmoc_tier {
eosvmoc_tier(const boost::filesystem::path& d, const eosvmoc::config& c, const chainbase::database& db) : cc(d, c, db), exec(cc) {}
eosvmoc_tier(const boost::filesystem::path& d, const eosvmoc::config& c, const chainbase::database& db)
: cc(d, c, db), exec(cc),
// Can't get max_pages from db, because db hasn't been initialized yet.
mem(0) {}
eosvmoc::code_cache_async cc;
eosvmoc::executor exec;
eosvmoc::memory mem;
Expand Down Expand Up @@ -158,6 +162,7 @@ namespace eosio { namespace chain {
try {
Serialization::MemoryInputStream stream((const U8*)bytes.data(),
bytes.size());
WASM::scoped_skip_checks no_check;
WASM::serialize(stream, module);
module.userSections.clear();
} catch (const Serialization::FatalSerializationException& e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,6 @@ struct eos_vm_oc_control_block {
uintptr_t running_code_base;
int64_t first_invalid_memory_address;
unsigned is_running;
};
int64_t max_linear_memory_pages;
void* globals;
};
Loading

0 comments on commit c356876

Please sign in to comment.