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

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

......@@ -32,6 +32,9 @@ typedef uint64_t asset_symbol;
typedef int64_t share_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 {
char data[34];
};
......@@ -40,15 +43,15 @@ struct signature {
uint8_t data[66];
};
struct checksum256 {
struct ALIGNED(checksum256) {
uint8_t hash[32];
};
struct checksum160 {
struct ALIGNED(checksum160) {
uint8_t hash[20];
};
struct checksum512 {
struct ALIGNED(checksum512) {
uint8_t hash[64];
};
......
......@@ -12,8 +12,8 @@
#include <eosiolib/datastream.hpp>
#include <eosiolib/print.hpp>
#include <eosiolib/compiler_builtins.h>
#include "test_api.hpp"
void test_action::read_action_normal() {
char buffer[100];
......
......@@ -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[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])) {
// - | - | 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) {
return current_game.host;
} else if (current_game.board[4] == 2) {
......@@ -61,9 +61,9 @@ struct impl {
}
} 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])) {
// - | - | - - | - | x
// - | - | - - | - | x
// x | x | x - | - | x
// - | - | x - | - | -
// - | - | x - | - | -
// - | - | x x | x | x
if (current_game.board[8] == 1) {
return current_game.host;
} else if (current_game.board[8] == 2) {
......
......@@ -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));
}
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 ) {
require_read_lock(code, scope);
return db.find<table_id_object, contracts::by_code_scope_table>(boost::make_tuple(code, scope, table));
......
......@@ -587,6 +587,8 @@ class apply_context {
generic_index<contracts::index_long_double_object> idx_long_double;
uint32_t recurse_depth; // how deep inline actions can recurse
void add_cpu_usage( const uint64_t usage );
private:
iterator_cache<key_value_object> keyval_cache;
......
......@@ -15,7 +15,7 @@ typedef __uint128_t uint128_t;
const static auto default_block_log_dir = "block_log";
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 nobody_account_name = N(nobody);
......
......@@ -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_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_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_overcommitment, eosio::chain::rate_limiting_invariant_exception, 3150002, "chain resource limits are overcommitted" )
......
......@@ -57,8 +57,7 @@ namespace eosio { namespace chain { namespace wasm_injections {
if ( exp.kind == IR::ObjectKind::function )
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++;
}
......@@ -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() );
injected_index_mapping.emplace( index, actual_index );
// shift all exported functions by 1
bool have_updated_start = false;
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++;
}
}
// shift all table entries for call indirect
for(TableSegment& ts : module.tableSegments) {
for(auto& idx : ts.indices)
......@@ -90,7 +97,7 @@ namespace eosio { namespace chain { namespace wasm_injections {
}
}
};
struct noop_injection_visitor {
static void inject( IR::Module& m );
static void initializer();
......@@ -189,6 +196,7 @@ namespace eosio { namespace chain { namespace wasm_injections {
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);
auto mapped_index = injector_utils::injected_index_mapping.find(call_inst->field);
if ( mapped_index != injector_utils::injected_index_mapping.end() ) {
call_inst->field = mapped_index->second;
}
......
......@@ -3,6 +3,7 @@
#include <eosio/chain/webassembly/common.hpp>
#include <eosio/chain/webassembly/runtime_interface.hpp>
#include <eosio/chain/exceptions.hpp>
#include <eosio/chain/apply_context.hpp>
#include <wasm-interpreter.h>
#include <softfloat_types.h>
......@@ -196,18 +197,6 @@ constexpr bool is_reference_from_value_v = is_reference_from_value<T>::value;
template<typename T>
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<>
inline double convert_literal_to_native<double>(Literal& v) {
return v.getf64();
......@@ -254,15 +243,6 @@ inline auto convert_native_to_literal(const interpreter_interface*, T 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) {
return Literal(val.value);
}
......@@ -472,10 +452,32 @@ struct intrinsic_invoker_impl<Ret, std::tuple<T *, Inputs...>> {
using next_step = intrinsic_invoker_impl<Ret, std::tuple<Inputs...>>;
using then_type = Ret (*)(interpreter_interface*, T *, Inputs..., LiteralList&, int);
template<then_type Then>
static Ret translate_one(interpreter_interface* interface, Inputs... rest, LiteralList& args, int offset) {
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();
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();
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);
};
......@@ -551,15 +553,40 @@ struct intrinsic_invoker_impl<Ret, std::tuple<T &, Inputs...>> {
using next_step = intrinsic_invoker_impl<Ret, std::tuple<Inputs...>>;
using then_type = Ret (*)(interpreter_interface*, T &, Inputs..., LiteralList&, int);
template<then_type Then>
static Ret translate_one(interpreter_interface* interface, Inputs... rest, LiteralList& args, int offset) {
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
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
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 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);
}
template<then_type Then>
static const auto fn() {
return next_step::template fn<translate_one<Then>>();
......
......@@ -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 then_type = Ret (*)(running_instance_context&, T *, Inputs..., Translated...);
template<then_type Then>
static Ret translate_one(running_instance_context& ctx, Inputs... rest, Translated... translated, I32 ptr) {
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 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...);
};
......@@ -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
* 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
using next_step = intrinsic_invoker_impl<Ret, std::tuple<Inputs...>, std::tuple<Translated..., I32>>;
using then_type = Ret (*)(running_instance_context &, T &, Inputs..., Translated...);
template<then_type Then>
static Ret translate_one(running_instance_context& ctx, Inputs... rest, Translated... translated, I32 ptr) {
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
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
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 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...);
}
......
......@@ -686,7 +686,6 @@ class crypto_api : public context_aware_api {
public:
explicit crypto_api( apply_context& ctx )
:context_aware_api(ctx,true){}
/**
* This method can be optimized out during replay as it has
* no possible side effects other than "passing".
......@@ -738,7 +737,6 @@ class crypto_api : public context_aware_api {
FC_ASSERT( result == hash_val, "hash miss match" );
}
void sha1(array_ptr<char> data, size_t datalen, fc::sha1& hash_val) {
hash_val = fc::sha1::hash( data, datalen );
}
......
......@@ -43,7 +43,7 @@ class binaryen_instantiated_module : public wasm_instantiated_module_interface {
memset(_shared_linear_memory.data, 0, initial_memory_size);
//copy back in the initial data
memcpy(_shared_linear_memory.data, _initial_memory.data(), _initial_memory.size());
//be aware that construction of the ModuleInstance implictly fires the start function
ModuleInstance instance(*_module.get(), &local_interface);
instance.callExport(Name(entry_point), args);
......
......@@ -40,6 +40,7 @@ public:
time_point genesis_timestamp;
uint32_t skip_flags = skip_nothing;
bool readonly = false;
uint64_t shared_memory_size;
flat_map<uint32_t,block_id_type> loaded_checkpoints;
fc::optional<fork_database> fork_db;
......@@ -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),
"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")
("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
/*("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.")
......@@ -128,6 +131,9 @@ void chain_plugin::plugin_initialize(const variables_map& options) {
else
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>()) {
ilog("Replay requested: wiping database");
......@@ -182,6 +188,7 @@ void chain_plugin::plugin_startup()
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->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>();
if (my->genesis_timestamp.sec_since_epoch() > 0) {
my->chain_config->genesis.initial_timestamp = my->genesis_timestamp;
......
......@@ -15,7 +15,7 @@ namespace eosio {
typedef std::chrono::system_clock::duration::rep tstamp;
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
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
......
此差异已折叠。
......@@ -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() {
check_timeout();
EOS_ASSERT(!wallets.empty(), wallet_not_available_exception, "You don't have any wallet!");
flat_set<public_key_type> result;
bool is_all_wallet_locked = true;
for (const auto& i : wallets) {
if (!i.second->is_locked()) {
const auto& keys = i.second->list_keys();
......@@ -117,7 +119,9 @@ flat_set<public_key_type> wallet_manager::get_public_keys() {
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;
}
......
......@@ -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_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_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_3140006 = "Ensure that you have created a wallet and have it open";
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 },
{ 3140003, error_advice_3140003 },
{ 3140004, error_advice_3140004 },
{ 3140005, error_advice_3140005 }
{ 3140005, error_advice_3140005 },
{ 3140006, error_advice_3140006 }
};
......
......@@ -124,7 +124,7 @@
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)
COUNT=1
DISPLAY=""
......@@ -172,6 +172,44 @@
printf "\n\tNo required YUM dependencies to install.\n"
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"
if [ ! -e ${CMAKE} ]; then
printf "\tInstalling CMAKE\n"
......
......@@ -972,7 +972,6 @@ BOOST_FIXTURE_TEST_CASE(multi_index_tests, TESTER) { try {
produce_blocks(1);
set_code( N(testapi), test_api_multi_index_wast );
produce_blocks(1);
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_check_without_storing", {});
......
......@@ -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"=====(
(module
(import "env" "require_auth" (func $require_auth (param i64)))
......@@ -27,21 +167,25 @@ static const char entry_wast[] = R"=====(
(export "entry" (func $entry))
(export "apply" (func $apply))
(func $entry
(i32.store offset=4
(i32.const 0)
(call $now)
(block
(i32.store offset=4
(i32.const 0)
(call $now)
)
)
)
(func $apply (param $0 i64) (param $1 i64) (param $2 i64)
(call $require_auth (i64.const 6121376101093867520))
(call $eosio_assert
(i32.eq
(i32.load offset=4
(i32.const 0)
(block
(call $require_auth (i64.const 6121376101093867520))
(call $eosio_assert
(i32.eq
(i32.load offset=4
(i32.const 0)
)
(call $now)
)
(call $now)
(i32.const 0)
)
(i32.const 0)
)
)
(start $entry)
......
#include <boost/test/unit_test.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <eosio/testing/tester.hpp>
#include <eosio/chain/contracts/abi_serializer.hpp>
#include <eosio/chain/wasm_eosio_constraints.hpp>
......@@ -363,7 +365,6 @@ BOOST_FIXTURE_TEST_CASE( f32_f64_conversion_tests, tester ) try {
// test softfloat conversion operations
BOOST_FIXTURE_TEST_CASE( f32_f64_overflow_tests, tester ) try {
int count = 0;
auto check = [&](const char *wast_template, const char *op, const char *param) -> bool {
count+=16;
......@@ -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"));
} 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
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.
先完成此消息的编辑!
想要评论请 注册