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

Make wasm constraints configurable #8360

Merged
merged 39 commits into from
Apr 27, 2020
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
44ede56
add configurable wasm limits. Not yet fully tested. Broken with OC.
swatanabe-b1 Dec 19, 2019
981d87d
Move the wasm table into the code segment to bypass the hard-coded li…
swatanabe-b1 Dec 19, 2019
d383323
Add tests for max_mutable_global_bytes.
swatanabe-b1 Dec 19, 2019
a76b244
Add tests for max_section_elements and skip all the checks in wasm-ji…
swatanabe-b1 Dec 19, 2019
ff92bde
Add tests for max_linear_memory_init
swatanabe-b1 Dec 19, 2019
b9f5940
Add tests for max_nested_structures.
swatanabe-b1 Dec 19, 2019
b1d6676
Add tests for max_symbol_bytes
swatanabe-b1 Dec 30, 2019
ae50807
Add tests for max_module_bytes and max_code_bytes.
swatanabe-b1 Dec 30, 2019
52a65fd
Update eos-vm
swatanabe-b1 Dec 30, 2019
ae1edd2
Merge remote-tracking branch 'origin/kv-database' into wasm-config
swatanabe-b1 Mar 24, 2020
a866971
Fix errors from merging
swatanabe-b1 Mar 24, 2020
12f266a
Allow eos-vm-oc to switch to another stack if the maximum call depth …
swatanabe-b1 Mar 25, 2020
77b93d8
Avoid changing the layout of the control block.
swatanabe-b1 Mar 27, 2020
fcdee65
OC: Allow the highest segment of linear memory to be resized using mp…
swatanabe-b1 Mar 27, 2020
77940e6
merged kv-database
Apr 20, 2020
de49f74
fix conflicts with develop
Apr 20, 2020
609d56f
fix conflicts
Apr 20, 2020
833ed82
update wasm spec test submod
Apr 21, 2020
0bb92d5
update snapshot reference
Apr 22, 2020
f51b0aa
merge kv-database and fix conflicts
Apr 23, 2020
5b12412
forgot eos-vm.cpp
Apr 23, 2020
0028ad6
some more overlooked artifacts
Apr 23, 2020
8a142dd
remove extra validate
Apr 23, 2020
1e0ce4b
my goof
Apr 23, 2020
9265ff0
fixed tests
Apr 24, 2020
3c4a40f
merge kv-database
Apr 24, 2020
fd4090c
add back missing host functions
Apr 24, 2020
5dc127c
Enforce minimum values on some wasm_configuration parameters, suffici…
swatanabe-b1 Apr 24, 2020
09b73bd
Update fc.
swatanabe-b1 Apr 24, 2020
85a0daf
Fix typos in description of protocol feature and update digest to match.
swatanabe-b1 Apr 24, 2020
3b1ee9f
Revert changes to validate_intrinsics and update the wasm_config vers…
swatanabe-b1 Apr 24, 2020
a4019e7
Remove wasm_config parameter from instantiate_module.
swatanabe-b1 Apr 24, 2020
5453e49
Add version to set/get_wasm_parameters packed.
swatanabe-b1 Apr 24, 2020
9307697
Move all eos-vm-oc source files into runtimes/ and fix paths in CMake.
swatanabe-b1 Apr 27, 2020
cf63148
Remove forward declaration that is no longer needed.
swatanabe-b1 Apr 27, 2020
5e14a2c
Add a couple of warnings for issues that are inconvenient to fix righ…
swatanabe-b1 Apr 27, 2020
5394a1d
update eos-vm
swatanabe-b1 Apr 27, 2020
937c3d1
Merge branch 'develop' into wasm-config
arhag Apr 27, 2020
5d06cfc
Merge branch 'develop' into wasm-config
arhag Apr 27, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 17 additions & 12 deletions libraries/chain/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,22 @@ else()
endif()

if("eos-vm-oc" IN_LIST EOSIO_WASM_RUNTIMES)
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
webassembly/runtimes/eos-vm-oc/intrinsic.cpp
webassembly/runtimes/eos-vm-oc/LLVMJIT.cpp
webassembly/runtimes/eos-vm-oc/LLVMEmitIR.cpp
webassembly/runtimes/eos-vm-oc/compile_monitor.cpp
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.cpp
webassembly/runtimes/eos-vm-oc/default_real_main.cpp)
enable_language(ASM)
set(CHAIN_EOSVMOC_SOURCES webassembly/eos-vm-oc/code_cache.cpp
arhag marked this conversation as resolved.
Show resolved Hide resolved
webassembly/eos-vm-oc/executor.cpp
webassembly/eos-vm-oc/memory.cpp
webassembly/eos-vm-oc/intrinsic.cpp
webassembly/eos-vm-oc/LLVMJIT.cpp
webassembly/eos-vm-oc/LLVMEmitIR.cpp
webassembly/eos-vm-oc/compile_monitor.cpp
webassembly/eos-vm-oc/compile_trampoline.cpp
webassembly/eos-vm-oc/ipc_helpers.cpp
webassembly/eos-vm-oc/gs_seg_helpers.c
webassembly/eos-vm-oc/stack.cpp
webassembly/eos-vm-oc/switch_stack_linux.s
webassembly/eos-vm-oc.cpp
webassembly/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)
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
Loading