diff --git a/.gitignore b/.gitignore index 9109fd71b22850cc47c92f1e48b2d8dec195d83f..32c2856e360ba20de5fdde0611436d5ca84e61a9 100644 --- a/.gitignore +++ b/.gitignore @@ -57,8 +57,9 @@ tests/chain_bench tests/chain_test tests/intense_test tests/performance_test -tests/tests/config.hpp +tests/config.hpp unittests/config.hpp + doxygen wallet.json diff --git a/libraries/chain/include/eosio/chain/controller.hpp b/libraries/chain/include/eosio/chain/controller.hpp index f82dd45b7b422215acc11e0562675c7f5218cc4b..09ea4bfe24bad82d19417b1b01f1cf1fa35e106e 100644 --- a/libraries/chain/include/eosio/chain/controller.hpp +++ b/libraries/chain/include/eosio/chain/controller.hpp @@ -76,12 +76,11 @@ namespace eosio { namespace chain { /** * */ - void push_transaction( const transaction_metadata_ptr& trx = transaction_metadata_ptr(), - fc::time_point deadline = fc::time_point::maximum() ); + void push_transaction( const transaction_metadata_ptr& trx, fc::time_point deadline ); - bool push_next_unapplied_transaction( fc::time_point deadline = fc::time_point::maximum() ); + bool push_next_unapplied_transaction( fc::time_point deadline ); - transaction_trace_ptr sync_push( const transaction_metadata_ptr& trx, fc::time_point deadline = fc::time_point::now() + fc::milliseconds(30) ); + transaction_trace_ptr sync_push( const transaction_metadata_ptr& trx, fc::time_point deadline ); /** * Attempt to execute a specific transaction in our deferred trx database diff --git a/libraries/testing/tester.cpp b/libraries/testing/tester.cpp index a01d1d001a618a9fc69ce209b7d7d800b82ee526..dca4c6ed8f960696b3520e92527b0370de2b9936 100644 --- a/libraries/testing/tester.cpp +++ b/libraries/testing/tester.cpp @@ -112,9 +112,9 @@ namespace eosio { namespace testing { if( !skip_pending_trxs ) { //wlog( "pushing all input transactions in waiting queue" ); - while( control->push_next_unapplied_transaction() ); + while( control->push_next_unapplied_transaction( fc::time_point::maximum() ) ); //wlog( "pushing all available deferred transactions" ); - while( control->push_next_scheduled_transaction() ); + while( control->push_next_scheduled_transaction( fc::time_point::maximum() ) ); } control->finalize_block(); diff --git a/plugins/chain_plugin/chain_plugin.cpp b/plugins/chain_plugin/chain_plugin.cpp index bb38b04ee4996035f05e915dba9c9c4dcee51bb4..180274f6b853ba8120819b2aba41270d2b811484 100644 --- a/plugins/chain_plugin/chain_plugin.cpp +++ b/plugins/chain_plugin/chain_plugin.cpp @@ -290,7 +290,7 @@ void chain_plugin::accept_block(const signed_block_ptr& block ) { } void chain_plugin::accept_transaction(const packed_transaction& trx) { - chain().push_transaction( std::make_shared(trx) ); + chain().push_transaction( std::make_shared(trx), get_transaction_deadline() ); } bool chain_plugin::block_is_on_preferred_chain(const block_id_type& block_id) { @@ -306,9 +306,13 @@ controller::config& chain_plugin::chain_config() { controller& chain_plugin::chain() { return *my->chain; } const controller& chain_plugin::chain() const { return *my->chain; } - void chain_plugin::get_chain_id (chain_id_type &cid)const { - memcpy (cid.data(), my->chain_id.data(), cid.data_size()); - } +void chain_plugin::get_chain_id(chain_id_type &cid)const { + memcpy(cid.data(), my->chain_id.data(), cid.data_size()); +} + +fc::time_point chain_plugin::get_transaction_deadline()const { + return fc::time_point::now() + fc::milliseconds(my->max_pending_transaction_time_ms); +} namespace chain_apis { @@ -464,13 +468,18 @@ read_write::push_block_results read_write::push_block(const read_write::push_blo } read_write::push_transaction_results read_write::push_transaction(const read_write::push_transaction_params& params) { + chain_plugin* chain_plug = app().find_plugin(); + FC_ASSERT( chain_plug != nullptr, "Unable to retrieve chain_plugin" ); + packed_transaction pretty_input; auto resolver = make_resolver(this); try { abi_serializer::from_variant(params, pretty_input, resolver); } EOS_RETHROW_EXCEPTIONS(chain::packed_transaction_type_exception, "Invalid packed transaction") - auto trx_trace_ptr = db.sync_push( std::make_shared(move(pretty_input)) ); + auto trx_trace_ptr = db.sync_push( + std::make_shared(move(pretty_input)), + chain_plug->get_transaction_deadline() ); fc::variant pretty_output = db.to_variant_with_abi( *trx_trace_ptr );; //abi_serializer::to_variant(*trx_trace_ptr, pretty_output, resolver); diff --git a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp index b7012e8756cd2727ad672c8ee8bacaace5ba323b..f1630949d6e9c1d9b385906861d02bee554febac 100644 --- a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp +++ b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp @@ -354,7 +354,10 @@ public: // Only call this after plugin_startup()! const controller& chain() const; - void get_chain_id (chain::chain_id_type &cid) const; + // Calculate deadline for controller push_transaction + fc::time_point get_transaction_deadline()const; + + void get_chain_id(chain::chain_id_type& cid) const; private: unique_ptr my; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 080ca25e4dc92b62afcd99d617f137322c776d22..9c35500468dc77310a879ea5c4bc5a8e78a93085 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,4 +1,3 @@ -#file(GLOB COMMON_SOURCES "common/*.cpp") find_package( Gperftools QUIET ) if( GPERFTOOLS_FOUND ) @@ -12,24 +11,17 @@ link_directories(${LLVM_LIBRARY_DIR}) set( CMAKE_CXX_STANDARD 14 ) -include_directories("${CMAKE_BINARY_DIR}/contracts") -include_directories("${CMAKE_SOURCE_DIR}/contracts") 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) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.hpp.in ${CMAKE_CURRENT_SOURCE_DIR}/config.hpp ESCAPE_QUOTES) -# Temporarily remove some tests to get chain_test to compile -#file(GLOB UNIT_TESTS "tests/wallet_tests.cpp" "chain_tests/*.cpp" "api_tests/*.cpp" "wasm_tests/*.cpp") -file(GLOB UNIT_TESTS "tests/wallet_tests.cpp") +file(GLOB UNIT_TESTS "wallet_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} ) +add_executable( plugin_test ${UNIT_TESTS} ${WASM_UNIT_TESTS} main.cpp) +target_link_libraries( plugin_test eosio_testing eosio_chain chainbase eos_utilities chain_plugin wallet_plugin abi_generator fc ${PLATFORM_SPECIFIC_LIBS} ) -target_include_directories( chain_test PUBLIC ${CMAKE_BINARY_DIR}/contracts ${CMAKE_CURRENT_BINARY_DIR}/tests/contracts ) -target_include_directories( chain_test PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/wasm_tests ) -target_include_directories( chain_test PUBLIC ${CMAKE_SOURCE_DIR}/plugins/net_plugin/include ) -target_include_directories( chain_test PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ) -add_dependencies(chain_test asserter test_api test_api_mem test_api_db test_api_multi_index exchange proxy identity identity_test stltest infinite eosio.system eosio.token eosio.bios test.inline multi_index_test noop dice eosio.msig) +target_include_directories( plugin_test PUBLIC ${CMAKE_SOURCE_DIR}/plugins/net_plugin/include ) +add_dependencies(plugin_test asserter test_api test_api_mem test_api_db test_api_multi_index exchange proxy identity identity_test stltest infinite eosio.system eosio.token eosio.bios test.inline multi_index_test noop dice eosio.msig) # configure_file(${CMAKE_CURRENT_SOURCE_DIR}/p2p_tests/sync/test.sh ${CMAKE_CURRENT_BINARY_DIR}/p2p_tests/sync/test.sh COPYONLY) @@ -44,10 +36,8 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/nodeos_run_test.py ${CMAKE_CURRENT_BI configure_file(${CMAKE_CURRENT_SOURCE_DIR}/nodeos_run_remote_test.py ${CMAKE_CURRENT_BINARY_DIR}/nodeos_run_remote_test.py COPYONLY) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/consensus-validation-malicious-producers.py ${CMAKE_CURRENT_BINARY_DIR}/consensus-validation-malicious-producers.py COPYONLY) -#Manually run chain_test for all supported runtimes -#To run chain_test with all log from blockchain displayed, put --verbose after --, i.e. chain_test -- --verbose -# TODO removed on slim: #add_test(NAME chain_test_binaryen COMMAND chain_test --report_level=detailed --color_output -- --binaryen) -# TODO removed on slim: add_test(NAME chain_test_wavm COMMAND chain_test --report_level=detailed --color_output --catch_system_errors=no -- --wavm) +#To run plugin_test with all log from blockchain displayed, put --verbose after --, i.e. plugin_test -- --verbose +add_test(NAME plugin_test COMMAND plugin_test --report_level=detailed --color_output) # TODO removed on slim: add_test(NAME nodeos_run_test COMMAND tests/nodeos_run_test.py -v --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) # TODO removed on slim: add_test(NAME nodeos_run_remote_test COMMAND tests/nodeos_run_remote_test.py -v --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) # TODO removed on slim: add_test(NAME p2p_dawn515_test COMMAND tests/p2p_tests/dawn_515/test.sh WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) @@ -83,7 +73,7 @@ if(ENABLE_COVERAGE_TESTING) endif() # NOT GENHTML_PATH # no spaces allowed within tests list - set(ctest_tests 'chain_test_binaryen|chain_test_wavm|p2p_dawn515_test|nodeos_run_test|distributed-transactions-test|restart-scenarios-test_resync') + set(ctest_tests 'plugin_test|p2p_dawn515_test|nodeos_run_test|distributed-transactions-test|restart-scenarios-test_resync') set(ctest_exclude_tests 'nodeos_run_remote_test|nodeos_run_test-mongodb|distributed-transactions-remote-test|restart-scenarios-test_replay') # Setup target diff --git a/tests/common/database_fixture.cpp b/tests/common/database_fixture.cpp deleted file mode 100644 index 4d79660896131b462ad4748c7ca50b5fc4465262..0000000000000000000000000000000000000000 --- a/tests/common/database_fixture.cpp +++ /dev/null @@ -1,266 +0,0 @@ -/** - * @file - * @copyright defined in eos/LICENSE.txt - */ -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include "database_fixture.hpp" - -uint32_t EOS_TESTING_GENESIS_TIMESTAMP = 1431700005; - -namespace eosio { namespace chain { - -testing_fixture::testing_fixture() { - default_genesis_state.initial_timestamp = fc::time_point_sec(EOS_TESTING_GENESIS_TIMESTAMP); - for (int i = 0; i < config::blocks_per_round; ++i) { - auto name = std::string("inita"); name.back()+=i; - auto private_key = fc::ecc::private_key::regenerate(fc::sha256::hash(name)); - public_key_type public_key = private_key.get_public_key(); - default_genesis_state.initial_accounts.emplace_back(name, 0, 100000, public_key, public_key); - store_private_key(private_key); - - private_key = fc::ecc::private_key::regenerate(fc::sha256::hash(name + ".producer")); - public_key = private_key.get_public_key(); - default_genesis_state.initial_producers.emplace_back(name, public_key); - store_private_key(private_key); - } -} - -fc::path testing_fixture::get_temp_dir(std::string id) { - if (id.empty()) { - anonymous_temp_dirs.emplace_back(); - return anonymous_temp_dirs.back().path(); - } - if (named_temp_dirs.count(id)) - return named_temp_dirs[id].path(); - return named_temp_dirs.emplace(std::make_pair(id, fc::temp_directory())).first->second.path(); -} - -const native_contract::genesis_state_type& testing_fixture::genesis_state() const { - return default_genesis_state; -} - -native_contract::genesis_state_type& testing_fixture::genesis_state() { - return default_genesis_state; -} - -void testing_fixture::store_private_key(const private_key_type& key) { - key_ring[key.get_public_key()] = key; -} - -private_key_type testing_fixture::get_private_key(const public_key_type& public_key) const { - auto itr = key_ring.find(public_key); - EOS_ASSERT(itr != key_ring.end(), missing_key_exception, - "Private key corresponding to public key ${k} not known.", ("k", public_key)); - return itr->second; -} - -flat_set testing_fixture::available_keys() const { - auto range = key_ring | boost::adaptors::map_keys; - return {range.begin(), range.end()}; -} - -testing_blockchain::testing_blockchain(chainbase::database& db, fork_database& fork_db, block_log& blocklog, - chain_initializer_interface& initializer, testing_fixture& fixture) - : chain_controller(db, fork_db, blocklog, initializer, native_contract::make_administrator(), - ::eosio::chain_plugin::default_transaction_execution_time * 1000, - ::eosio::chain_plugin::default_received_block_transaction_execution_time * 1000, - ::eosio::chain_plugin::default_create_block_transaction_execution_time * 1000, - chain_controller::txn_msg_limits{}), - db(db), - fixture(fixture) {} - -testing_blockchain::testing_blockchain(chainbase::database& db, fork_database& fork_db, block_log& blocklog, - chain_initializer_interface& initializer, testing_fixture& fixture, - uint32_t transaction_execution_time_msec, - uint32_t received_block_execution_time_msec, - uint32_t create_block_execution_time_msec, - const chain_controller::txn_msg_limits& rate_limits) - : chain_controller(db, fork_db, blocklog, initializer, native_contract::make_administrator(), - transaction_execution_time_msec * 1000, - received_block_execution_time_msec * 1000, - create_block_execution_time_msec * 1000, - rate_limits), - db(db), - fixture(fixture) {} - -void testing_blockchain::produce_blocks(uint32_t count, uint32_t blocks_to_miss) { - if (count == 0) - return; - - for (int i = 0; i < count; ++i) { - auto slot = blocks_to_miss + 1; - auto producer = get_producer(get_scheduled_producer(slot)); - auto private_key = fixture.get_private_key(producer.signing_key); - generate_block(get_slot_time(slot), producer.owner, private_key, block_schedule::in_single_thread, - chain_controller::created_block | (skip_trx_sigs? chain_controller::skip_transaction_signatures : 0)); - } -} - -void testing_blockchain::sync_with(testing_blockchain& other) { - // Already in sync? - if (head_block_id() == other.head_block_id()) - return; - // If other has a longer chain than we do, sync it to us first - if (head_block_num() < other.head_block_num()) - return other.sync_with(*this); - - auto sync_dbs = [](testing_blockchain& a, testing_blockchain& b) { - for (int i = 1; i <= a.head_block_num(); ++i) { - auto block = a.fetch_block_by_number(i); - if (block && !b.is_known_block(block->id())) { - b.push_block(*block, chain_controller::validation_steps::created_block); - } - } - }; - - sync_dbs(*this, other); - sync_dbs(other, *this); -} - -types::asset testing_blockchain::get_liquid_balance(const types::account_name& account) { - return get_database().get(account).balance; -} - -types::asset testing_blockchain::get_staked_balance(const types::account_name& account) { - return get_database().get(account).staked_balance; -} - -types::asset testing_blockchain::get_unstaking_balance(const types::account_name& account) { - return get_database().get(account).unstaking_balance; -} - -std::set testing_blockchain::get_approved_producers(const types::account_name& account) { - const auto& sbo = get_database().get(account); - if (sbo.producer_votes.contains()) { - auto range = sbo.producer_votes.get().range(); - return {range.begin(), range.end()}; - } - return {}; -} - -types::public_key testing_blockchain::get_block_signing_key(const types::account_name& producerName) { - return get_database().get(producerName).signing_key; -} - -void testing_blockchain::sign_transaction(signed_transaction& trx) const { - auto keys = get_required_keys(trx, fixture.available_keys()); - for (const auto& k : keys) { - // TODO: Use a real chain_id here - trx.sign(fixture.get_private_key(k), chain_id_type{}); - } -} - -fc::optional testing_blockchain::push_transaction(signed_transaction trx, uint32_t skip_flags) { - if (skip_trx_sigs) - skip_flags |= chain_controller::skip_transaction_signatures; - - if (auto_sign_trxs) { - sign_transaction(trx); - } - - if (hold_for_review) { - review_storage = std::make_pair(trx, skip_flags); - return {}; - } - return chain_controller::push_transaction(trx, skip_flags | chain_controller::pushed_transaction); -} - -vector testing_blockchain::assemble_wast( const std::string& wast ) { - // std::cout << "\n" << wast << "\n"; - IR::Module module; - std::vector parseErrors; - WAST::parseModule(wast.c_str(),wast.size(),module,parseErrors); - if(parseErrors.size()) - { - // Print any parse errors; - std::cerr << "Error parsing WebAssembly text file:" << std::endl; - for(auto& error : parseErrors) - { - std::cerr << ":" << error.locus.describe() << ": " << error.message.c_str() << std::endl; - std::cerr << error.locus.sourceLine << std::endl; - std::cerr << std::setw(error.locus.column(8)) << "^" << std::endl; - } - FC_ASSERT( !"error parsing wast" ); - } - - try - { - // Serialize the WebAssembly module. - Serialization::ArrayOutputStream stream; - WASM::serialize(stream,module); - return stream.getBytes(); - } - catch(Serialization::FatalSerializationException exception) - { - std::cerr << "Error serializing WebAssembly binary file:" << std::endl; - std::cerr << exception.message << std::endl; - throw; - } -} - - - -void testing_network::connect_blockchain(testing_blockchain& new_database) { - if (blockchains.count(&new_database)) - return; - - // If the network isn't empty, sync the new database with one of the old ones. The old ones are already in sync with - // each other, so just grab one arbitrarily. The old databases are connected to the propagation signals, so when one - // of them gets synced, it will propagate blocks to the others as well. - if (!blockchains.empty()) { - blockchains.begin()->first->sync_with(new_database); - } - - // The new database is now in sync with any old ones; go ahead and connect the propagation signal. - blockchains[&new_database] = new_database.applied_block.connect([this, &new_database](const signed_block& block) { - propagate_block(block, new_database); - }); -} - -void testing_network::disconnect_database(testing_blockchain& leaving_database) { - blockchains.erase(&leaving_database); -} - -void testing_network::disconnect_all() { - blockchains.clear(); -} - -void testing_network::propagate_block(const signed_block& block, const testing_blockchain& skip_db) { - for (const auto& pair : blockchains) { - if (pair.first == &skip_db) continue; - boost::signals2::shared_connection_block blocker(pair.second); - pair.first->push_block(block, chain_controller::created_block); - } -} - -} } // eosio::chain diff --git a/tests/tests/config.hpp.in b/tests/config.hpp.in similarity index 100% rename from tests/tests/config.hpp.in rename to tests/config.hpp.in diff --git a/tests/common/main.cpp b/tests/main.cpp similarity index 100% rename from tests/common/main.cpp rename to tests/main.cpp diff --git a/tests/tests/wallet_tests.cpp b/tests/wallet_tests.cpp similarity index 100% rename from tests/tests/wallet_tests.cpp rename to tests/wallet_tests.cpp diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index df3b90691d58bccf9d057758af0e73b21ce12bfc..7def41555eafa5a6077456c5d3d742a1e63fd6aa 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -29,8 +29,8 @@ target_include_directories( unit_test PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/wasm_te target_include_directories( unit_test PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ) add_dependencies(unit_test asserter test_api test_api_mem test_api_db test_api_multi_index exchange eosio.token proxy identity identity_test stltest infinite eosio.system eosio.token eosio.bios test.inline multi_index_test noop dice eosio.msig) -#Manually run chain_test for all supported runtimes -#To run chain_test with all log from blockchain displayed, put --verbose after --, i.e. chain_test -- --verbose +#Manually run unit_test for all supported runtimes +#To run unit_test with all log from blockchain displayed, put --verbose after --, i.e. unit_test -- --verbose add_test(NAME unit_test_binaryen COMMAND unit_test -t \!auth_tests/linkauth_special -t \!eosio_system_tests/* -t \!delay_tests/* --report_level=detailed --color_output -- --binaryen) add_test(NAME unit_test_wavm COMMAND unit_test -t \!auth_tests/linkauth_special -t \!eosio_system_tests/* -t \!delay_tests/* --report_level=detailed --color_output --catch_system_errors=no -- --wavm)