提交 82cde96d 编写于 作者: A arhag

Merge branch 'master' into enforce-new-transaction-header-parameters

......@@ -29,7 +29,6 @@ libraries/egenesis/egenesis_full.cpp
libraries/egenesis/embed_genesis
libraries/types/type_generator
libraries/types/types_test
libraries/types/include/eos/types/generated.hpp
libraries/wallet/Doxyfile
libraries/wallet/api_documentation.cpp
......
......@@ -190,13 +190,13 @@ namespace eosiosystem {
}
ACTION( SystemAccount, canceldelay ) {
uint32_t sender_id;
transaction_id_type trx_id;
EOSLIB_SERIALIZE( canceldelay, (sender_id) )
EOSLIB_SERIALIZE( canceldelay, (trx_id) )
};
static void on( const canceldelay& ) {
}
};
}
......@@ -59,6 +59,8 @@ struct fixed_string16 {
char str[16];
};
typedef struct checksum256 transaction_id_type;
typedef struct fixed_string16 field_name;
struct fixed_string32 {
......
......@@ -303,7 +303,7 @@ void apply_context::execute_deferred( deferred_transaction&& trx ) {
} FC_CAPTURE_AND_RETHROW((trx));
}
void apply_context::cancel_deferred( uint128_t sender_id ) {
void apply_context::cancel_deferred( const uint128_t& sender_id ) {
results.deferred_transaction_requests.push_back(deferred_reference(receiver, sender_id));
}
......@@ -428,24 +428,6 @@ int apply_context::get_context_free_data( uint32_t index, char* buffer, size_t b
return s;
}
uint32_t apply_context::get_next_sender_id() {
const uint64_t id = N(config::eosio_auth_scope);
const auto table = N(deferred.seq);
const auto payer = config::system_account_name;
const auto iter = db_find_i64(config::system_account_name, config::eosio_auth_scope, table, id);
if (iter == -1) {
const uint32_t next_serial = 1;
db_store_i64(config::system_account_name, config::eosio_auth_scope, table, payer, id, (const char*)&next_serial, sizeof(next_serial));
return 0;
}
uint32_t next_serial = 0;
db_get_i64(iter, (char*)&next_serial, sizeof(next_serial));
const auto result = next_serial++;
db_update_i64(iter, payer, (const char*)&next_serial, sizeof(next_serial));
return result;
}
int apply_context::db_store_i64( uint64_t scope, uint64_t table, const account_name& payer, uint64_t id, const char* buffer, size_t buffer_size ) {
return db_store_i64( receiver, scope, table, payer, id, buffer, buffer_size);
}
......
......@@ -311,6 +311,7 @@ transaction_trace chain_controller::_push_transaction(const packed_transaction&
if( mtrx.delay.count() == 0 ) {
result = _push_transaction( std::move(mtrx) );
} else {
result = wrap_transaction_processing( std::move(mtrx),
[this](transaction_metadata& meta) { return delayed_transaction_processing(meta); } );
}
......@@ -350,6 +351,11 @@ transaction_trace chain_controller::_push_transaction( transaction_metadata&& da
return wrap_transaction_processing( move(data), process_apply_transaction );
} FC_CAPTURE_AND_RETHROW( ) }
uint128_t chain_controller::transaction_id_to_sender_id( const transaction_id_type& tid )const {
fc::uint128_t _id(tid._hash[3], tid._hash[2]);
return (unsigned __int128)_id;
}
transaction_trace chain_controller::delayed_transaction_processing( const transaction_metadata& mtrx )
{ try {
transaction_trace result(mtrx.id);
......@@ -386,7 +392,7 @@ transaction_trace chain_controller::delayed_transaction_processing( const transa
FC_ASSERT(!payer.empty(), "Failed to find a payer for delayed transaction!");
deferred_transaction dtrx(context.get_next_sender_id(), config::system_account_name, payer, execute_after, trx);
deferred_transaction dtrx(transaction_id_to_sender_id( trx.id() ), config::system_account_name, payer, execute_after, trx);
FC_ASSERT( dtrx.execute_after < dtrx.expiration, "transaction expires before it can execute" );
result.deferred_transaction_requests.push_back(std::move(dtrx));
......
......@@ -71,6 +71,7 @@ namespace eosio { namespace chain { namespace contracts {
built_in_types.emplace("checksum160", pack_unpack<checksum160_type>());
built_in_types.emplace("checksum256", pack_unpack<checksum256_type>());
built_in_types.emplace("checksum512", pack_unpack<checksum512_type>());
built_in_types.emplace("transaction_id_type", pack_unpack<checksum256_type>());
built_in_types.emplace("field_name", pack_unpack<field_name>());
built_in_types.emplace("fixed_string32", pack_unpack<fixed_string32>());
built_in_types.emplace("fixed_string16", pack_unpack<fixed_string16>());
......
......@@ -160,7 +160,7 @@ abi_def chain_initializer::eos_contract_abi(const abi_def& eosio_system_abi)
eos_abi.structs.emplace_back( struct_def {
"canceldelay", "", {
{"sender_id", "uint32"},
{"trx_id", "transaction_id_type"},
}
});
......@@ -169,7 +169,7 @@ abi_def chain_initializer::eos_contract_abi(const abi_def& eosio_system_abi)
eos_abi.structs.emplace_back( struct_def {
"pending_recovery", "", {
{"account", "name"},
{"request_id", "uint32"},
{"request_id", "uint128"},
{"update", "updateauth"},
{"memo", "string"}
}
......
......@@ -480,9 +480,8 @@ void apply_eosio_postrecovery(apply_context& context) {
.parent = 0,
.data = recover_act.data
}, update);
uint32_t request_id = context.get_next_sender_id();
const uint128_t request_id = context.controller.transaction_id_to_sender_id(context.trx_meta.id);
auto record_data = mutable_variant_object()
("account", account)
("request_id", request_id)
......@@ -490,10 +489,10 @@ void apply_eosio_postrecovery(apply_context& context) {
("memo", recover_act.memo);
deferred_transaction dtrx;
dtrx.sender = config::system_account_name;
dtrx.sender = config::system_account_name;
dtrx.sender_id = request_id;
dtrx.payer = config::system_account_name; // NOTE: we pre-reserve capacity for this during create account
dtrx.region = 0;
dtrx.payer = config::system_account_name; // NOTE: we pre-reserve capacity for this during create account
dtrx.region = 0;
dtrx.execute_after = context.controller.head_block_time() + delay_lock;
dtrx.set_reference_block(context.controller.head_block_id());
dtrx.expiration = dtrx.execute_after + fc::seconds(60);
......@@ -502,11 +501,11 @@ void apply_eosio_postrecovery(apply_context& context) {
context.execute_deferred(std::move(dtrx));
auto data = get_abi_serializer().variant_to_binary("pending_recovery", record_data);
const uint64_t id = account;
const uint64_t table = N(recovery);
const auto payer = account;
const auto iter = context.db_find_i64(config::system_account_name, account, table, id);
if (iter == -1) {
context.db_store_i64(account, table, payer, id, (const char*)data.data(), data.size());
......@@ -543,7 +542,7 @@ void apply_eosio_passrecovery(apply_context& context) {
context.execute_inline(move(act));
remove_pending_recovery(context, account);
context.console_append_formatted("Account ${account} successfully recoverd!\n", mutable_variant_object()("account", account));
context.console_append_formatted("Account ${account} successfully recovered!\n", mutable_variant_object()("account", account));
}
void apply_eosio_vetorecovery(apply_context& context) {
......@@ -556,7 +555,7 @@ void apply_eosio_vetorecovery(apply_context& context) {
FC_ASSERT(maybe_recovery, "No pending recovery found for account ${account}", ("account", account));
auto recovery = *maybe_recovery;
context.cancel_deferred(recovery["request_id"].as<uint32_t>());
context.cancel_deferred(recovery["request_id"].as<uint128_t>());
remove_pending_recovery(context, account);
context.console_append_formatted("Recovery for account ${account} vetoed!\n", mutable_variant_object()("account", account));
......@@ -564,12 +563,13 @@ void apply_eosio_vetorecovery(apply_context& context) {
void apply_eosio_canceldelay(apply_context& context) {
auto cancel = context.act.data_as<canceldelay>();
const auto sender_id = cancel.sender_id;
const auto& trx_id = cancel.trx_id;
const auto& generated_transaction_idx = context.controller.get_database().get_index<generated_transaction_multi_index>();
const auto& generated_index = generated_transaction_idx.indices().get<by_sender_id>();
const auto& itr = generated_index.lower_bound(boost::make_tuple(config::system_account_name, sender_id));
FC_ASSERT (itr != generated_index.end() && itr->sender == config::system_account_name && itr->sender_id == sender_id,
"cannot cancel sender_id=${sid}, there is no deferred transaction with that sender_id",("sid",sender_id));
const auto& generated_index = generated_transaction_idx.indices().get<by_trx_id>();
const auto& itr = generated_index.lower_bound(trx_id);
FC_ASSERT (itr != generated_index.end() && itr->sender == config::system_account_name && itr->trx_id == trx_id,
"cannot cancel trx_id=${tid}, there is no deferred transaction with that transaction id",("tid", trx_id));
auto dtrx = fc::raw::unpack<deferred_transaction>(itr->packed_trx.data(), itr->packed_trx.size());
set<account_name> accounts;
......@@ -589,7 +589,8 @@ void apply_eosio_canceldelay(apply_context& context) {
FC_ASSERT (found, "canceldelay action must be signed with the \"active\" permission for one of the actors"
" provided in the authorizations on the original transaction");
context.cancel_deferred(sender_id);
context.cancel_deferred(context.controller.transaction_id_to_sender_id(trx_id));
}
} } } // namespace eosio::chain::contracts
......@@ -471,7 +471,7 @@ class apply_context {
void execute_inline( action &&a );
void execute_context_free_inline( action &&a );
void execute_deferred( deferred_transaction &&trx );
void cancel_deferred( uint128_t sender_id );
void cancel_deferred( const uint128_t& sender_id );
/**
* @brief Require @ref account to have approved of this message
......@@ -511,8 +511,6 @@ class apply_context {
const bytes& get_packed_transaction();
uint32_t get_next_sender_id();
const chain_controller& controller;
const chainbase::database& db; ///< database where state is stored
const action& act; ///< message being applied
......
......@@ -91,7 +91,8 @@ namespace eosio { namespace chain {
void push_block( const signed_block& b, uint32_t skip = skip_nothing );
transaction_trace push_transaction( const packed_transaction& trx, uint32_t skip = skip_nothing );
vector<transaction_trace> push_deferred_transactions( bool flush = false, uint32_t skip = skip_nothing );
uint128_t transaction_id_to_sender_id( const transaction_id_type& tid )const;
/**
* This signal is emitted after all operations and virtual operation for a
......
......@@ -270,7 +270,7 @@ struct vetorecovery {
};
struct canceldelay {
uint128_t sender_id;
transaction_id_type trx_id;
static account_name get_account() {
return config::system_account_name;
......@@ -300,4 +300,4 @@ FC_REFLECT( eosio::chain::contracts::unlinkauth , (account
FC_REFLECT( eosio::chain::contracts::postrecovery , (account)(data)(memo) )
FC_REFLECT( eosio::chain::contracts::passrecovery , (account) )
FC_REFLECT( eosio::chain::contracts::vetorecovery , (account) )
FC_REFLECT( eosio::chain::contracts::canceldelay , (sender_id) )
FC_REFLECT( eosio::chain::contracts::canceldelay , (trx_id) )
......@@ -90,6 +90,7 @@ namespace eosio { namespace chain {
operator bool()const { return value; }
operator uint64_t()const { return value; }
operator unsigned __int128()const { return value; }
};
......
......@@ -4,7 +4,6 @@
*/
#pragma once
#include <eosio/chain/types.hpp>
#include <numeric>
namespace eosio { namespace chain {
......@@ -229,7 +228,7 @@ namespace eosio { namespace chain {
uint128_t sender_id; /// ID assigned by sender of generated, accessible via WASM api when executing normal or error
account_name sender; /// receives error handler callback
account_name payer;
time_point_sec execute_after; /// delayed exeuction
time_point_sec execute_after; /// delayed execution
deferred_transaction() = default;
......@@ -244,7 +243,7 @@ namespace eosio { namespace chain {
struct deferred_reference {
deferred_reference(){}
deferred_reference( const account_name& sender, uint128_t sender_id)
deferred_reference( const account_name& sender, const uint128_t& sender_id)
:sender(sender),sender_id(sender_id)
{}
......@@ -263,4 +262,4 @@ FC_REFLECT_DERIVED( eosio::chain::signed_transaction, (eosio::chain::transaction
FC_REFLECT_ENUM( eosio::chain::packed_transaction::compression_type, (none)(zlib))
FC_REFLECT( eosio::chain::packed_transaction, (signatures)(compression)(packed_context_free_data)(packed_trx) )
FC_REFLECT_DERIVED( eosio::chain::deferred_transaction, (eosio::chain::transaction), (sender_id)(sender)(payer)(execute_after) )
FC_REFLECT( eosio::chain::deferred_reference, (sender_id)(sender) )
FC_REFLECT( eosio::chain::deferred_reference, (sender)(sender_id) )
......@@ -545,7 +545,7 @@ class softfloat_api : public context_aware_api {
}
int32_t _eosio_f32_trunc_i32s( float af ) {
float32_t a = to_softfloat32(af);
if (_eosio_f32_ge(af, 2147483648.0f) || _eosio_f32_le(af, -2147483649.0f))
if (_eosio_f32_ge(af, 2147483648.0f) || _eosio_f32_lt(af, -2147483648.0f))
FC_THROW_EXCEPTION( eosio::chain::wasm_execution_error, "Error, f32.convert_s/i32 overflow" );
if (is_nan(a))
......@@ -554,7 +554,7 @@ class softfloat_api : public context_aware_api {
}
int32_t _eosio_f64_trunc_i32s( double af ) {
float64_t a = to_softfloat64(af);
if (_eosio_f64_ge(af, 2147483648.0) || _eosio_f64_le(af, -2147483649.0))
if (_eosio_f64_ge(af, 2147483648.0) || _eosio_f64_lt(af, -2147483648.0))
FC_THROW_EXCEPTION( eosio::chain::wasm_execution_error, "Error, f64.convert_s/i32 overflow");
if (is_nan(a))
FC_THROW_EXCEPTION( eosio::chain::wasm_execution_error, "Error, f64.convert_s/i32 unrepresentable");
......@@ -578,7 +578,7 @@ class softfloat_api : public context_aware_api {
}
int64_t _eosio_f32_trunc_i64s( float af ) {
float32_t a = to_softfloat32(af);
if (_eosio_f32_ge(af, 9223372036854775808.0f) || _eosio_f32_le(af, -9223372036854775809.0f))
if (_eosio_f32_ge(af, 9223372036854775808.0f) || _eosio_f32_lt(af, -9223372036854775808.0f))
FC_THROW_EXCEPTION( eosio::chain::wasm_execution_error, "Error, f32.convert_s/i64 overflow");
if (is_nan(a))
FC_THROW_EXCEPTION( eosio::chain::wasm_execution_error, "Error, f32.convert_s/i64 unrepresentable");
......@@ -586,7 +586,7 @@ class softfloat_api : public context_aware_api {
}
int64_t _eosio_f64_trunc_i64s( double af ) {
float64_t a = to_softfloat64(af);
if (_eosio_f64_ge(af, 9223372036854775808.0) || _eosio_f64_le(af, -9223372036854775809.0))
if (_eosio_f64_ge(af, 9223372036854775808.0) || _eosio_f64_lt(af, -9223372036854775808.0))
FC_THROW_EXCEPTION( eosio::chain::wasm_execution_error, "Error, f64.convert_s/i64 overflow");
if (is_nan(a))
FC_THROW_EXCEPTION( eosio::chain::wasm_execution_error, "Error, f64.convert_s/i64 unrepresentable");
......
......@@ -7,7 +7,7 @@ if(NOT EOS_GIT_REVISION_DESCRIPTION)
set(EOS_GIT_REVISION_DESCRIPTION "unknown")
endif(NOT EOS_GIT_REVISION_DESCRIPTION)
file(GLOB HEADERS "include/eos/utilities/*.hpp")
file(GLOB HEADERS "include/eosio/utilities/*.hpp")
set(sources
key_conversion.cpp
......
file(GLOB HEADERS "include/eos/chain_api_plugin/*.hpp")
file(GLOB HEADERS "include/eosio/chain_api_plugin/*.hpp")
add_library( chain_api_plugin
chain_api_plugin.cpp
${HEADERS} )
......
file(GLOB HEADERS "include/eos/chain_plugin/*.hpp")
file(GLOB HEADERS "include/eosio/chain_plugin/*.hpp")
add_library( chain_plugin
chain_plugin.cpp
${HEADERS} )
......
......@@ -12,7 +12,7 @@ echo Copying template...
cp -r template_plugin $pluginName
echo Renaming files/directories...
mv $pluginName/include/eos/template_plugin $pluginName/include/eos/$pluginName
mv $pluginName/include/eosio/template_plugin $pluginName/include/eosio/$pluginName
for file in `find $pluginName -type f -name '*template_plugin*'`; do mv $file `sed s/template_plugin/$pluginName/g <<< $file`; done;
echo Renaming in files...
......
file(GLOB HEADERS "include/eos/http_plugin/*.hpp")
file(GLOB HEADERS "include/eosio/http_plugin/*.hpp")
add_library( http_plugin
http_plugin.cpp
${HEADERS} )
......
file(GLOB HEADERS "include/eos/producer_plugin/*.hpp")
file(GLOB HEADERS "include/eosio/producer_plugin/*.hpp")
add_library( producer_plugin
producer_plugin.cpp
......
file(GLOB HEADERS "include/eos/wallet_api_plugin/*.hpp")
file(GLOB HEADERS "include/eosio/wallet_api_plugin/*.hpp")
add_library( wallet_api_plugin
wallet_api_plugin.cpp
${HEADERS} )
......
file(GLOB HEADERS "include/eos/wallet_plugin/*.hpp")
file(GLOB HEADERS "include/eosio/wallet_plugin/*.hpp")
add_library( wallet_plugin
wallet.cpp
wallet_plugin.cpp
......
......@@ -19,7 +19,7 @@ include_directories("${CMAKE_SOURCE_DIR}/plugins/wallet_plugin/include")
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/tests/config.hpp.in ${CMAKE_CURRENT_SOURCE_DIR}/tests/config.hpp ESCAPE_QUOTES)
file(GLOB UNIT_TESTS "chain_tests/*.cpp" "api_tests/*.cpp" "tests/abi_tests.cpp" "tests/database_tests.cpp" "tests/misc_tests.cpp" "wasm_tests/*.cpp" "tests/message_buffer_tests.cpp" "tests/wallet_tests.cpp" "library_tests/*/*.cpp")
file(GLOB UNIT_TESTS "chain_tests/*.cpp" "api_tests/*.cpp" "tests/abi_tests.cpp" "tests/database_tests.cpp" "tests/misc_tests.cpp" "wasm_tests/*.cpp" "tests/message_buffer_tests.cpp" "tests/special_accounts_tests.cpp" "tests/wallet_tests.cpp" "library_tests/*/*.cpp")
add_executable( chain_test ${UNIT_TESTS} ${WASM_UNIT_TESTS} common/main.cpp)
target_link_libraries( chain_test eosio_testing eosio_chain chainbase eos_utilities chain_plugin wallet_plugin abi_generator fc ${PLATFORM_SPECIFIC_LIBS} )
......
......@@ -1362,7 +1362,7 @@ BOOST_AUTO_TEST_CASE( canceldelay_test ) { try {
TESTER chain;
const auto& tester_account = N(tester);
std::vector<transaction_id_type> ids;
chain.set_code(config::system_account_name, eosio_system_wast);
chain.set_abi(config::system_account_name, eosio_system_abi);
......@@ -1428,9 +1428,11 @@ BOOST_AUTO_TEST_CASE( canceldelay_test ) { try {
("memo", "hi" ),
30, 10
);
ids.push_back(trace.id);
BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace.status);
BOOST_REQUIRE_EQUAL(1, trace.deferred_transaction_requests.size());
BOOST_REQUIRE_EQUAL(0, trace.action_traces.size());
const auto sender_id_to_cancel = trace.deferred_transaction_requests[0].get<deferred_transaction>().sender_id;
chain.produce_blocks();
......@@ -1451,6 +1453,7 @@ BOOST_AUTO_TEST_CASE( canceldelay_test ) { try {
("delay", 0),
30, 10
);
ids.push_back(trace.id);
BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace.status);
BOOST_REQUIRE_EQUAL(1, trace.deferred_transaction_requests.size());
BOOST_REQUIRE_EQUAL(0, trace.action_traces.size());
......@@ -1477,6 +1480,7 @@ BOOST_AUTO_TEST_CASE( canceldelay_test ) { try {
("memo", "hi" ),
30, 10
);
ids.push_back(trace.id);
BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace.status);
BOOST_REQUIRE_EQUAL(1, trace.deferred_transaction_requests.size());
BOOST_REQUIRE_EQUAL(0, trace.action_traces.size());
......@@ -1491,14 +1495,16 @@ BOOST_AUTO_TEST_CASE( canceldelay_test ) { try {
// send canceldelay for first delayed transaction
signed_transaction trx;
trx.actions.emplace_back(vector<permission_level>{{N(tester), config::active_name}},
chain::contracts::canceldelay{sender_id_to_cancel});
chain::contracts::canceldelay{ids[0]});
trx.actions.back().authorization.push_back({N(tester), config::active_name});
chain.set_transaction_headers(trx);
trx.sign(chain.get_private_key(N(tester), "active"), chain_id_type());
trace = chain.push_transaction(trx);
BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace.status);
BOOST_REQUIRE_EQUAL(1, trace.deferred_transaction_requests.size());
const auto sender_id_canceled = trace.deferred_transaction_requests[0].get<deferred_reference>().sender_id;
BOOST_REQUIRE_EQUAL(std::string(uint128(sender_id_to_cancel)), std::string(uint128(sender_id_canceled)));
......@@ -1555,7 +1561,6 @@ BOOST_AUTO_TEST_CASE( canceldelay_test ) { try {
BOOST_REQUIRE_EQUAL(asset::from_string("85.0000 CUR"), liquid_balance);
liquid_balance = get_currency_balance(chain, N(tester2));
BOOST_REQUIRE_EQUAL(asset::from_string("15.0000 CUR"), liquid_balance);
} FC_LOG_AND_RETHROW() }/// schedule_test
BOOST_AUTO_TEST_SUITE_END()
/**
* @file
* @copyright defined in eos/LICENSE.txt
*/
#include <algorithm>
#include <vector>
#include <iterator>
#include <boost/test/unit_test.hpp>
#include <eosio/chain/chain_controller.hpp>
#include <eosio/chain/exceptions.hpp>
#include <eosio/chain/permission_object.hpp>
#include <eosio/testing/tester.hpp>
#include <eosio/utilities/tempdir.hpp>
#include <fc/crypto/digest.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/range/algorithm/find.hpp>
#include <boost/range/algorithm/find_if.hpp>
#include <boost/range/algorithm/permutation.hpp>
using namespace eosio;
using namespace chain;
using tester = eosio::testing::tester;
BOOST_AUTO_TEST_SUITE(special_account_tests)
//Check special accounts exits in genesis
BOOST_FIXTURE_TEST_CASE(accounts_exists, tester)
{ try {
tester test;
chain::chain_controller *control = test.control.get();
chain::database &chain1_db = control->get_mutable_database();
auto nobody = chain1_db.find<account_object, by_name>(config::nobody_account_name);
BOOST_CHECK(nobody != nullptr);
const auto& nobody_active_authority = chain1_db.get<permission_object, by_owner>(boost::make_tuple(config::nobody_account_name, config::active_name));
BOOST_CHECK_EQUAL(nobody_active_authority.auth.threshold, 0);
BOOST_CHECK_EQUAL(nobody_active_authority.auth.accounts.size(), 0);
BOOST_CHECK_EQUAL(nobody_active_authority.auth.keys.size(), 0);
const auto& nobody_owner_authority = chain1_db.get<permission_object, by_owner>(boost::make_tuple(config::nobody_account_name, config::owner_name));
BOOST_CHECK_EQUAL(nobody_owner_authority.auth.threshold, 0);
BOOST_CHECK_EQUAL(nobody_owner_authority.auth.accounts.size(), 0);
BOOST_CHECK_EQUAL(nobody_owner_authority.auth.keys.size(), 0);
auto producers = chain1_db.find<account_object, by_name>(config::producers_account_name);
BOOST_CHECK(producers != nullptr);
auto& gpo = chain1_db.get<global_property_object>();
const auto& producers_active_authority = chain1_db.get<permission_object, by_owner>(boost::make_tuple(config::producers_account_name, config::active_name));
BOOST_CHECK_EQUAL(producers_active_authority.auth.threshold, config::producers_authority_threshold);
BOOST_CHECK_EQUAL(producers_active_authority.auth.accounts.size(), gpo.active_producers.producers.size());
BOOST_CHECK_EQUAL(producers_active_authority.auth.keys.size(), 0);
std::vector<account_name> active_auth;
for(auto& apw : producers_active_authority.auth.accounts) {
active_auth.emplace_back(apw.permission.actor);
}
std::vector<account_name> diff;
for (int i = 0; i < std::max(active_auth.size(), gpo.active_producers.producers.size()); ++i) {
account_name n1 = i < active_auth.size() ? active_auth[i] : (account_name)0;
account_name n2 = i < gpo.active_producers.producers.size() ? gpo.active_producers.producers[i].producer_name : (account_name)0;
if (n1 != n2) diff.push_back((uint64_t)n2 - (uint64_t)n1);
}
BOOST_CHECK_EQUAL(diff.size(), 0);
const auto& producers_owner_authority = chain1_db.get<permission_object, by_owner>(boost::make_tuple(config::producers_account_name, config::owner_name));
BOOST_CHECK_EQUAL(producers_owner_authority.auth.threshold, 0);
BOOST_CHECK_EQUAL(producers_owner_authority.auth.accounts.size(), 0);
BOOST_CHECK_EQUAL(producers_owner_authority.auth.keys.size(), 0);
} FC_LOG_AND_RETHROW() }
BOOST_AUTO_TEST_SUITE_END()
......@@ -21647,3 +21647,38 @@ static const char f32_f64_conv_wast[] = R"=====(
(call $assert_returnf64 (call $f64_convert_u_i64 (i64.const 9007199254740995)) (f64.const 9007199254740996) (i32.const 1040))
))
)=====";
static const char i32_overflow_wast[] = R"=====(
(module
(import "env" "require_auth" (func $require_auth (param i64)))
(import "env" "eosio_assert" (func $eosio_assert (param i32 i32)))
(table 0 anyfunc)
(memory $0 1)
(export "apply" (func $apply))
(func $i32_trunc_s_f32 (param $0 f32) (result i32) (i32.trunc_s/f32 (get_local $0)))
(func $i32_trunc_u_f32 (param $0 f32) (result i32) (i32.trunc_u/f32 (get_local $0)))
(func $i32_trunc_s_f64 (param $0 f64) (result i32) (i32.trunc_s/f64 (get_local $0)))
(func $i32_trunc_u_f64 (param $0 f64) (result i32) (i32.trunc_u/f64 (get_local $0)))
(func $test (param $0 i32))
(func $apply (param $0 i64)(param $1 i64)(param $2 i64)
(call $test (call $%s (%s)))
))
)=====";
static const char i64_overflow_wast[] = R"=====(
(module
(import "env" "require_auth" (func $require_auth (param i64)))
(import "env" "eosio_assert" (func $eosio_assert (param i32 i32)))
(table 0 anyfunc)
(memory $0 1)
(export "apply" (func $apply))
(func $i64_trunc_s_f32 (param $0 f32) (result i64) (i64.trunc_s/f32 (get_local $0)))
(func $i64_trunc_u_f32 (param $0 f32) (result i64) (i64.trunc_u/f32 (get_local $0)))
(func $i64_trunc_s_f64 (param $0 f64) (result i64) (i64.trunc_s/f64 (get_local $0)))
(func $i64_trunc_u_f64 (param $0 f64) (result i64) (i64.trunc_u/f64 (get_local $0)))
(func $test (param $0 i64))
(func $apply (param $0 i64)(param $1 i64)(param $2 i64)
(call $test (call $%s (%s)))
))
)=====";
......@@ -360,6 +360,110 @@ BOOST_FIXTURE_TEST_CASE( f32_f64_conversion_tests, tester ) try {
}
} FC_LOG_AND_RETHROW()
// 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;
create_accounts( {N(f_tests)+count} );
produce_blocks(1);
std::vector<char> wast;
wast.resize(strlen(wast_template) + 128);
sprintf(&(wast[0]), wast_template, op, param);
set_code(N(f_tests)+count, &(wast[0]));
produce_blocks(10);
signed_transaction trx;
action act;
act.account = N(f_tests)+count;
act.name = N();
act.authorization = vector<permission_level>{{N(f_tests)+count,config::active_name}};
trx.actions.push_back(act);
set_transaction_headers(trx);
trx.sign(get_private_key( N(f_tests)+count, "active" ), chain_id_type());
try {
push_transaction(trx);
produce_blocks(1);
BOOST_REQUIRE_EQUAL(true, chain_has_transaction(trx.id()));
const auto& receipt = get_transaction_receipt(trx.id());
return true;
} catch (eosio::chain::wasm_execution_error &) {
return false;
}
};
//
//// float32 => int32
// 2^31
BOOST_REQUIRE_EQUAL(false, check(i32_overflow_wast, "i32_trunc_s_f32", "f32.const 2147483648"));
// the maximum value below 2^31 representable in IEEE float32
BOOST_REQUIRE_EQUAL(true, check(i32_overflow_wast, "i32_trunc_s_f32", "f32.const 2147483520"));
// -2^31
BOOST_REQUIRE_EQUAL(true, check(i32_overflow_wast, "i32_trunc_s_f32", "f32.const -2147483648"));
// the maximum value below -2^31 in IEEE float32
BOOST_REQUIRE_EQUAL(false, check(i32_overflow_wast, "i32_trunc_s_f32", "f32.const -2147483904"));
//
//// float32 => uint32
BOOST_REQUIRE_EQUAL(true, check(i32_overflow_wast, "i32_trunc_u_f32", "f32.const 0"));
BOOST_REQUIRE_EQUAL(false, check(i32_overflow_wast, "i32_trunc_u_f32", "f32.const -1"));
// max value below 2^32 in IEEE float32
BOOST_REQUIRE_EQUAL(true, check(i32_overflow_wast, "i32_trunc_u_f32", "f32.const 4294967040"));
BOOST_REQUIRE_EQUAL(false, check(i32_overflow_wast, "i32_trunc_u_f32", "f32.const 4294967296"));
//
//// double => int32
BOOST_REQUIRE_EQUAL(false, check(i32_overflow_wast, "i32_trunc_s_f64", "f64.const 2147483648"));
BOOST_REQUIRE_EQUAL(true, check(i32_overflow_wast, "i32_trunc_s_f64", "f64.const 2147483647"));
BOOST_REQUIRE_EQUAL(true, check(i32_overflow_wast, "i32_trunc_s_f64", "f64.const -2147483648"));
BOOST_REQUIRE_EQUAL(false, check(i32_overflow_wast, "i32_trunc_s_f64", "f64.const -2147483649"));
//
//// double => uint32
BOOST_REQUIRE_EQUAL(true, check(i32_overflow_wast, "i32_trunc_u_f64", "f64.const 0"));
BOOST_REQUIRE_EQUAL(false, check(i32_overflow_wast, "i32_trunc_u_f64", "f64.const -1"));
BOOST_REQUIRE_EQUAL(true, check(i32_overflow_wast, "i32_trunc_u_f64", "f64.const 4294967295"));
BOOST_REQUIRE_EQUAL(false, check(i32_overflow_wast, "i32_trunc_u_f64", "f64.const 4294967296"));
//// float32 => int64
// 2^63
BOOST_REQUIRE_EQUAL(false, check(i64_overflow_wast, "i64_trunc_s_f32", "f32.const 9223372036854775808"));
// the maximum value below 2^63 representable in IEEE float32
BOOST_REQUIRE_EQUAL(true, check(i64_overflow_wast, "i64_trunc_s_f32", "f32.const 9223371487098961920"));
// -2^63
BOOST_REQUIRE_EQUAL(true, check(i64_overflow_wast, "i64_trunc_s_f32", "f32.const -9223372036854775808"));
// the maximum value below -2^63 in IEEE float32
BOOST_REQUIRE_EQUAL(false, check(i64_overflow_wast, "i64_trunc_s_f32", "f32.const -9223373136366403584"));
//// float32 => uint64
BOOST_REQUIRE_EQUAL(false, check(i64_overflow_wast, "i64_trunc_u_f32", "f32.const -1"));
BOOST_REQUIRE_EQUAL(true, check(i64_overflow_wast, "i64_trunc_u_f32", "f32.const 0"));
// max value below 2^64 in IEEE float32
BOOST_REQUIRE_EQUAL(true, check(i64_overflow_wast, "i64_trunc_u_f32", "f32.const 18446742974197923840"));
BOOST_REQUIRE_EQUAL(false, check(i64_overflow_wast, "i64_trunc_u_f32", "f32.const 18446744073709551616"));
//// double => int64
// 2^63
BOOST_REQUIRE_EQUAL(false, check(i64_overflow_wast, "i64_trunc_s_f64", "f64.const 9223372036854775808"));
// the maximum value below 2^63 representable in IEEE float64
BOOST_REQUIRE_EQUAL(true, check(i64_overflow_wast, "i64_trunc_s_f64", "f64.const 9223372036854774784"));
// -2^63
BOOST_REQUIRE_EQUAL(true, check(i64_overflow_wast, "i64_trunc_s_f64", "f64.const -9223372036854775808"));
// the maximum value below -2^63 in IEEE float64
BOOST_REQUIRE_EQUAL(false, check(i64_overflow_wast, "i64_trunc_s_f64", "f64.const -9223372036854777856"));
//// double => uint64
BOOST_REQUIRE_EQUAL(false, check(i64_overflow_wast, "i64_trunc_u_f64", "f64.const -1"));
BOOST_REQUIRE_EQUAL(true, check(i64_overflow_wast, "i64_trunc_u_f64", "f64.const 0"));
// max value below 2^64 in IEEE float64
BOOST_REQUIRE_EQUAL(true, check(i64_overflow_wast, "i64_trunc_u_f64", "f64.const 18446744073709549568"));
BOOST_REQUIRE_EQUAL(false, check(i64_overflow_wast, "i64_trunc_u_f64", "f64.const 18446744073709551616"));
} FC_LOG_AND_RETHROW()
/**
* Make sure WASM "start" method is used correctly
*/
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册