提交 76a413d9 编写于 作者: A Anton Perkov

Merge branch 'master' into identity-contract-new-style

...@@ -32,6 +32,9 @@ typedef uint64_t asset_symbol; ...@@ -32,6 +32,9 @@ typedef uint64_t asset_symbol;
typedef int64_t share_type; typedef int64_t share_type;
typedef uint16_t weight_type; typedef uint16_t weight_type;
/* macro to align/overalign a type to ensure calls to intrinsics with pointers/references are properly aligned */
#define ALIGNED(X) __attribute__ ((aligned (16))) X
struct public_key { struct public_key {
char data[34]; char data[34];
}; };
...@@ -40,15 +43,15 @@ struct signature { ...@@ -40,15 +43,15 @@ struct signature {
uint8_t data[66]; uint8_t data[66];
}; };
struct checksum256 { struct ALIGNED(checksum256) {
uint8_t hash[32]; uint8_t hash[32];
}; };
struct checksum160 { struct ALIGNED(checksum160) {
uint8_t hash[20]; uint8_t hash[20];
}; };
struct checksum512 { struct ALIGNED(checksum512) {
uint8_t hash[64]; uint8_t hash[64];
}; };
......
...@@ -12,8 +12,8 @@ ...@@ -12,8 +12,8 @@
#include <eosiolib/datastream.hpp> #include <eosiolib/datastream.hpp>
#include <eosiolib/print.hpp> #include <eosiolib/print.hpp>
#include <eosiolib/compiler_builtins.h> #include <eosiolib/compiler_builtins.h>
#include "test_api.hpp" #include "test_api.hpp"
void test_action::read_action_normal() { void test_action::read_action_normal() {
char buffer[100]; char buffer[100];
......
...@@ -41,9 +41,9 @@ struct impl { ...@@ -41,9 +41,9 @@ struct impl {
(current_game.board[1] == current_game.board[4] && current_game.board[4] == current_game.board[7]) || (current_game.board[1] == current_game.board[4] && current_game.board[4] == current_game.board[7]) ||
(current_game.board[2] == current_game.board[4] && current_game.board[4] == current_game.board[6]) || (current_game.board[2] == current_game.board[4] && current_game.board[4] == current_game.board[6]) ||
(current_game.board[3] == current_game.board[4] && current_game.board[4] == current_game.board[5])) { (current_game.board[3] == current_game.board[4] && current_game.board[4] == current_game.board[5])) {
// - | - | x x | - | - - | - | - - | x | - // x | - | - - | x | - - | - | x - | - | -
// - | x | - - | x | - x | x | x - | x | - // - | x | - - | x | - - | x | - x | x | x
// x | - | - - | - | x - | - | - - | x | - // - | - | x - | x | - x | - | - - | - | -
if (current_game.board[4] == 1) { if (current_game.board[4] == 1) {
return current_game.host; return current_game.host;
} else if (current_game.board[4] == 2) { } else if (current_game.board[4] == 2) {
...@@ -61,9 +61,9 @@ struct impl { ...@@ -61,9 +61,9 @@ struct impl {
} }
} else if ((current_game.board[2] == current_game.board[5] && current_game.board[5] == current_game.board[8]) || } else if ((current_game.board[2] == current_game.board[5] && current_game.board[5] == current_game.board[8]) ||
(current_game.board[6] == current_game.board[7] && current_game.board[7] == current_game.board[8])) { (current_game.board[6] == current_game.board[7] && current_game.board[7] == current_game.board[8])) {
// - | - | - - | - | x // - | - | x - | - | -
// - | - | - - | - | x // - | - | x - | - | -
// x | x | x - | - | x // - | - | x x | x | x
if (current_game.board[8] == 1) { if (current_game.board[8] == 1) {
return current_game.host; return current_game.host;
} else if (current_game.board[8] == 2) { } else if (current_game.board[8] == 2) {
......
...@@ -311,6 +311,11 @@ void apply_context::cancel_deferred( const uint128_t& sender_id ) { ...@@ -311,6 +311,11 @@ void apply_context::cancel_deferred( const uint128_t& sender_id ) {
results.deferred_transaction_requests.push_back(deferred_reference(receiver, sender_id)); results.deferred_transaction_requests.push_back(deferred_reference(receiver, sender_id));
} }
void apply_context::add_cpu_usage( const uint64_t usage ) {
// TODO for now just increase the usage, in the future check against some limit
_cpu_usage += usage;
}
const contracts::table_id_object* apply_context::find_table( name code, name scope, name table ) { const contracts::table_id_object* apply_context::find_table( name code, name scope, name table ) {
require_read_lock(code, scope); require_read_lock(code, scope);
return db.find<table_id_object, contracts::by_code_scope_table>(boost::make_tuple(code, scope, table)); return db.find<table_id_object, contracts::by_code_scope_table>(boost::make_tuple(code, scope, table));
......
...@@ -587,6 +587,8 @@ class apply_context { ...@@ -587,6 +587,8 @@ class apply_context {
generic_index<contracts::index_long_double_object> idx_long_double; generic_index<contracts::index_long_double_object> idx_long_double;
uint32_t recurse_depth; // how deep inline actions can recurse uint32_t recurse_depth; // how deep inline actions can recurse
void add_cpu_usage( const uint64_t usage );
private: private:
iterator_cache<key_value_object> keyval_cache; iterator_cache<key_value_object> keyval_cache;
......
...@@ -15,7 +15,7 @@ typedef __uint128_t uint128_t; ...@@ -15,7 +15,7 @@ typedef __uint128_t uint128_t;
const static auto default_block_log_dir = "block_log"; const static auto default_block_log_dir = "block_log";
const static auto default_shared_memory_dir = "shared_mem"; const static auto default_shared_memory_dir = "shared_mem";
const static auto default_shared_memory_size = 1024*1024*1024ll; const static auto default_shared_memory_size = 32*1024*1024*1024ll;
const static uint64_t system_account_name = N(eosio); const static uint64_t system_account_name = N(eosio);
const static uint64_t nobody_account_name = N(nobody); const static uint64_t nobody_account_name = N(nobody);
......
...@@ -100,6 +100,7 @@ namespace eosio { namespace chain { ...@@ -100,6 +100,7 @@ namespace eosio { namespace chain {
FC_DECLARE_DERIVED_EXCEPTION( wallet_locked_exception, eosio::chain::wallet_exception, 3140003, "Locked wallet" ) FC_DECLARE_DERIVED_EXCEPTION( wallet_locked_exception, eosio::chain::wallet_exception, 3140003, "Locked wallet" )
FC_DECLARE_DERIVED_EXCEPTION( wallet_missing_pub_key_exception, eosio::chain::wallet_exception, 3140004, "Missing public key" ) FC_DECLARE_DERIVED_EXCEPTION( wallet_missing_pub_key_exception, eosio::chain::wallet_exception, 3140004, "Missing public key" )
FC_DECLARE_DERIVED_EXCEPTION( wallet_invalid_password_exception, eosio::chain::wallet_exception, 3140005, "Invalid wallet password" ) FC_DECLARE_DERIVED_EXCEPTION( wallet_invalid_password_exception, eosio::chain::wallet_exception, 3140005, "Invalid wallet password" )
FC_DECLARE_DERIVED_EXCEPTION( wallet_not_available_exception, eosio::chain::wallet_exception, 3140006, "No available wallet" )
FC_DECLARE_DERIVED_EXCEPTION( rate_limiting_state_inconsistent, eosio::chain::rate_limiting_invariant_exception, 3150001, "internal state is no longer consistent" ) FC_DECLARE_DERIVED_EXCEPTION( rate_limiting_state_inconsistent, eosio::chain::rate_limiting_invariant_exception, 3150001, "internal state is no longer consistent" )
FC_DECLARE_DERIVED_EXCEPTION( rate_limiting_overcommitment, eosio::chain::rate_limiting_invariant_exception, 3150002, "chain resource limits are overcommitted" ) FC_DECLARE_DERIVED_EXCEPTION( rate_limiting_overcommitment, eosio::chain::rate_limiting_invariant_exception, 3150002, "chain resource limits are overcommitted" )
......
...@@ -57,8 +57,7 @@ namespace eosio { namespace chain { namespace wasm_injections { ...@@ -57,8 +57,7 @@ namespace eosio { namespace chain { namespace wasm_injections {
if ( exp.kind == IR::ObjectKind::function ) if ( exp.kind == IR::ObjectKind::function )
exports++; exports++;
next_function_index = module.functions.imports.size() + module.functions.defs.size() + registered_injected.size(); // + exports + registered_injected.size()-1; next_function_index = module.functions.imports.size() + module.functions.defs.size() + registered_injected.size();
;
next_actual_index = next_injected_index++; next_actual_index = next_injected_index++;
} }
...@@ -75,10 +74,18 @@ namespace eosio { namespace chain { namespace wasm_injections { ...@@ -75,10 +74,18 @@ namespace eosio { namespace chain { namespace wasm_injections {
module.functions.imports.insert( module.functions.imports.begin()+(registered_injected.size()-1), new_import.begin(), new_import.end() ); module.functions.imports.insert( module.functions.imports.begin()+(registered_injected.size()-1), new_import.begin(), new_import.end() );
injected_index_mapping.emplace( index, actual_index ); injected_index_mapping.emplace( index, actual_index );
// shift all exported functions by 1 // shift all exported functions by 1
bool have_updated_start = false;
for ( int i=0; i < module.exports.size(); i++ ) { for ( int i=0; i < module.exports.size(); i++ ) {
if ( module.exports[i].kind == IR::ObjectKind::function ) if ( module.exports[i].kind == IR::ObjectKind::function ) {
// update the start function
if ( !have_updated_start && module.exports[i].index == module.startFunctionIndex ) {
module.startFunctionIndex++;
have_updated_start = true;
}
module.exports[i].index++; module.exports[i].index++;
}
} }
// shift all table entries for call indirect // shift all table entries for call indirect
for(TableSegment& ts : module.tableSegments) { for(TableSegment& ts : module.tableSegments) {
for(auto& idx : ts.indices) for(auto& idx : ts.indices)
...@@ -90,7 +97,7 @@ namespace eosio { namespace chain { namespace wasm_injections { ...@@ -90,7 +97,7 @@ namespace eosio { namespace chain { namespace wasm_injections {
} }
} }
}; };
struct noop_injection_visitor { struct noop_injection_visitor {
static void inject( IR::Module& m ); static void inject( IR::Module& m );
static void initializer(); static void initializer();
...@@ -189,6 +196,7 @@ namespace eosio { namespace chain { namespace wasm_injections { ...@@ -189,6 +196,7 @@ namespace eosio { namespace chain { namespace wasm_injections {
static void accept( wasm_ops::instr* inst, wasm_ops::visitor_arg& arg ) { static void accept( wasm_ops::instr* inst, wasm_ops::visitor_arg& arg ) {
wasm_ops::op_types<>::call_t* call_inst = reinterpret_cast<wasm_ops::op_types<>::call_t*>(inst); wasm_ops::op_types<>::call_t* call_inst = reinterpret_cast<wasm_ops::op_types<>::call_t*>(inst);
auto mapped_index = injector_utils::injected_index_mapping.find(call_inst->field); auto mapped_index = injector_utils::injected_index_mapping.find(call_inst->field);
if ( mapped_index != injector_utils::injected_index_mapping.end() ) { if ( mapped_index != injector_utils::injected_index_mapping.end() ) {
call_inst->field = mapped_index->second; call_inst->field = mapped_index->second;
} }
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include <eosio/chain/webassembly/common.hpp> #include <eosio/chain/webassembly/common.hpp>
#include <eosio/chain/webassembly/runtime_interface.hpp> #include <eosio/chain/webassembly/runtime_interface.hpp>
#include <eosio/chain/exceptions.hpp> #include <eosio/chain/exceptions.hpp>
#include <eosio/chain/apply_context.hpp>
#include <wasm-interpreter.h> #include <wasm-interpreter.h>
#include <softfloat_types.h> #include <softfloat_types.h>
...@@ -196,18 +197,6 @@ constexpr bool is_reference_from_value_v = is_reference_from_value<T>::value; ...@@ -196,18 +197,6 @@ constexpr bool is_reference_from_value_v = is_reference_from_value<T>::value;
template<typename T> template<typename T>
T convert_literal_to_native(Literal& v); T convert_literal_to_native(Literal& v);
template<>
inline float64_t convert_literal_to_native<float64_t>(Literal& v) {
auto val = v.getf64();
return reinterpret_cast<float64_t&>(val);
}
template<>
inline float32_t convert_literal_to_native<float32_t>(Literal& v) {
auto val = v.getf32();
return reinterpret_cast<float32_t&>(val);
}
template<> template<>
inline double convert_literal_to_native<double>(Literal& v) { inline double convert_literal_to_native<double>(Literal& v) {
return v.getf64(); return v.getf64();
...@@ -254,15 +243,6 @@ inline auto convert_native_to_literal(const interpreter_interface*, T val) { ...@@ -254,15 +243,6 @@ inline auto convert_native_to_literal(const interpreter_interface*, T val) {
return Literal(val); return Literal(val);
} }
inline auto convert_native_to_literal(const interpreter_interface*, const float64_t& val) {
return Literal( *((double*)(&val)) );
}
inline auto convert_native_to_literal(const interpreter_interface*, const float32_t& val) {
return Literal( *((float*)(&val)) );
}
inline auto convert_native_to_literal(const interpreter_interface*, const name &val) { inline auto convert_native_to_literal(const interpreter_interface*, const name &val) {
return Literal(val.value); return Literal(val.value);
} }
...@@ -472,10 +452,32 @@ struct intrinsic_invoker_impl<Ret, std::tuple<T *, Inputs...>> { ...@@ -472,10 +452,32 @@ struct intrinsic_invoker_impl<Ret, std::tuple<T *, Inputs...>> {
using next_step = intrinsic_invoker_impl<Ret, std::tuple<Inputs...>>; using next_step = intrinsic_invoker_impl<Ret, std::tuple<Inputs...>>;
using then_type = Ret (*)(interpreter_interface*, T *, Inputs..., LiteralList&, int); using then_type = Ret (*)(interpreter_interface*, T *, Inputs..., LiteralList&, int);
template<then_type Then> template<then_type Then, typename U=T>
static Ret translate_one(interpreter_interface* interface, Inputs... rest, LiteralList& args, int offset) { static auto translate_one(interpreter_interface* interface, Inputs... rest, LiteralList& args, int offset) -> std::enable_if_t<std::is_const<U>::value, Ret> {
uint32_t ptr = args.at(offset).geti32();
T* base = array_ptr_impl<T>(interface, ptr, 1);
if ( reinterpret_cast<uintptr_t>(base) % alignof(T) != 0 ) {
wlog( "misaligned const pointer" );
std::remove_const_t<T> copy;
T* copy_ptr = &copy;
memcpy( (void*)copy_ptr, (void*)base, sizeof(T) );
return Then(interface, copy_ptr, rest..., args, offset - 1);
}
return Then(interface, base, rest..., args, offset - 1);
};
template<then_type Then, typename U=T>
static auto translate_one(interpreter_interface* interface, Inputs... rest, LiteralList& args, int offset) -> std::enable_if_t<!std::is_const<U>::value, Ret> {
uint32_t ptr = args.at(offset).geti32(); uint32_t ptr = args.at(offset).geti32();
T* base = array_ptr_impl<T>(interface, ptr, 1); T* base = array_ptr_impl<T>(interface, ptr, 1);
if ( reinterpret_cast<uintptr_t>(base) % alignof(T) != 0 ) {
wlog( "misaligned pointer" );
T copy;
memcpy( (void*)&copy, (void*)base, sizeof(T) );
Ret ret = Then(interface, &copy, rest..., args, offset - 1);
memcpy( (void*)base, (void*)&copy, sizeof(T) );
return ret;
}
return Then(interface, base, rest..., args, offset - 1); return Then(interface, base, rest..., args, offset - 1);
}; };
...@@ -551,15 +553,40 @@ struct intrinsic_invoker_impl<Ret, std::tuple<T &, Inputs...>> { ...@@ -551,15 +553,40 @@ struct intrinsic_invoker_impl<Ret, std::tuple<T &, Inputs...>> {
using next_step = intrinsic_invoker_impl<Ret, std::tuple<Inputs...>>; using next_step = intrinsic_invoker_impl<Ret, std::tuple<Inputs...>>;
using then_type = Ret (*)(interpreter_interface*, T &, Inputs..., LiteralList&, int); using then_type = Ret (*)(interpreter_interface*, T &, Inputs..., LiteralList&, int);
template<then_type Then> template<then_type Then, typename U=T>
static Ret translate_one(interpreter_interface* interface, Inputs... rest, LiteralList& args, int offset) { static auto translate_one(interpreter_interface* interface, Inputs... rest, LiteralList& args, int offset) -> std::enable_if_t<std::is_const<U>::value, Ret> {
// references cannot be created for null pointers
uint32_t ptr = args.at(offset).geti32();
FC_ASSERT(ptr != 0);
T* base = array_ptr_impl<T>(interface, ptr, 1);
if ( reinterpret_cast<uintptr_t>(base) % alignof(T) != 0 ) {
wlog( "misaligned const reference" );
std::remove_const_t<T> copy;
T* copy_ptr = &copy;
memcpy( (void*)copy_ptr, (void*)base, sizeof(T) );
return Then(interface, *copy_ptr, rest..., args, offset - 1);
}
return Then(interface, *base, rest..., args, offset - 1);
}
template<then_type Then, typename U=T>
static auto translate_one(interpreter_interface* interface, Inputs... rest, LiteralList& args, int offset) -> std::enable_if_t<!std::is_const<U>::value, Ret> {
// references cannot be created for null pointers // references cannot be created for null pointers
uint32_t ptr = args.at(offset).geti32(); uint32_t ptr = args.at(offset).geti32();
FC_ASSERT(ptr != 0); FC_ASSERT(ptr != 0);
T* base = array_ptr_impl<T>(interface, ptr, 1); T* base = array_ptr_impl<T>(interface, ptr, 1);
if ( reinterpret_cast<uintptr_t>(base) % alignof(T) != 0 ) {
wlog( "misaligned reference" );
T copy;
memcpy( (void*)&copy, (void*)base, sizeof(T) );
Ret ret = Then(interface, copy, rest..., args, offset - 1);
memcpy( (void*)base, (void*)&copy, sizeof(T) );
return ret;
}
return Then(interface, *base, rest..., args, offset - 1); return Then(interface, *base, rest..., args, offset - 1);
} }
template<then_type Then> template<then_type Then>
static const auto fn() { static const auto fn() {
return next_step::template fn<translate_one<Then>>(); return next_step::template fn<translate_one<Then>>();
......
...@@ -475,9 +475,31 @@ struct intrinsic_invoker_impl<Ret, std::tuple<T *, Inputs...>, std::tuple<Transl ...@@ -475,9 +475,31 @@ struct intrinsic_invoker_impl<Ret, std::tuple<T *, Inputs...>, std::tuple<Transl
using next_step = intrinsic_invoker_impl<Ret, std::tuple<Inputs...>, std::tuple<Translated..., I32>>; using next_step = intrinsic_invoker_impl<Ret, std::tuple<Inputs...>, std::tuple<Translated..., I32>>;
using then_type = Ret (*)(running_instance_context&, T *, Inputs..., Translated...); using then_type = Ret (*)(running_instance_context&, T *, Inputs..., Translated...);
template<then_type Then> template<then_type Then, typename U=T>
static Ret translate_one(running_instance_context& ctx, Inputs... rest, Translated... translated, I32 ptr) { static auto translate_one(running_instance_context& ctx, Inputs... rest, Translated... translated, I32 ptr) -> std::enable_if_t<std::is_const<U>::value, Ret> {
T* base = array_ptr_impl<T>(ctx, ptr, 1); T* base = array_ptr_impl<T>(ctx, ptr, 1);
if ( reinterpret_cast<uintptr_t>(base) % alignof(T) != 0 ) {
wlog( "misaligned const pointer" );
std::remove_const_t<T> copy;
T* copy_ptr = &copy;
memcpy( (void*)copy_ptr, (void*)base, sizeof(T) );
return Then(ctx, copy_ptr, rest..., translated...);
}
return Then(ctx, base, rest..., translated...);
};
template<then_type Then, typename U=T>
static auto translate_one(running_instance_context& ctx, Inputs... rest, Translated... translated, I32 ptr) -> std::enable_if_t<!std::is_const<U>::value, Ret> {
T* base = array_ptr_impl<T>(ctx, ptr, 1);
if ( reinterpret_cast<uintptr_t>(base) % alignof(T) != 0 ) {
wlog( "misaligned pointer" );
std::remove_const_t<T> copy;
T* copy_ptr = &copy;
memcpy( (void*)copy_ptr, (void*)base, sizeof(T) );
Ret ret = Then(ctx, copy_ptr, rest..., translated...);
memcpy( (void*)base, (void*)copy_ptr, sizeof(T) );
return ret;
}
return Then(ctx, base, rest..., translated...); return Then(ctx, base, rest..., translated...);
}; };
...@@ -539,7 +561,6 @@ struct intrinsic_invoker_impl<Ret, std::tuple<const fc::time_point_sec&, Inputs. ...@@ -539,7 +561,6 @@ struct intrinsic_invoker_impl<Ret, std::tuple<const fc::time_point_sec&, Inputs.
} }
}; };
/** /**
* Specialization for transcribing a reference type in the native method signature * Specialization for transcribing a reference type in the native method signature
* This type transcribes into an int32 pointer checks the validity of that memory * This type transcribes into an int32 pointer checks the validity of that memory
...@@ -554,14 +575,41 @@ struct intrinsic_invoker_impl<Ret, std::tuple<T &, Inputs...>, std::tuple<Transl ...@@ -554,14 +575,41 @@ struct intrinsic_invoker_impl<Ret, std::tuple<T &, Inputs...>, std::tuple<Transl
using next_step = intrinsic_invoker_impl<Ret, std::tuple<Inputs...>, std::tuple<Translated..., I32>>; using next_step = intrinsic_invoker_impl<Ret, std::tuple<Inputs...>, std::tuple<Translated..., I32>>;
using then_type = Ret (*)(running_instance_context &, T &, Inputs..., Translated...); using then_type = Ret (*)(running_instance_context &, T &, Inputs..., Translated...);
template<then_type Then> template<then_type Then, typename U=T>
static Ret translate_one(running_instance_context& ctx, Inputs... rest, Translated... translated, I32 ptr) { static auto translate_one(running_instance_context& ctx, Inputs... rest, Translated... translated, I32 ptr) -> std::enable_if_t<std::is_const<U>::value, Ret> {
// references cannot be created for null pointers
FC_ASSERT(ptr != 0);
MemoryInstance* mem = ctx.memory;
if(!mem || ptr+sizeof(T) >= IR::numBytesPerPage*Runtime::getMemoryNumPages(mem))
Runtime::causeException(Exception::Cause::accessViolation);
T &base = *(T*)(getMemoryBaseAddress(mem)+ptr);
if ( reinterpret_cast<uintptr_t>(&base) % alignof(T) != 0 ) {
wlog( "misaligned const reference" );
std::remove_const_t<T> copy;
T* copy_ptr = &copy;
memcpy( (void*)copy_ptr, (void*)&base, sizeof(T) );
return Then(ctx, *copy_ptr, rest..., translated...);
}
return Then(ctx, base, rest..., translated...);
}
template<then_type Then, typename U=T>
static auto translate_one(running_instance_context& ctx, Inputs... rest, Translated... translated, I32 ptr) -> std::enable_if_t<!std::is_const<U>::value, Ret> {
// references cannot be created for null pointers // references cannot be created for null pointers
FC_ASSERT(ptr != 0); FC_ASSERT(ptr != 0);
MemoryInstance* mem = ctx.memory; MemoryInstance* mem = ctx.memory;
if(!mem || ptr+sizeof(T) >= IR::numBytesPerPage*Runtime::getMemoryNumPages(mem)) if(!mem || ptr+sizeof(T) >= IR::numBytesPerPage*Runtime::getMemoryNumPages(mem))
Runtime::causeException(Exception::Cause::accessViolation); Runtime::causeException(Exception::Cause::accessViolation);
T &base = *(T*)(getMemoryBaseAddress(mem)+ptr); T &base = *(T*)(getMemoryBaseAddress(mem)+ptr);
if ( reinterpret_cast<uintptr_t>(&base) % alignof(T) != 0 ) {
wlog( "misaligned reference" );
std::remove_const_t<T> copy;
T* copy_ptr = &copy;
memcpy( (void*)copy_ptr, (void*)&base, sizeof(T) );
Ret ret = Then(ctx, *copy_ptr, rest..., translated...);
memcpy( (void*)&base, (void*)copy_ptr, sizeof(T) );
return ret;
}
return Then(ctx, base, rest..., translated...); return Then(ctx, base, rest..., translated...);
} }
......
...@@ -686,7 +686,6 @@ class crypto_api : public context_aware_api { ...@@ -686,7 +686,6 @@ class crypto_api : public context_aware_api {
public: public:
explicit crypto_api( apply_context& ctx ) explicit crypto_api( apply_context& ctx )
:context_aware_api(ctx,true){} :context_aware_api(ctx,true){}
/** /**
* This method can be optimized out during replay as it has * This method can be optimized out during replay as it has
* no possible side effects other than "passing". * no possible side effects other than "passing".
...@@ -738,7 +737,6 @@ class crypto_api : public context_aware_api { ...@@ -738,7 +737,6 @@ class crypto_api : public context_aware_api {
FC_ASSERT( result == hash_val, "hash miss match" ); FC_ASSERT( result == hash_val, "hash miss match" );
} }
void sha1(array_ptr<char> data, size_t datalen, fc::sha1& hash_val) { void sha1(array_ptr<char> data, size_t datalen, fc::sha1& hash_val) {
hash_val = fc::sha1::hash( data, datalen ); hash_val = fc::sha1::hash( data, datalen );
} }
......
...@@ -43,7 +43,7 @@ class binaryen_instantiated_module : public wasm_instantiated_module_interface { ...@@ -43,7 +43,7 @@ class binaryen_instantiated_module : public wasm_instantiated_module_interface {
memset(_shared_linear_memory.data, 0, initial_memory_size); memset(_shared_linear_memory.data, 0, initial_memory_size);
//copy back in the initial data //copy back in the initial data
memcpy(_shared_linear_memory.data, _initial_memory.data(), _initial_memory.size()); memcpy(_shared_linear_memory.data, _initial_memory.data(), _initial_memory.size());
//be aware that construction of the ModuleInstance implictly fires the start function //be aware that construction of the ModuleInstance implictly fires the start function
ModuleInstance instance(*_module.get(), &local_interface); ModuleInstance instance(*_module.get(), &local_interface);
instance.callExport(Name(entry_point), args); instance.callExport(Name(entry_point), args);
......
...@@ -40,6 +40,7 @@ public: ...@@ -40,6 +40,7 @@ public:
time_point genesis_timestamp; time_point genesis_timestamp;
uint32_t skip_flags = skip_nothing; uint32_t skip_flags = skip_nothing;
bool readonly = false; bool readonly = false;
uint64_t shared_memory_size;
flat_map<uint32_t,block_id_type> loaded_checkpoints; flat_map<uint32_t,block_id_type> loaded_checkpoints;
fc::optional<fork_database> fork_db; fc::optional<fork_database> fork_db;
...@@ -75,6 +76,8 @@ void chain_plugin::set_program_options(options_description& cli, options_descrip ...@@ -75,6 +76,8 @@ void chain_plugin::set_program_options(options_description& cli, options_descrip
("max-deferred-transaction-time", bpo::value<int32_t>()->default_value(20), ("max-deferred-transaction-time", bpo::value<int32_t>()->default_value(20),
"Limits the maximum time (in milliseconds) that is allowed a to push deferred transactions at the start of a block") "Limits the maximum time (in milliseconds) that is allowed a to push deferred transactions at the start of a block")
("wasm-runtime", bpo::value<eosio::chain::wasm_interface::vm_type>()->value_name("wavm/binaryen"), "Override default WASM runtime") ("wasm-runtime", bpo::value<eosio::chain::wasm_interface::vm_type>()->value_name("wavm/binaryen"), "Override default WASM runtime")
("shared-memory-size-mb", bpo::value<uint64_t>()->default_value(config::default_shared_memory_size / (1024 * 1024)), "Minimum size MB of database shared memory file")
#warning TODO: rate limiting #warning TODO: rate limiting
/*("per-authorized-account-transaction-msg-rate-limit-time-frame-sec", bpo::value<uint32_t>()->default_value(default_per_auth_account_time_frame_seconds), /*("per-authorized-account-transaction-msg-rate-limit-time-frame-sec", bpo::value<uint32_t>()->default_value(default_per_auth_account_time_frame_seconds),
"The time frame, in seconds, that the per-authorized-account-transaction-msg-rate-limit is imposed over.") "The time frame, in seconds, that the per-authorized-account-transaction-msg-rate-limit is imposed over.")
...@@ -128,6 +131,9 @@ void chain_plugin::plugin_initialize(const variables_map& options) { ...@@ -128,6 +131,9 @@ void chain_plugin::plugin_initialize(const variables_map& options) {
else else
my->block_log_dir = bld; my->block_log_dir = bld;
} }
if (options.count("shared-memory-size-mb")) {
my->shared_memory_size = options.at("shared-memory-size-mb").as<uint64_t>() * 1024 * 1024;
}
if (options.at("replay-blockchain").as<bool>()) { if (options.at("replay-blockchain").as<bool>()) {
ilog("Replay requested: wiping database"); ilog("Replay requested: wiping database");
...@@ -182,6 +188,7 @@ void chain_plugin::plugin_startup() ...@@ -182,6 +188,7 @@ void chain_plugin::plugin_startup()
my->chain_config->block_log_dir = my->block_log_dir; my->chain_config->block_log_dir = my->block_log_dir;
my->chain_config->shared_memory_dir = app().data_dir() / default_shared_memory_dir; my->chain_config->shared_memory_dir = app().data_dir() / default_shared_memory_dir;
my->chain_config->read_only = my->readonly; my->chain_config->read_only = my->readonly;
my->chain_config->shared_memory_size = my->shared_memory_size;
my->chain_config->genesis = fc::json::from_file(my->genesis_file).as<contracts::genesis_state_type>(); my->chain_config->genesis = fc::json::from_file(my->genesis_file).as<contracts::genesis_state_type>();
if (my->genesis_timestamp.sec_since_epoch() > 0) { if (my->genesis_timestamp.sec_since_epoch() > 0) {
my->chain_config->genesis.initial_timestamp = my->genesis_timestamp; my->chain_config->genesis.initial_timestamp = my->genesis_timestamp;
......
...@@ -15,7 +15,7 @@ namespace eosio { ...@@ -15,7 +15,7 @@ namespace eosio {
typedef std::chrono::system_clock::duration::rep tstamp; typedef std::chrono::system_clock::duration::rep tstamp;
struct handshake_message { struct handshake_message {
int16_t network_version = 0; ///< derived from git commit hash, not sequential uint16_t network_version = 0; ///< incremental value above a computed base
chain_id_type chain_id; ///< used to identify chain chain_id_type chain_id; ///< used to identify chain
fc::sha256 node_id; ///< used to identify peers and prevent self-connect fc::sha256 node_id; ///< used to identify peers and prevent self-connect
chain::public_key_type key; ///< authentication key; may be a producer or peer key, or empty chain::public_key_type key; ///< authentication key; may be a producer or peer key, or empty
......
此差异已折叠。
...@@ -109,7 +109,9 @@ map<public_key_type,private_key_type> wallet_manager::list_keys() { ...@@ -109,7 +109,9 @@ map<public_key_type,private_key_type> wallet_manager::list_keys() {
flat_set<public_key_type> wallet_manager::get_public_keys() { flat_set<public_key_type> wallet_manager::get_public_keys() {
check_timeout(); check_timeout();
EOS_ASSERT(!wallets.empty(), wallet_not_available_exception, "You don't have any wallet!");
flat_set<public_key_type> result; flat_set<public_key_type> result;
bool is_all_wallet_locked = true;
for (const auto& i : wallets) { for (const auto& i : wallets) {
if (!i.second->is_locked()) { if (!i.second->is_locked()) {
const auto& keys = i.second->list_keys(); const auto& keys = i.second->list_keys();
...@@ -117,7 +119,9 @@ flat_set<public_key_type> wallet_manager::get_public_keys() { ...@@ -117,7 +119,9 @@ flat_set<public_key_type> wallet_manager::get_public_keys() {
result.emplace(i.first); result.emplace(i.first);
} }
} }
is_all_wallet_locked &= i.second->is_locked();
} }
EOS_ASSERT(!is_all_wallet_locked, wallet_locked_exception, "You don't have any unlocked wallet!");
return result; return result;
} }
......
...@@ -219,10 +219,11 @@ const char* error_advice_3130003 = "Ensure that you have \033[2meosio::account_ ...@@ -219,10 +219,11 @@ const char* error_advice_3130003 = "Ensure that you have \033[2meosio::account_
const char* error_advice_3130004 = "Ensure that you have \033[2meosio::net_api_plugin\033[0m\033[32m added to your node's configuration!"; const char* error_advice_3130004 = "Ensure that you have \033[2meosio::net_api_plugin\033[0m\033[32m added to your node's configuration!";
const char* error_advice_3140001 = "Try to use different wallet name."; const char* error_advice_3140001 = "Try to use different wallet name.";
const char* error_advice_3140002 = "Are you sure you typed the name correctly?"; const char* error_advice_3140002 = "Are you sure you typed the wallet name correctly?";
const char* error_advice_3140003 = "Ensure that your wallet is unlocked before using it!"; const char* error_advice_3140003 = "Ensure that your wallet is unlocked before using it!";
const char* error_advice_3140004 = "Ensure that you have the relevant private key imported!"; const char* error_advice_3140004 = "Ensure that you have the relevant private key imported!";
const char* error_advice_3140005 = "Are you sure you are using the right password?"; const char* error_advice_3140005 = "Are you sure you are using the right password?";
const char* error_advice_3140006 = "Ensure that you have created a wallet and have it open";
const std::map<int64_t, std::string> error_advice = { const std::map<int64_t, std::string> error_advice = {
...@@ -264,7 +265,8 @@ const std::map<int64_t, std::string> error_advice = { ...@@ -264,7 +265,8 @@ const std::map<int64_t, std::string> error_advice = {
{ 3140002, error_advice_3140002 }, { 3140002, error_advice_3140002 },
{ 3140003, error_advice_3140003 }, { 3140003, error_advice_3140003 },
{ 3140004, error_advice_3140004 }, { 3140004, error_advice_3140004 },
{ 3140005, error_advice_3140005 } { 3140005, error_advice_3140005 },
{ 3140006, error_advice_3140006 }
}; };
......
...@@ -124,7 +124,7 @@ ...@@ -124,7 +124,7 @@
printf "\n\tYUM repository successfully updated.\n" printf "\n\tYUM repository successfully updated.\n"
DEP_ARRAY=( git autoconf automake libtool ocaml.x86_64 doxygen libicu-devel.x86_64 \ DEP_ARRAY=( git autoconf automake libtool ocaml.x86_64 doxygen graphviz-devel.x86_64 libicu-devel.x86_64 \
bzip2-devel.x86_64 openssl-devel.x86_64 gmp-devel.x86_64 python-devel.x86_64 gettext-devel.x86_64) bzip2-devel.x86_64 openssl-devel.x86_64 gmp-devel.x86_64 python-devel.x86_64 gettext-devel.x86_64)
COUNT=1 COUNT=1
DISPLAY="" DISPLAY=""
...@@ -172,6 +172,44 @@ ...@@ -172,6 +172,44 @@
printf "\n\tNo required YUM dependencies to install.\n" printf "\n\tNo required YUM dependencies to install.\n"
fi fi
if [[ $ENABLE_CODE_COVERAGE == true ]]; then
printf "\n\tChecking perl installation."
perl_bin=$( which perl 2>/dev/null )
if [ $? -ne 0 ]; then
printf "\n\tInstalling perl."
yum -y install perl
if [ $? -ne 0 ]; then
printf "\n\tUnable to install perl at this time.\n"
printf "\n\tExiting now.\n"
fi
else
printf "\n\tPerl installation found at ${perl_bin}."
fi
printf "\n\tChecking LCOV installation."
if [ ! -e /usr/local/bin/lcov ]; then
printf "\n\tLCOV installation not found.\n"
printf "\tInstalling LCOV.\n"
cd ${TEMP_DIR}
git clone https://github.com/linux-test-project/lcov.git
if [ $? -ne 0 ]; then
printf "\tUnable to clone LCOV at this time.\n"
printf "\tExiting now.\n\n"
exit;
fi
cd lcov
sudo make install
if [ $? -ne 0 ]; then
printf "\tUnable to install LCOV at this time.\n"
printf "\tExiting now.\n\n"
exit;
fi
rm -rf ${TEMP_DIR}/lcov
printf "\tSuccessfully installed LCOV.\n"
else
printf "\n\tLCOV installation found @ /usr/local/bin/lcov.\n"
fi
fi
printf "\n\tChecking CMAKE installation.\n" printf "\n\tChecking CMAKE installation.\n"
if [ ! -e ${CMAKE} ]; then if [ ! -e ${CMAKE} ]; then
printf "\tInstalling CMAKE\n" printf "\tInstalling CMAKE\n"
......
...@@ -972,7 +972,6 @@ BOOST_FIXTURE_TEST_CASE(multi_index_tests, TESTER) { try { ...@@ -972,7 +972,6 @@ BOOST_FIXTURE_TEST_CASE(multi_index_tests, TESTER) { try {
produce_blocks(1); produce_blocks(1);
set_code( N(testapi), test_api_multi_index_wast ); set_code( N(testapi), test_api_multi_index_wast );
produce_blocks(1); produce_blocks(1);
CALL_TEST_FUNCTION( *this, "test_multi_index", "idx64_general", {}); CALL_TEST_FUNCTION( *this, "test_multi_index", "idx64_general", {});
CALL_TEST_FUNCTION( *this, "test_multi_index", "idx64_store_only", {}); CALL_TEST_FUNCTION( *this, "test_multi_index", "idx64_store_only", {});
CALL_TEST_FUNCTION( *this, "test_multi_index", "idx64_check_without_storing", {}); CALL_TEST_FUNCTION( *this, "test_multi_index", "idx64_check_without_storing", {});
......
...@@ -16,6 +16,146 @@ static const char f32_add_wast[] = R"=====( ...@@ -16,6 +16,146 @@ static const char f32_add_wast[] = R"=====(
) )
)====="; )=====";
*/ */
static const char aligned_ref_wast[] = R"=====(
(module
(import "env" "sha256" (func $sha256 (param i32 i32 i32)))
(table 0 anyfunc)
(memory $0 32)
(data (i32.const 4) "hello")
(export "apply" (func $apply))
(func $apply (param $0 i64) (param $1 i64) (param $2 i64)
(call $sha256
(i32.const 4)
(i32.const 5)
(i32.const 16)
)
)
)
)=====";
static const char aligned_ptr_wast[] = R"=====(
(module
(import "env" "diveq_i128" (func $diveq_i128 (param i32 i32)))
(table 0 anyfunc)
(memory $0 32)
(data (i32.const 16) "random stuff")
(export "apply" (func $apply))
(func $apply (param $0 i64) (param $1 i64) (param $2 i64)
(call $diveq_i128
(i32.const 16)
(i32.const 16)
)
)
)
)=====";
static const char aligned_const_ref_wast[] = R"=====(
(module
(import "env" "sha256" (func $sha256 (param i32 i32 i32)))
(import "env" "assert_sha256" (func $assert_sha256 (param i32 i32 i32)))
(table 0 anyfunc)
(memory $0 32)
(data (i32.const 4) "hello")
(export "apply" (func $apply))
(func $apply (param $0 i64) (param $1 i64) (param $2 i64)
(local $3 i32)
(call $sha256
(i32.const 4)
(i32.const 5)
(i32.const 16)
)
(call $assert_sha256
(i32.const 4)
(i32.const 5)
(i32.const 16)
)
)
)
)=====";
static const char misaligned_ptr_wast[] = R"=====(
(module
(import "env" "diveq_i128" (func $diveq_i128 (param i32 i32)))
(table 0 anyfunc)
(memory $0 32)
(data (i32.const 16) "random stuff")
(export "apply" (func $apply))
(func $apply (param $0 i64) (param $1 i64) (param $2 i64)
(call $diveq_i128
(i32.const 17)
(i32.const 16)
)
)
)
)=====";
static const char misaligned_const_ptr_wast[] = R"=====(
(module
(import "env" "diveq_i128" (func $diveq_i128 (param i32 i32)))
(table 0 anyfunc)
(memory $0 32)
(data (i32.const 16) "random stuff")
(export "apply" (func $apply))
(func $apply (param $0 i64) (param $1 i64) (param $2 i64)
(call $diveq_i128
(i32.const 16)
(i32.const 17)
)
)
)
)=====";
static const char misaligned_ref_wast[] = R"=====(
(module
(import "env" "sha256" (func $sha256 (param i32 i32 i32)))
(table 0 anyfunc)
(memory $0 32)
(data (i32.const 4) "hello")
(export "apply" (func $apply))
(func $apply (param $0 i64) (param $1 i64) (param $2 i64)
(call $sha256
(i32.const 4)
(i32.const 5)
(i32.const 5)
)
)
)
)=====";
static const char misaligned_const_ref_wast[] = R"=====(
(module
(import "env" "sha256" (func $sha256 (param i32 i32 i32)))
(import "env" "assert_sha256" (func $assert_sha256 (param i32 i32 i32)))
(import "env" "memcpy" (func $memcpy (param i32 i32 i32) (result i32)))
(table 0 anyfunc)
(memory $0 32)
(data (i32.const 4) "hello")
(export "apply" (func $apply))
(func $apply (param $0 i64) (param $1 i64) (param $2 i64)
(local $3 i32)
(call $sha256
(i32.const 4)
(i32.const 5)
(i32.const 16)
)
(set_local $3
(call $memcpy
(i32.const 17)
(i32.const 16)
(i32.const 64)
)
)
(call $assert_sha256
(i32.const 4)
(i32.const 5)
(i32.const 17)
)
)
)
)=====";
static const char entry_wast[] = R"=====( static const char entry_wast[] = R"=====(
(module (module
(import "env" "require_auth" (func $require_auth (param i64))) (import "env" "require_auth" (func $require_auth (param i64)))
...@@ -27,21 +167,25 @@ static const char entry_wast[] = R"=====( ...@@ -27,21 +167,25 @@ static const char entry_wast[] = R"=====(
(export "entry" (func $entry)) (export "entry" (func $entry))
(export "apply" (func $apply)) (export "apply" (func $apply))
(func $entry (func $entry
(i32.store offset=4 (block
(i32.const 0) (i32.store offset=4
(call $now) (i32.const 0)
(call $now)
)
) )
) )
(func $apply (param $0 i64) (param $1 i64) (param $2 i64) (func $apply (param $0 i64) (param $1 i64) (param $2 i64)
(call $require_auth (i64.const 6121376101093867520)) (block
(call $eosio_assert (call $require_auth (i64.const 6121376101093867520))
(i32.eq (call $eosio_assert
(i32.load offset=4 (i32.eq
(i32.const 0) (i32.load offset=4
(i32.const 0)
)
(call $now)
) )
(call $now) (i32.const 0)
) )
(i32.const 0)
) )
) )
(start $entry) (start $entry)
......
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <eosio/testing/tester.hpp> #include <eosio/testing/tester.hpp>
#include <eosio/chain/contracts/abi_serializer.hpp> #include <eosio/chain/contracts/abi_serializer.hpp>
#include <eosio/chain/wasm_eosio_constraints.hpp> #include <eosio/chain/wasm_eosio_constraints.hpp>
...@@ -363,7 +365,6 @@ BOOST_FIXTURE_TEST_CASE( f32_f64_conversion_tests, tester ) try { ...@@ -363,7 +365,6 @@ BOOST_FIXTURE_TEST_CASE( f32_f64_conversion_tests, tester ) try {
// test softfloat conversion operations // test softfloat conversion operations
BOOST_FIXTURE_TEST_CASE( f32_f64_overflow_tests, tester ) try { BOOST_FIXTURE_TEST_CASE( f32_f64_overflow_tests, tester ) try {
int count = 0; int count = 0;
auto check = [&](const char *wast_template, const char *op, const char *param) -> bool { auto check = [&](const char *wast_template, const char *op, const char *param) -> bool {
count+=16; count+=16;
...@@ -464,6 +465,40 @@ BOOST_FIXTURE_TEST_CASE( f32_f64_overflow_tests, tester ) try { ...@@ -464,6 +465,40 @@ BOOST_FIXTURE_TEST_CASE( f32_f64_overflow_tests, tester ) try {
BOOST_REQUIRE_EQUAL(false, check(i64_overflow_wast, "i64_trunc_u_f64", "f64.const 18446744073709551616")); BOOST_REQUIRE_EQUAL(false, check(i64_overflow_wast, "i64_trunc_u_f64", "f64.const 18446744073709551616"));
} FC_LOG_AND_RETHROW() } FC_LOG_AND_RETHROW()
BOOST_FIXTURE_TEST_CASE(misaligned_tests, tester ) try {
produce_blocks(2);
create_accounts( {N(aligncheck)} );
produce_block();
auto check_aligned = [&]( auto wast ) {
set_code(N(aligncheck), wast);
produce_blocks(10);
signed_transaction trx;
action act;
act.account = N(aligncheck);
act.name = N();
act.authorization = vector<permission_level>{{N(aligncheck),config::active_name}};
trx.actions.push_back(act);
set_transaction_headers(trx);
trx.sign(get_private_key( N(aligncheck), "active" ), chain_id_type());
push_transaction(trx);
auto sb = produce_block();
block_trace trace(sb);
BOOST_REQUIRE_EQUAL(true, chain_has_transaction(trx.id()));
};
check_aligned(aligned_ref_wast);
check_aligned(misaligned_ref_wast);
check_aligned(aligned_const_ref_wast);
check_aligned(misaligned_const_ref_wast);
check_aligned(aligned_ptr_wast);
check_aligned(misaligned_ptr_wast);
check_aligned(misaligned_const_ptr_wast);
} FC_LOG_AND_RETHROW()
// test cpu usage // test cpu usage
BOOST_FIXTURE_TEST_CASE(cpu_usage_tests, tester ) try { BOOST_FIXTURE_TEST_CASE(cpu_usage_tests, tester ) try {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册