From 83f490c133639b93d8d823048a326da75d629196 Mon Sep 17 00:00:00 2001 From: John Jones Date: Mon, 11 Feb 2019 15:05:25 -0500 Subject: [PATCH 1/6] test helpers for node connectivity --- tests/CMakeLists.txt | 2 +- tests/common/application_helper.cpp | 103 ++++++++++++++++++++++++++++ tests/common/application_helper.hpp | 23 +++++++ tests/common/genesis_file_util.hpp | 2 + 4 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 tests/common/application_helper.cpp create mode 100644 tests/common/application_helper.hpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b863c6347e..993b348180 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -16,7 +16,7 @@ endif(MSVC) file(GLOB PERFORMANCE_TESTS "performance/*.cpp") add_executable( performance_test ${COMMON_SOURCES} ${PERFORMANCE_TESTS} ) -target_link_libraries( performance_test graphene_chain graphene_app graphene_account_history graphene_elasticsearch graphene_es_objects graphene_egenesis_none fc ${PLATFORM_SPECIFIC_LIBS} ) +target_link_libraries( performance_test graphene_chain graphene_app graphene_witness graphene_account_history graphene_elasticsearch graphene_es_objects graphene_egenesis_none fc ${PLATFORM_SPECIFIC_LIBS} ) file(GLOB BENCH_MARKS "benchmarks/*.cpp") add_executable( chain_bench ${COMMON_SOURCES} ${BENCH_MARKS} ) diff --git a/tests/common/application_helper.cpp b/tests/common/application_helper.cpp new file mode 100644 index 0000000000..4082696caa --- /dev/null +++ b/tests/common/application_helper.cpp @@ -0,0 +1,103 @@ +#include "application_helper.hpp" +#include "genesis_file_util.hpp" +#include +#include +#include +#include +#include + +#ifdef _WIN32 + #ifndef _WIN32_WINNT + #define _WIN32_WINNT 0x0501 + #endif + #include + #include +int sockInit(void) +{ + WSADATA wsa_data; + return WSAStartup(MAKEWORD(1,1), &wsa_data); +} +int sockQuit(void) +{ + return WSACleanup(); +} +#else + #include + #include + #include +#endif + +#include + +namespace graphene { namespace test { + +application_runner::application_runner() +{ + _app = std::make_shared(); + + _app->register_plugin(true); + _app->register_plugin< graphene::market_history::market_history_plugin >(true); + _app->register_plugin< graphene::witness_plugin::witness_plugin >(true); + _app->register_plugin< graphene::grouped_orders::grouped_orders_plugin>(true); + _app->startup_plugins(); + boost::program_options::variables_map cfg; +#ifdef _WIN32 + sockInit(); +#endif + server_port_number = get_available_port(); + cfg.emplace( + "rpc-endpoint", + boost::program_options::variable_value(std::string("127.0.0.1:" + std::to_string(server_port_number)), false) + ); + cfg.emplace("genesis-json", boost::program_options::variable_value(create_genesis_file(_dir), false)); + cfg.emplace("seed-nodes", boost::program_options::variable_value(std::string("[]"), false)); + _app->initialize(_dir.path(), cfg); + + _app->initialize_plugins(cfg); + _app->startup_plugins(); + + _app->startup(); + fc::usleep(fc::milliseconds(500)); +} + +const graphene::app::application& application_runner::get_app() +{ + return *_app; +} + +void application_runner::add_seed_node(int remote_port) +{ + // add seed node + std::string node = "127.0.0.1:" + std::to_string(remote_port); + std::vector endpoints = resolve_string_to_ip_endpoints(node); + for(const auto& ep : endpoints) + _app->p2p_node()->add_node(ep); +} + +////// +/// @brief attempt to find an available port on localhost +/// @returns an available port number, or -1 on error +///// +int application_runner::get_available_port() +{ + struct sockaddr_in sin; + int socket_fd = socket(AF_INET, SOCK_STREAM, 0); + if (socket_fd == -1) + return -1; + sin.sin_family = AF_INET; + sin.sin_port = 0; + sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + if (::bind(socket_fd, (struct sockaddr*)&sin, sizeof(struct sockaddr_in)) == -1) + return -1; + socklen_t len = sizeof(sin); + if (getsockname(socket_fd, (struct sockaddr *)&sin, &len) == -1) + return -1; +#ifdef _WIN32 + closesocket(socket_fd); +#else + close(socket_fd); +#endif + return ntohs(sin.sin_port); +} + +}} diff --git a/tests/common/application_helper.hpp b/tests/common/application_helper.hpp new file mode 100644 index 0000000000..3d2d7366c8 --- /dev/null +++ b/tests/common/application_helper.hpp @@ -0,0 +1,23 @@ +#pragma once +#include +#include + +namespace graphene { namespace test { + +/** + * Handles creating a running node + */ +class application_runner +{ + public: + application_runner(); + int server_port_number; + const graphene::app::application& get_app(); + void add_seed_node(int remote_port); + private: + std::shared_ptr _app; + fc::temp_directory _dir; + static int get_available_port(); +}; + +}} diff --git a/tests/common/genesis_file_util.hpp b/tests/common/genesis_file_util.hpp index a87d9585af..24e6cbea5c 100644 --- a/tests/common/genesis_file_util.hpp +++ b/tests/common/genesis_file_util.hpp @@ -1,5 +1,7 @@ #pragma once +#include + ///////// /// @brief forward declaration, using as a hack to generate a genesis.json file /// for testing From 38f3dab15eb325b854d3dd1a78e255fdff57d9b9 Mon Sep 17 00:00:00 2001 From: jmjatlanta Date: Tue, 12 Feb 2019 10:19:33 -0500 Subject: [PATCH 2/6] ability to add node after starting --- libraries/app/application.cpp | 65 +++++++++---------- libraries/app/application_impl.hxx | 2 - .../app/include/graphene/app/application.hpp | 1 + tests/CMakeLists.txt | 4 +- tests/common/application_helper.cpp | 14 ++-- tests/common/application_helper.hpp | 65 ++++++++++++++++++- tests/tests/block_tests.cpp | 11 ++++ 7 files changed, 115 insertions(+), 47 deletions(-) diff --git a/libraries/app/application.cpp b/libraries/app/application.cpp index f6607a5e2f..28b30a721b 100644 --- a/libraries/app/application.cpp +++ b/libraries/app/application.cpp @@ -128,7 +128,7 @@ void application_impl::reset_p2p_node(const fc::path& data_dir) for( const string& endpoint_string : seeds ) { try { - std::vector endpoints = resolve_string_to_ip_endpoints(endpoint_string); + std::vector endpoints = application::resolve_string_to_ip_endpoints(endpoint_string); for (const fc::ip::endpoint& endpoint : endpoints) { ilog("Adding seed node ${endpoint}", ("endpoint", endpoint)); @@ -149,7 +149,7 @@ void application_impl::reset_p2p_node(const fc::path& data_dir) for( const string& endpoint_string : seeds ) { try { - std::vector endpoints = resolve_string_to_ip_endpoints(endpoint_string); + std::vector endpoints = application::resolve_string_to_ip_endpoints(endpoint_string); for (const fc::ip::endpoint& endpoint : endpoints) { ilog("Adding seed node ${endpoint}", ("endpoint", endpoint)); @@ -188,7 +188,7 @@ void application_impl::reset_p2p_node(const fc::path& data_dir) for( const string& endpoint_string : seeds ) { try { - std::vector endpoints = resolve_string_to_ip_endpoints(endpoint_string); + std::vector endpoints = application::resolve_string_to_ip_endpoints(endpoint_string); for (const fc::ip::endpoint& endpoint : endpoints) { ilog("Adding seed node ${endpoint}", ("endpoint", endpoint)); @@ -214,36 +214,6 @@ void application_impl::reset_p2p_node(const fc::path& data_dir) std::vector()); } FC_CAPTURE_AND_RETHROW() } -std::vector application_impl::resolve_string_to_ip_endpoints(const std::string& endpoint_string) -{ - try - { - string::size_type colon_pos = endpoint_string.find(':'); - if (colon_pos == std::string::npos) - FC_THROW("Missing required port number in endpoint string \"${endpoint_string}\"", - ("endpoint_string", endpoint_string)); - std::string port_string = endpoint_string.substr(colon_pos + 1); - try - { - uint16_t port = boost::lexical_cast(port_string); - - std::string hostname = endpoint_string.substr(0, colon_pos); - std::vector endpoints = fc::resolve(hostname, port); - if (endpoints.empty()) - FC_THROW_EXCEPTION( fc::unknown_host_exception, - "The host name can not be resolved: ${hostname}", - ("hostname", hostname) ); - return endpoints; - } - catch (const boost::bad_lexical_cast&) - { - FC_THROW("Bad port: ${port}", ("port", port_string)); - } - } - FC_CAPTURE_AND_RETHROW((endpoint_string)) -} - - void application_impl::new_connection( const fc::http::websocket_connection_ptr& c ) { auto wsc = std::make_shared(*c, GRAPHENE_NET_MAX_NESTED_OBJECTS); @@ -1100,5 +1070,34 @@ const application_options& application::get_options() return my->_app_options; } +std::vector application::resolve_string_to_ip_endpoints(const std::string& endpoint_string) +{ + try + { + string::size_type colon_pos = endpoint_string.find(':'); + if (colon_pos == std::string::npos) + FC_THROW("Missing required port number in endpoint string \"${endpoint_string}\"", + ("endpoint_string", endpoint_string)); + std::string port_string = endpoint_string.substr(colon_pos + 1); + try + { + uint16_t port = boost::lexical_cast(port_string); + + std::string hostname = endpoint_string.substr(0, colon_pos); + std::vector endpoints = fc::resolve(hostname, port); + if (endpoints.empty()) + FC_THROW_EXCEPTION( fc::unknown_host_exception, + "The host name can not be resolved: ${hostname}", + ("hostname", hostname) ); + return endpoints; + } + catch (const boost::bad_lexical_cast&) + { + FC_THROW("Bad port: ${port}", ("port", port_string)); + } + } + FC_CAPTURE_AND_RETHROW((endpoint_string)) +} + // namespace detail } } diff --git a/libraries/app/application_impl.hxx b/libraries/app/application_impl.hxx index 2d5d48080d..831b92bc08 100644 --- a/libraries/app/application_impl.hxx +++ b/libraries/app/application_impl.hxx @@ -22,8 +22,6 @@ class application_impl : public net::node_delegate void reset_p2p_node(const fc::path& data_dir); - std::vector resolve_string_to_ip_endpoints(const std::string& endpoint_string); - void new_connection( const fc::http::websocket_connection_ptr& c ); void reset_websocket_server(); diff --git a/libraries/app/include/graphene/app/application.hpp b/libraries/app/include/graphene/app/application.hpp index 66a73f3999..6b1627249d 100644 --- a/libraries/app/include/graphene/app/application.hpp +++ b/libraries/app/include/graphene/app/application.hpp @@ -56,6 +56,7 @@ namespace graphene { namespace app { void shutdown(); void startup_plugins(); void shutdown_plugins(); + static std::vector resolve_string_to_ip_endpoints(const std::string& endpoint_string); template std::shared_ptr register_plugin(bool auto_load = false) { diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 993b348180..c8cc3934a1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -20,7 +20,7 @@ target_link_libraries( performance_test graphene_chain graphene_app graphene_wit file(GLOB BENCH_MARKS "benchmarks/*.cpp") add_executable( chain_bench ${COMMON_SOURCES} ${BENCH_MARKS} ) -target_link_libraries( chain_bench graphene_chain graphene_app graphene_account_history graphene_elasticsearch graphene_es_objects graphene_egenesis_none fc ${PLATFORM_SPECIFIC_LIBS} ) +target_link_libraries( chain_bench graphene_chain graphene_witness graphene_app graphene_account_history graphene_elasticsearch graphene_es_objects graphene_egenesis_none fc ${PLATFORM_SPECIFIC_LIBS} ) file(GLOB APP_SOURCES "app/*.cpp") add_executable( app_test ${APP_SOURCES} ) @@ -38,6 +38,6 @@ endif(MSVC) file(GLOB ES_SOURCES "elasticsearch/*.cpp") add_executable( es_test ${COMMON_SOURCES} ${ES_SOURCES} ) -target_link_libraries( es_test graphene_chain graphene_app graphene_account_history graphene_elasticsearch graphene_es_objects graphene_egenesis_none fc ${PLATFORM_SPECIFIC_LIBS} ) +target_link_libraries( es_test graphene_chain graphene_app graphene_witness graphene_account_history graphene_elasticsearch graphene_es_objects graphene_egenesis_none fc ${PLATFORM_SPECIFIC_LIBS} ) add_subdirectory( generate_empty_blocks ) diff --git a/tests/common/application_helper.cpp b/tests/common/application_helper.cpp index 4082696caa..e70c21509f 100644 --- a/tests/common/application_helper.cpp +++ b/tests/common/application_helper.cpp @@ -35,10 +35,10 @@ application_runner::application_runner() { _app = std::make_shared(); - _app->register_plugin(true); + _app->register_plugin< graphene::account_history::account_history_plugin >(true); _app->register_plugin< graphene::market_history::market_history_plugin >(true); _app->register_plugin< graphene::witness_plugin::witness_plugin >(true); - _app->register_plugin< graphene::grouped_orders::grouped_orders_plugin>(true); + _app->register_plugin< graphene::grouped_orders::grouped_orders_plugin >(true); _app->startup_plugins(); boost::program_options::variables_map cfg; #ifdef _WIN32 @@ -60,16 +60,14 @@ application_runner::application_runner() fc::usleep(fc::milliseconds(500)); } -const graphene::app::application& application_runner::get_app() +std::shared_ptr application_runner::get_app() { - return *_app; + return _app; } -void application_runner::add_seed_node(int remote_port) +void application_runner::add_seed_node(std::string addr) { - // add seed node - std::string node = "127.0.0.1:" + std::to_string(remote_port); - std::vector endpoints = resolve_string_to_ip_endpoints(node); + std::vector endpoints = graphene::app::application::resolve_string_to_ip_endpoints(addr); for(const auto& ep : endpoints) _app->p2p_node()->add_node(ep); } diff --git a/tests/common/application_helper.hpp b/tests/common/application_helper.hpp index 3d2d7366c8..c7d119af69 100644 --- a/tests/common/application_helper.hpp +++ b/tests/common/application_helper.hpp @@ -1,6 +1,12 @@ #pragma once #include #include +#include + +#include +#include +#include +#include namespace graphene { namespace test { @@ -12,12 +18,67 @@ class application_runner public: application_runner(); int server_port_number; - const graphene::app::application& get_app(); - void add_seed_node(int remote_port); + std::shared_ptr get_app(); + void add_seed_node(std::string addr); private: std::shared_ptr _app; fc::temp_directory _dir; static int get_available_port(); }; +/////////// +/// @brief a class to make connecting to the application server easier +/////////// +class client_connection +{ +public: + ///////// + // constructor + ///////// + client_connection( + std::shared_ptr app, + const int server_port_number, + const fc::temp_directory& data_dir = fc::temp_directory() + ) + { + wallet_data.chain_id = app->chain_database()->get_chain_id(); + wallet_data.ws_server = "ws://127.0.0.1:" + std::to_string(server_port_number); + wallet_data.ws_user = ""; + wallet_data.ws_password = ""; + websocket_connection = websocket_client.connect( wallet_data.ws_server ); + + api_connection = std::make_shared(*websocket_connection, GRAPHENE_MAX_NESTED_OBJECTS); + + remote_login_api = api_connection->get_remote_api< graphene::app::login_api >(1); + remote_login_api->login( wallet_data.ws_user, wallet_data.ws_password ); + + + wallet_api_ptr = std::make_shared(wallet_data, remote_login_api); + wallet_filename = data_dir.path().generic_string() + "/wallet.json"; + wallet_api_ptr->set_wallet_filename(wallet_filename); + + wallet_api = fc::api(wallet_api_ptr); + + wallet_cli = std::make_shared(GRAPHENE_MAX_NESTED_OBJECTS); + for( auto& name_formatter : wallet_api_ptr->get_result_formatters() ) + wallet_cli->format_result( name_formatter.first, name_formatter.second ); + + boost::signals2::scoped_connection closed_connection(websocket_connection->closed.connect([=]{ + std::cerr << "Server has disconnected us.\n"; + wallet_cli->stop(); + })); + (void)(closed_connection); + } +public: + fc::http::websocket_client websocket_client; + graphene::wallet::wallet_data wallet_data; + fc::http::websocket_connection_ptr websocket_connection; + std::shared_ptr api_connection; + fc::api remote_login_api; + std::shared_ptr wallet_api_ptr; + fc::api wallet_api; + std::shared_ptr wallet_cli; + std::string wallet_filename; +}; + }} diff --git a/tests/tests/block_tests.cpp b/tests/tests/block_tests.cpp index 2c7eec7d05..fda282810c 100644 --- a/tests/tests/block_tests.cpp +++ b/tests/tests/block_tests.cpp @@ -41,6 +41,7 @@ #include #include "../common/database_fixture.hpp" +#include "../common/application_helper.hpp" using namespace graphene::chain; using namespace graphene::chain::test; @@ -778,6 +779,16 @@ BOOST_AUTO_TEST_CASE( tapos ) } } +BOOST_AUTO_TEST_CASE( big_block_p2p ) +{ + graphene::test::application_runner app1; + graphene::test::application_runner app2; + app2.add_seed_node( "localhost:" + std::to_string( app1.server_port_number ) ); + + // connect to a node, send a very big tx, and make sure the nodes stay connected to each other + graphene::test::client_connection conn1(app2.get_app(), app1.server_port_number); +} + BOOST_FIXTURE_TEST_CASE( optional_tapos, database_fixture ) { try From 5f35d8b756e7b151dbb28dc4a0d8065c2e0a1a18 Mon Sep 17 00:00:00 2001 From: John Jones Date: Tue, 12 Feb 2019 16:25:05 -0500 Subject: [PATCH 3/6] build a big transaction --- tests/common/application_helper.cpp | 44 +++++++++++-- tests/common/application_helper.hpp | 17 ++++- tests/tests/block_tests.cpp | 99 +++++++++++++++++++++++++++-- 3 files changed, 150 insertions(+), 10 deletions(-) diff --git a/tests/common/application_helper.cpp b/tests/common/application_helper.cpp index e70c21509f..577513a8db 100644 --- a/tests/common/application_helper.cpp +++ b/tests/common/application_helper.cpp @@ -40,17 +40,33 @@ application_runner::application_runner() _app->register_plugin< graphene::witness_plugin::witness_plugin >(true); _app->register_plugin< graphene::grouped_orders::grouped_orders_plugin >(true); _app->startup_plugins(); - boost::program_options::variables_map cfg; #ifdef _WIN32 sockInit(); #endif - server_port_number = get_available_port(); + rpc_port_number = get_available_port(); + p2p_port_number = get_available_port(); +} + +void application_runner::start() +{ + boost::program_options::variables_map cfg; cfg.emplace( "rpc-endpoint", - boost::program_options::variable_value(std::string("127.0.0.1:" + std::to_string(server_port_number)), false) + boost::program_options::variable_value(std::string("127.0.0.1:" + std::to_string(rpc_port_number)), false) ); + cfg.emplace( "p2p-endpoint", + boost::program_options::variable_value(std::string("127.0.0.1:" + std::to_string(p2p_port_number)), false)); cfg.emplace("genesis-json", boost::program_options::variable_value(create_genesis_file(_dir), false)); - cfg.emplace("seed-nodes", boost::program_options::variable_value(std::string("[]"), false)); + std::string seed_node_string = "["; + bool isFirst = true; + for(auto url : seed_nodes) + { + if (!isFirst) + seed_node_string += ", "; + seed_node_string += "\"" + url + "\""; + } + seed_node_string += "]"; + cfg.emplace("seed-nodes", boost::program_options::variable_value(seed_node_string, false)); _app->initialize(_dir.path(), cfg); _app->initialize_plugins(cfg); @@ -67,9 +83,29 @@ std::shared_ptr application_runner::get_app() void application_runner::add_seed_node(std::string addr) { + /* std::vector endpoints = graphene::app::application::resolve_string_to_ip_endpoints(addr); for(const auto& ep : endpoints) _app->p2p_node()->add_node(ep); + */ + seed_nodes.push_back(addr); +} + +uint32_t application_runner::get_connection_count() +{ + return _app->p2p_node()->get_connection_count(); +} + +bool application_runner::is_connected( std::string addr ) +{ + auto peer_statuses = _app->p2p_node()->get_connected_peers(); + for (auto status : peer_statuses ) + { + std::string host = status.host; + if ( host == addr ) + return true; + } + return false; } ////// diff --git a/tests/common/application_helper.hpp b/tests/common/application_helper.hpp index c7d119af69..89e5684fca 100644 --- a/tests/common/application_helper.hpp +++ b/tests/common/application_helper.hpp @@ -17,13 +17,19 @@ class application_runner { public: application_runner(); - int server_port_number; + void start(); + int rpc_port_number; + int p2p_port_number; std::shared_ptr get_app(); + // networking void add_seed_node(std::string addr); + bool is_connected( std::string addr ); + uint32_t get_connection_count(); private: std::shared_ptr _app; fc::temp_directory _dir; static int get_available_port(); + std::vector seed_nodes; }; /////////// @@ -56,6 +62,7 @@ class client_connection wallet_api_ptr = std::make_shared(wallet_data, remote_login_api); wallet_filename = data_dir.path().generic_string() + "/wallet.json"; wallet_api_ptr->set_wallet_filename(wallet_filename); + wallet_api_ptr->save_wallet_file(); wallet_api = fc::api(wallet_api_ptr); @@ -69,6 +76,14 @@ class client_connection })); (void)(closed_connection); } + bool import_nathan_account() + { + std::string wif_key = "5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"; + std::vector keys( { wif_key } ); + bool ret_val = wallet_api_ptr->import_key("nathan", wif_key); + wallet_api_ptr->import_balance("nathan", keys, true); + return ret_val; + } public: fc::http::websocket_client websocket_client; graphene::wallet::wallet_data wallet_data; diff --git a/tests/tests/block_tests.cpp b/tests/tests/block_tests.cpp index fda282810c..2b9bcae634 100644 --- a/tests/tests/block_tests.cpp +++ b/tests/tests/block_tests.cpp @@ -39,6 +39,7 @@ #include #include +#include #include "../common/database_fixture.hpp" #include "../common/application_helper.hpp" @@ -781,12 +782,100 @@ BOOST_AUTO_TEST_CASE( tapos ) BOOST_AUTO_TEST_CASE( big_block_p2p ) { - graphene::test::application_runner app1; - graphene::test::application_runner app2; - app2.add_seed_node( "localhost:" + std::to_string( app1.server_port_number ) ); + try + { + graphene::test::application_runner app1; + app1.start(); + std::string app1_p2p_address = "127.0.0.1:" + std::to_string( app1.p2p_port_number ); + + graphene::test::application_runner app2; + std::string app2_p2p_address = "127.0.0.1:" + std::to_string( app2.p2p_port_number ); + app2.add_seed_node( app1_p2p_address ); + app2.start(); + + BOOST_CHECK_EQUAL( app1.get_connection_count(), 1u ); + BOOST_CHECK( app2.is_connected( app1_p2p_address ) ); + BOOST_CHECK( app1.is_connected( app2_p2p_address ) ); + + // connect to a node, send a very big tx, and make sure the nodes stay connected to each other + fc::temp_directory wallet_dir; + graphene::test::client_connection conn1(app1.get_app(), app1.rpc_port_number, wallet_dir); + conn1.wallet_api_ptr->set_password("supersecret"); + conn1.wallet_api_ptr->unlock("supersecret"); + conn1.import_nathan_account(); + + graphene::chain::account_object nathan = conn1.wallet_api_ptr->get_account( "nathan" ); + + transfer_operation xfer_op; + xfer_op.from = nathan.id; + xfer_op.to = GRAPHENE_NULL_ACCOUNT; + xfer_op.amount = asset( 1000000 ); + + graphene::wallet::transaction_handle_type trx_handle = conn1.wallet_api_ptr->begin_builder_transaction(); + for(int i = 0; i < 100000; ++i) + { + conn1.wallet_api_ptr->add_operation_to_builder_transaction( trx_handle, xfer_op ); + xfer_op.amount.amount++; + } + conn1.wallet_api_ptr->set_fees_on_builder_transaction( trx_handle, GRAPHENE_SYMBOL ); + conn1.wallet_api_ptr->sign_builder_transaction( trx_handle, true ); + + /* + trx.operations.push_back( xfer_op ); + db1->current_fee_schedule().set_fee( trx.operations.back() ); + + trx.set_expiration( db1->get_slot_time( 10 ) ); + trx.sign( nathan_key, db1->get_chain_id() ); + trx.validate(); + + proposal_create_operation op; + op.expiration_time = time_point::now() + fc::minutes(30000); + op.review_period_seconds = 100; + + fc::optional asset_obj = conn1.wallet_api_ptr->get_asset("TEST"); + FC_ASSERT(asset_obj, "Could not find asset matching TEST"); + + account_object from_account = nathan; + account_object to_account = nathan; + account_id_type from_id = from_account.id; + account_id_type to_id = to_account.id; - // connect to a node, send a very big tx, and make sure the nodes stay connected to each other - graphene::test::client_connection conn1(app2.get_app(), app1.server_port_number); + op.fee_paying_account = nathan.id; + + transfer_operation xfer_op; + + xfer_op.from = from_id; + xfer_op.to = to_id; + xfer_op.amount = asset_obj->amount_from_string(amount); + xfer_op.fee = asset(2000000, asset_id_type(0)); + + signed_transaction& trx = conn1.wallet_api_ptr->get trx_handle. _builder_transactions[0]; + + trx.operations = {xfer_op}; + set_operation_fees( trx, _remote_db->get_global_properties().parameters.current_fees ); + + for (uint64_t j=0; j < 16; j++) { + op.proposed_ops.emplace_back( xfer_op ); + op.proposed_ops.emplace_back( op ); + } + + trx.operations = {op}; + set_operation_fees( trx, _remote_db->get_global_properties().parameters.current_fees ); + + for (uint64_t i=0; i < 17; i++) + { + fc::async([this, &trx, &broadcast](){ sign_transaction(trx, broadcast); }, "htd_attack"); + } + */ + + BOOST_CHECK( app2.is_connected( app1_p2p_address ) ); + BOOST_CHECK( app1.is_connected( app2_p2p_address ) ); + } + catch(fc::exception& e) + { + edump((e.to_detail_string())); + } + } BOOST_FIXTURE_TEST_CASE( optional_tapos, database_fixture ) From d0ce27ceb1a8e9e39c01aec51bddc40d65a67d2f Mon Sep 17 00:00:00 2001 From: John Jones Date: Thu, 14 Feb 2019 15:38:33 -0500 Subject: [PATCH 4/6] Test cleanup --- tests/common/application_helper.cpp | 5 +-- tests/tests/block_tests.cpp | 52 ++--------------------------- 2 files changed, 5 insertions(+), 52 deletions(-) diff --git a/tests/common/application_helper.cpp b/tests/common/application_helper.cpp index 577513a8db..6273108713 100644 --- a/tests/common/application_helper.cpp +++ b/tests/common/application_helper.cpp @@ -58,12 +58,13 @@ void application_runner::start() boost::program_options::variable_value(std::string("127.0.0.1:" + std::to_string(p2p_port_number)), false)); cfg.emplace("genesis-json", boost::program_options::variable_value(create_genesis_file(_dir), false)); std::string seed_node_string = "["; - bool isFirst = true; + bool needs_comma = false; for(auto url : seed_nodes) { - if (!isFirst) + if (needs_comma) seed_node_string += ", "; seed_node_string += "\"" + url + "\""; + needs_comma = true; } seed_node_string += "]"; cfg.emplace("seed-nodes", boost::program_options::variable_value(seed_node_string, false)); diff --git a/tests/tests/block_tests.cpp b/tests/tests/block_tests.cpp index 2b9bcae634..0dbbd9d494 100644 --- a/tests/tests/block_tests.cpp +++ b/tests/tests/block_tests.cpp @@ -809,10 +809,10 @@ BOOST_AUTO_TEST_CASE( big_block_p2p ) transfer_operation xfer_op; xfer_op.from = nathan.id; xfer_op.to = GRAPHENE_NULL_ACCOUNT; - xfer_op.amount = asset( 1000000 ); + xfer_op.amount = asset( 400000 ); graphene::wallet::transaction_handle_type trx_handle = conn1.wallet_api_ptr->begin_builder_transaction(); - for(int i = 0; i < 100000; ++i) + for(int i = 0; i < 50000; ++i) { conn1.wallet_api_ptr->add_operation_to_builder_transaction( trx_handle, xfer_op ); xfer_op.amount.amount++; @@ -820,54 +820,6 @@ BOOST_AUTO_TEST_CASE( big_block_p2p ) conn1.wallet_api_ptr->set_fees_on_builder_transaction( trx_handle, GRAPHENE_SYMBOL ); conn1.wallet_api_ptr->sign_builder_transaction( trx_handle, true ); - /* - trx.operations.push_back( xfer_op ); - db1->current_fee_schedule().set_fee( trx.operations.back() ); - - trx.set_expiration( db1->get_slot_time( 10 ) ); - trx.sign( nathan_key, db1->get_chain_id() ); - trx.validate(); - - proposal_create_operation op; - op.expiration_time = time_point::now() + fc::minutes(30000); - op.review_period_seconds = 100; - - fc::optional asset_obj = conn1.wallet_api_ptr->get_asset("TEST"); - FC_ASSERT(asset_obj, "Could not find asset matching TEST"); - - account_object from_account = nathan; - account_object to_account = nathan; - account_id_type from_id = from_account.id; - account_id_type to_id = to_account.id; - - op.fee_paying_account = nathan.id; - - transfer_operation xfer_op; - - xfer_op.from = from_id; - xfer_op.to = to_id; - xfer_op.amount = asset_obj->amount_from_string(amount); - xfer_op.fee = asset(2000000, asset_id_type(0)); - - signed_transaction& trx = conn1.wallet_api_ptr->get trx_handle. _builder_transactions[0]; - - trx.operations = {xfer_op}; - set_operation_fees( trx, _remote_db->get_global_properties().parameters.current_fees ); - - for (uint64_t j=0; j < 16; j++) { - op.proposed_ops.emplace_back( xfer_op ); - op.proposed_ops.emplace_back( op ); - } - - trx.operations = {op}; - set_operation_fees( trx, _remote_db->get_global_properties().parameters.current_fees ); - - for (uint64_t i=0; i < 17; i++) - { - fc::async([this, &trx, &broadcast](){ sign_transaction(trx, broadcast); }, "htd_attack"); - } - */ - BOOST_CHECK( app2.is_connected( app1_p2p_address ) ); BOOST_CHECK( app1.is_connected( app2_p2p_address ) ); } From 6e4ee9863d44fb0ccce80b085afc7d5f31eb5337 Mon Sep 17 00:00:00 2001 From: John Jones Date: Fri, 15 Feb 2019 07:52:14 -0500 Subject: [PATCH 5/6] Modify the test to match reported issue --- tests/tests/block_tests.cpp | 98 +++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/tests/tests/block_tests.cpp b/tests/tests/block_tests.cpp index 0dbbd9d494..df4f595966 100644 --- a/tests/tests/block_tests.cpp +++ b/tests/tests/block_tests.cpp @@ -830,6 +830,104 @@ BOOST_AUTO_TEST_CASE( big_block_p2p ) } +/***** + * Important: This test runs for a very long time. It SHOULD NOT be run + * as part of the normal test suite + * +BOOST_AUTO_TEST_CASE( big_transaction_p2p ) +{ + try + { + graphene::test::application_runner app1; + app1.start(); + std::string app1_p2p_address = "127.0.0.1:" + std::to_string( app1.p2p_port_number ); + + graphene::test::application_runner app2; + std::string app2_p2p_address = "127.0.0.1:" + std::to_string( app2.p2p_port_number ); + app2.add_seed_node( app1_p2p_address ); + app2.start(); + + BOOST_CHECK_EQUAL( app1.get_connection_count(), 1u ); + BOOST_CHECK( app2.is_connected( app1_p2p_address ) ); + BOOST_CHECK( app1.is_connected( app2_p2p_address ) ); + + // connect to a node + fc::temp_directory wallet_dir; + graphene::test::client_connection conn1(app1.get_app(), app1.rpc_port_number, wallet_dir); + conn1.wallet_api_ptr->set_password("supersecret"); + conn1.wallet_api_ptr->unlock("supersecret"); + conn1.import_nathan_account(); + + graphene::chain::account_object nathan = conn1.wallet_api_ptr->get_account( "nathan" ); + + // create a proposal + proposal_create_operation op; + op.expiration_time = time_point::now() + fc::minutes(30000); + op.review_period_seconds = 100; + + fc::optional asset_obj = conn1.wallet_api_ptr->get_asset(GRAPHENE_SYMBOL); + FC_ASSERT(asset_obj, "Could not find asset matching ${asset}", ("asset", GRAPHENE_SYMBOL)); + + account_object from_account = nathan; + account_object to_account = nathan; + account_id_type from_id = from_account.id; + account_id_type to_id = to_account.id; + + op.fee_paying_account = nathan.id; + + // create a transfer operation + transfer_operation xfer_op; + xfer_op.from = from_id; + xfer_op.to = to_id; + xfer_op.amount = asset_obj->amount_from_string("1000"); + xfer_op.fee = asset(2000000, asset_id_type(0)); + + // build a transaction + graphene::wallet::transaction_handle_type trx_handle = conn1.wallet_api_ptr->begin_builder_transaction(); + + // add the transfer operation to the transaction (nt sure why) + conn1.wallet_api_ptr->add_operation_to_builder_transaction(trx_handle, xfer_op); + conn1.wallet_api_ptr->set_fees_on_builder_transaction( trx_handle, GRAPHENE_SYMBOL ); + + // add 16 transfer operations and 16 proposal_create operations to the transaction + for (uint64_t j=0; j < 16; j++) { + op.proposed_ops.emplace_back( xfer_op ); + op.proposed_ops.emplace_back( op ); + } + + // remove the proposal_create operation added to the transaction earlier + // replace it with the large proposal_create operation + conn1.wallet_api_ptr->replace_operation_in_builder_transaction(trx_handle, 0, op); + + // calculate fees for the transaction + conn1.wallet_api_ptr->set_fees_on_builder_transaction( trx_handle, GRAPHENE_SYMBOL ); + + // send the transaction 17 times to the same server + auto func = [&trx_handle, &conn1](){ conn1.wallet_api_ptr->sign_builder_transaction(trx_handle, true); }; + std::vector< fc::future > futures; + for (uint64_t i=0; i < 17; i++) { + futures.push_back( fc::async(func, "htd_attack") ); + } + + // wait for everything to complete + for(auto f : futures) + { + f.wait(); + } + + // verify that the two nodes are still talking to each other + BOOST_CHECK( app2.is_connected( app1_p2p_address ) ); + BOOST_CHECK( app1.is_connected( app2_p2p_address ) ); + + } + catch(fc::exception& e) + { + edump((e.to_detail_string())); + } + +} +*/ + BOOST_FIXTURE_TEST_CASE( optional_tapos, database_fixture ) { try From 865ea35c889435b28eeb850e36db1f524086ff1b Mon Sep 17 00:00:00 2001 From: John Jones Date: Thu, 16 May 2019 10:32:53 -0500 Subject: [PATCH 6/6] remove another long-running test --- tests/tests/block_tests.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/tests/block_tests.cpp b/tests/tests/block_tests.cpp index df4f595966..6c063beaa0 100644 --- a/tests/tests/block_tests.cpp +++ b/tests/tests/block_tests.cpp @@ -780,6 +780,10 @@ BOOST_AUTO_TEST_CASE( tapos ) } } +/***** + * Important: The next two tests run for a very long time. They SHOULD NOT be run + * as part of the normal test suite + * BOOST_AUTO_TEST_CASE( big_block_p2p ) { try @@ -830,10 +834,6 @@ BOOST_AUTO_TEST_CASE( big_block_p2p ) } -/***** - * Important: This test runs for a very long time. It SHOULD NOT be run - * as part of the normal test suite - * BOOST_AUTO_TEST_CASE( big_transaction_p2p ) { try