From a7ad0d4aff268c673dfdb1e4e6d53e07167a4dff Mon Sep 17 00:00:00 2001 From: John Jones Date: Fri, 13 Sep 2019 10:05:09 -0500 Subject: [PATCH 1/5] make method available to others --- libraries/app/application.cpp | 65 +++++++++---------- libraries/app/application_impl.hxx | 2 - .../app/include/graphene/app/application.hpp | 2 + 3 files changed, 34 insertions(+), 35 deletions(-) diff --git a/libraries/app/application.cpp b/libraries/app/application.cpp index 5421fbc6bd..c9b4c04ec8 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)); @@ -170,7 +170,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)); @@ -196,36 +196,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); @@ -988,6 +958,35 @@ application::~application() } } +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)) +} + void application::set_program_options(boost::program_options::options_description& command_line_options, boost::program_options::options_description& configuration_file_options) const { diff --git a/libraries/app/application_impl.hxx b/libraries/app/application_impl.hxx index 175648e10f..accc8fe4f1 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 a9b6655cc3..78c9404c26 100644 --- a/libraries/app/include/graphene/app/application.hpp +++ b/libraries/app/include/graphene/app/application.hpp @@ -128,6 +128,8 @@ namespace graphene { namespace app { bool is_plugin_enabled(const string& name) const; + static std::vector resolve_string_to_ip_endpoints(const std::string& endpoint_string); + std::shared_ptr elasticsearch_thread; private: From 1cbe2f199af7e639c6a205565d634d4ad9b299c9 Mon Sep 17 00:00:00 2001 From: John Jones Date: Fri, 13 Sep 2019 10:06:39 -0500 Subject: [PATCH 2/5] Create node app --- tests/CMakeLists.txt | 9 +- tests/app/good_node.cpp | 20 ++++ tests/common/application_helper.cpp | 138 ++++++++++++++++++++++++++++ tests/common/application_helper.hpp | 99 ++++++++++++++++++++ tests/common/genesis_file_util.hpp | 2 + 5 files changed, 266 insertions(+), 2 deletions(-) create mode 100644 tests/app/good_node.cpp 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 d05bf13183..8bfcf1433d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,4 +1,4 @@ -file(GLOB COMMON_SOURCES "common/*.cpp") +file(GLOB COMMON_SOURCES "common/database_fixture.cpp") find_package( Gperftools QUIET ) if( GPERFTOOLS_FOUND ) @@ -31,10 +31,15 @@ target_link_libraries( chain_bench graphene_es_objects graphene_egenesis_none graphene_api_helper_indexes fc ${PLATFORM_SPECIFIC_LIBS} ) -file(GLOB APP_SOURCES "app/*.cpp") +file(GLOB APP_SOURCES "app/main.cpp") add_executable( app_test ${APP_SOURCES} ) target_link_libraries( app_test graphene_app graphene_account_history graphene_net graphene_witness graphene_chain graphene_egenesis_none fc ${PLATFORM_SPECIFIC_LIBS} ) +file(GLOB GOOD_NODE_SOURCES "common/application_helper.cpp" "app/good_node.cpp") +add_executable( good_node ${GOOD_NODE_SOURCES} ) +target_include_directories( good_node PRIVATE "../libraries/plugins/witness/include" ) +target_link_libraries( good_node graphene_app graphene_account_history graphene_net graphene_witness graphene_chain graphene_egenesis_none fc ${PLATFORM_SPECIFIC_LIBS} ) + file(GLOB CLI_SOURCES "cli/*.cpp") add_executable( cli_test ${CLI_SOURCES} ) if(WIN32) diff --git a/tests/app/good_node.cpp b/tests/app/good_node.cpp new file mode 100644 index 0000000000..e65ebe7853 --- /dev/null +++ b/tests/app/good_node.cpp @@ -0,0 +1,20 @@ +#include "../common/application_helper.hpp" + +int main(int argc, char** argv) +{ + graphene::test::application_runner app; + app.start(); + std::string p2p_address = "127.0.0.1:" + std::to_string( app.p2p_port_number ); + std::cout << "Running on " << p2p_address << std::endl; + + // add node + if (argc > 1) + { + app.add_seed_node(argv[1]); + } + + std::cout << "Press e to exit" << std::endl; + char c = 0; + while( c != 'e' ) + std::cin >> c; +} \ No newline at end of file diff --git a/tests/common/application_helper.cpp b/tests/common/application_helper.cpp new file mode 100644 index 0000000000..f5fc531c2c --- /dev/null +++ b/tests/common/application_helper.cpp @@ -0,0 +1,138 @@ +#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< 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->startup_plugins(); +#ifdef _WIN32 + sockInit(); +#endif + 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(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)); + std::string seed_node_string = "["; + bool needs_comma = false; + for(auto url : seed_nodes) + { + 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)); + _app->initialize(_dir.path(), cfg); + + _app->initialize_plugins(cfg); + _app->startup_plugins(); + + _app->startup(); + fc::usleep(fc::milliseconds(500)); +} + +std::shared_ptr application_runner::get_app() +{ + return _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; +} + +////// +/// @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); +} + +}} \ No newline at end of file diff --git a/tests/common/application_helper.hpp b/tests/common/application_helper.hpp new file mode 100644 index 0000000000..333ee504ae --- /dev/null +++ b/tests/common/application_helper.hpp @@ -0,0 +1,99 @@ +#pragma once +#include +#include +#include + +#include +#include +#include +#include + +namespace graphene { namespace test { + +/** + * Handles creating a running node + */ +class application_runner +{ + public: + application_runner(); + 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; +}; + +/////////// +/// @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_ptr->save_wallet_file(); + + 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); + } + 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; + 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; +}; + +}} \ No newline at end of file diff --git a/tests/common/genesis_file_util.hpp b/tests/common/genesis_file_util.hpp index a87d9585af..2edb2ff59f 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 b1e833190030c3aadc4b8ce08fef559c5fd97ca5 Mon Sep 17 00:00:00 2001 From: John Jones Date: Fri, 13 Sep 2019 16:40:30 -0500 Subject: [PATCH 3/5] get test app working --- libraries/net/node.cpp | 12 +++++--- tests/app/good_node.cpp | 46 +++++++++++++++++++++++++---- tests/app/main.cpp | 4 +-- tests/cli/main.cpp | 2 +- tests/common/application_helper.cpp | 43 ++++++++++++++++++++------- tests/common/application_helper.hpp | 7 ++++- tests/common/genesis_file_util.hpp | 4 +-- 7 files changed, 93 insertions(+), 25 deletions(-) diff --git a/libraries/net/node.cpp b/libraries/net/node.cpp index 9a9b98386b..66c1f431f8 100644 --- a/libraries/net/node.cpp +++ b/libraries/net/node.cpp @@ -1353,10 +1353,13 @@ namespace graphene { namespace net { namespace detail { user_data["node_id"] = fc::variant( _node_id, 1 ); - item_hash_t head_block_id = _delegate->get_head_block_id(); - user_data["last_known_block_hash"] = fc::variant( head_block_id, 1 ); - user_data["last_known_block_number"] = _delegate->get_block_number(head_block_id); - user_data["last_known_block_time"] = _delegate->get_block_time(head_block_id); + if (!_delegate) + { + item_hash_t head_block_id = _delegate->get_head_block_id(); + user_data["last_known_block_hash"] = fc::variant( head_block_id, 1 ); + user_data["last_known_block_number"] = _delegate->get_block_number(head_block_id); + user_data["last_known_block_time"] = _delegate->get_block_time(head_block_id); + } if (!_hard_fork_block_numbers.empty()) user_data["last_known_fork_block_number"] = _hard_fork_block_numbers.back(); @@ -4184,6 +4187,7 @@ namespace graphene { namespace net { namespace detail { void node_impl::add_node(const fc::ip::endpoint& ep) { + dlog("Attempting to add node ${ip}", ("ip", ep)); VERIFY_CORRECT_THREAD(); // if we're connecting to them, we believe they're not firewalled potential_peer_record updated_peer_record = _potential_peer_db.lookup_or_create_entry_for_endpoint(ep); diff --git a/tests/app/good_node.cpp b/tests/app/good_node.cpp index e65ebe7853..7e315fd594 100644 --- a/tests/app/good_node.cpp +++ b/tests/app/good_node.cpp @@ -1,19 +1,55 @@ #include "../common/application_helper.hpp" +#include +#include +#include +#include + +namespace fc { + extern std::unordered_map& get_logger_map(); + extern std::unordered_map& get_appender_map(); +} int main(int argc, char** argv) { - graphene::test::application_runner app; + fc::temp_directory td; + std::shared_ptr temp_dir = nullptr; + std::string remote_node_ip; + for (int i = 1; i < argc; i++) + { + if (std::string(argv[i]) == "-d") + { + temp_dir = std::make_shared( fc::path(argv[i+1])); + } + if (std::string(argv[i]) == "-s") + remote_node_ip = argv[i+1]; + } + // we were not passed a temp directory, create one + if (!temp_dir) + temp_dir = std::make_shared( td.path() ); + // start node + graphene::test::application_runner app(temp_dir); app.start(); std::string p2p_address = "127.0.0.1:" + std::to_string( app.p2p_port_number ); + + // adjust logging + auto log_map = fc::get_logger_map(); + auto appenders = fc::get_appender_map(); + auto p2p_logger = log_map["p2p"]; + p2p_logger.add_appender( appenders["stdout"] ); + p2p_logger.set_log_level(fc::log_level::debug); + auto default_logger = log_map["default"]; + default_logger.set_log_level(fc::log_level::debug); std::cout << "Running on " << p2p_address << std::endl; - // add node - if (argc > 1) + // add node if passed in + if (!remote_node_ip.empty()) { - app.add_seed_node(argv[1]); + std::this_thread::sleep_for(std::chrono::seconds(5)); + std::cout << "attempting to add node " << remote_node_ip << "\n"; + app.add_node(remote_node_ip); } - std::cout << "Press e to exit" << std::endl; + std::cout << "Press e [enter] to exit" << std::endl; char c = 0; while( c != 'e' ) std::cin >> c; diff --git a/tests/app/main.cpp b/tests/app/main.cpp index b85b847ae5..1097167935 100644 --- a/tests/app/main.cpp +++ b/tests/app/main.cpp @@ -227,7 +227,7 @@ BOOST_AUTO_TEST_CASE( two_node_network ) app1.startup_plugins(); boost::program_options::variables_map cfg; cfg.emplace("p2p-endpoint", boost::program_options::variable_value(string("127.0.0.1:3939"), false)); - cfg.emplace("genesis-json", boost::program_options::variable_value(create_genesis_file(app_dir), false)); + cfg.emplace("genesis-json", boost::program_options::variable_value(create_genesis_file(app_dir.path()), false)); cfg.emplace("seed-nodes", boost::program_options::variable_value(string("[]"), false)); app1.initialize(app_dir.path(), cfg); BOOST_TEST_MESSAGE( "Starting app1 and waiting 500 ms" ); @@ -246,7 +246,7 @@ BOOST_AUTO_TEST_CASE( two_node_network ) auto cfg2 = cfg; cfg2.erase("p2p-endpoint"); cfg2.emplace("p2p-endpoint", boost::program_options::variable_value(string("127.0.0.1:4040"), false)); - cfg2.emplace("genesis-json", boost::program_options::variable_value(create_genesis_file(app_dir), false)); + cfg2.emplace("genesis-json", boost::program_options::variable_value(create_genesis_file(app_dir.path()), false)); cfg2.emplace("seed-node", boost::program_options::variable_value(vector{"127.0.0.1:3939"}, false)); cfg2.emplace("seed-nodes", boost::program_options::variable_value(string("[]"), false)); app2.initialize(app2_dir.path(), cfg2); diff --git a/tests/cli/main.cpp b/tests/cli/main.cpp index c2c0278a43..afb302cfe4 100644 --- a/tests/cli/main.cpp +++ b/tests/cli/main.cpp @@ -136,7 +136,7 @@ std::shared_ptr start_application(fc::temp_directory "rpc-endpoint", boost::program_options::variable_value(string("127.0.0.1:" + std::to_string(server_port_number)), false) ); - cfg.emplace("genesis-json", boost::program_options::variable_value(create_genesis_file(app_dir), false)); + cfg.emplace("genesis-json", boost::program_options::variable_value(create_genesis_file(app_dir.path()), false)); cfg.emplace("seed-nodes", boost::program_options::variable_value(string("[]"), false)); app1->initialize(app_dir.path(), cfg); diff --git a/tests/common/application_helper.cpp b/tests/common/application_helper.cpp index f5fc531c2c..1882cb5d14 100644 --- a/tests/common/application_helper.cpp +++ b/tests/common/application_helper.cpp @@ -5,6 +5,8 @@ #include #include #include +#include +#include #ifdef _WIN32 #ifndef _WIN32_WINNT @@ -45,18 +47,34 @@ application_runner::application_runner() #endif rpc_port_number = get_available_port(); p2p_port_number = get_available_port(); + _dir = std::make_shared(); +} + +bool file_exists(std::string path) +{ + std::ifstream s(path); + if (s) + return true; + return false; } void application_runner::start() { - boost::program_options::variables_map cfg; + std::string genesis_path = _dir->generic_string() + "/genesis.json"; + boost::filesystem::path genesis = boost::filesystem::path(genesis_path); + if (!file_exists(genesis_path)) + genesis = create_genesis_file(*_dir); + start(*_dir, genesis); +} +void application_runner::start(const fc::path& data_path, const boost::filesystem::path& genesis ) +{ cfg.emplace( "rpc-endpoint", 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("genesis-json", boost::program_options::variable_value( genesis, false )); std::string seed_node_string = "["; bool needs_comma = false; for(auto url : seed_nodes) @@ -68,12 +86,11 @@ void application_runner::start() } seed_node_string += "]"; cfg.emplace("seed-nodes", boost::program_options::variable_value(seed_node_string, false)); - _app->initialize(_dir.path(), cfg); + _app->initialize(data_path, cfg); _app->initialize_plugins(cfg); _app->startup_plugins(); - - _app->startup(); + _app->startup(); fc::usleep(fc::milliseconds(500)); } @@ -84,14 +101,20 @@ 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); } +void application_runner::add_node(std::string addr) +{ + auto endpoints = application::resolve_string_to_ip_endpoints(addr); + if (endpoints.empty()) + { + std::cerr << "Invalid node address passed\n"; + return; + } + _app->p2p_node()->add_node( endpoints[0] ); +} + uint32_t application_runner::get_connection_count() { return _app->p2p_node()->get_connection_count(); diff --git a/tests/common/application_helper.hpp b/tests/common/application_helper.hpp index 333ee504ae..a08bf4be0a 100644 --- a/tests/common/application_helper.hpp +++ b/tests/common/application_helper.hpp @@ -17,19 +17,24 @@ class application_runner { public: application_runner(); + application_runner(std::shared_ptr dir) : application_runner() { _dir = dir; } void start(); + void start(const fc::path& data_path, const boost::filesystem::path& genesis_path); int rpc_port_number; int p2p_port_number; std::shared_ptr get_app(); // networking void add_seed_node(std::string addr); + void add_node(std::string addr); bool is_connected( std::string addr ); uint32_t get_connection_count(); + private: std::shared_ptr _app; - fc::temp_directory _dir; + std::shared_ptr _dir; static int get_available_port(); std::vector seed_nodes; + boost::program_options::variables_map cfg; }; /////////// diff --git a/tests/common/genesis_file_util.hpp b/tests/common/genesis_file_util.hpp index 2edb2ff59f..81dcf993c5 100644 --- a/tests/common/genesis_file_util.hpp +++ b/tests/common/genesis_file_util.hpp @@ -15,8 +15,8 @@ namespace graphene { namespace app { namespace detail { /// @param directory the directory to place the file "genesis.json" /// @returns the full path to the file //////// -boost::filesystem::path create_genesis_file(fc::temp_directory& directory) { - boost::filesystem::path genesis_path = boost::filesystem::path{directory.path().generic_string()} / "genesis.json"; +boost::filesystem::path create_genesis_file(const fc::path& directory) { + boost::filesystem::path genesis_path = boost::filesystem::path{directory.generic_string()} / "genesis.json"; fc::path genesis_out = genesis_path; graphene::chain::genesis_state_type genesis_state = graphene::app::detail::create_example_genesis(); From dff3dd5bcb30e6227f4543a15b9b7d04b4b3e823 Mon Sep 17 00:00:00 2001 From: John Jones Date: Fri, 13 Sep 2019 17:41:46 -0500 Subject: [PATCH 4/5] Improve flexibility --- libraries/net/node.cpp | 17 ++++++++--------- tests/app/good_node.cpp | 5 ++++- tests/common/application_helper.cpp | 6 ++++++ tests/common/application_helper.hpp | 2 +- 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/libraries/net/node.cpp b/libraries/net/node.cpp index 66c1f431f8..5026ca6786 100644 --- a/libraries/net/node.cpp +++ b/libraries/net/node.cpp @@ -1353,13 +1353,10 @@ namespace graphene { namespace net { namespace detail { user_data["node_id"] = fc::variant( _node_id, 1 ); - if (!_delegate) - { - item_hash_t head_block_id = _delegate->get_head_block_id(); - user_data["last_known_block_hash"] = fc::variant( head_block_id, 1 ); - user_data["last_known_block_number"] = _delegate->get_block_number(head_block_id); - user_data["last_known_block_time"] = _delegate->get_block_time(head_block_id); - } + item_hash_t head_block_id = _delegate->get_head_block_id(); + user_data["last_known_block_hash"] = fc::variant( head_block_id, 1 ); + user_data["last_known_block_number"] = _delegate->get_block_number(head_block_id); + user_data["last_known_block_time"] = _delegate->get_block_time(head_block_id); if (!_hard_fork_block_numbers.empty()) user_data["last_known_fork_block_number"] = _hard_fork_block_numbers.back(); @@ -5080,12 +5077,14 @@ namespace graphene { namespace net { namespace detail { fc::time_point_sec statistics_gathering_node_delegate_wrapper::get_block_time(const item_hash_t& block_id) { - INVOKE_AND_COLLECT_STATISTICS(get_block_time, block_id); + //INVOKE_AND_COLLECT_STATISTICS(get_block_time, block_id); + return _node_delegate->get_block_time(block_id); } item_hash_t statistics_gathering_node_delegate_wrapper::get_head_block_id() const { - INVOKE_AND_COLLECT_STATISTICS(get_head_block_id); + //INVOKE_AND_COLLECT_STATISTICS(get_head_block_id); + _node_delegate->get_head_block_id(); } uint32_t statistics_gathering_node_delegate_wrapper::estimate_last_known_fork_from_git_revision_timestamp(uint32_t unix_timestamp) const diff --git a/tests/app/good_node.cpp b/tests/app/good_node.cpp index 7e315fd594..cfb2056f6e 100644 --- a/tests/app/good_node.cpp +++ b/tests/app/good_node.cpp @@ -14,6 +14,7 @@ int main(int argc, char** argv) fc::temp_directory td; std::shared_ptr temp_dir = nullptr; std::string remote_node_ip; + std::string my_port = "0"; for (int i = 1; i < argc; i++) { if (std::string(argv[i]) == "-d") @@ -22,12 +23,14 @@ int main(int argc, char** argv) } if (std::string(argv[i]) == "-s") remote_node_ip = argv[i+1]; + if (std::string(argv[i]) == "-p") + my_port = argv[i+1]; } // we were not passed a temp directory, create one if (!temp_dir) temp_dir = std::make_shared( td.path() ); // start node - graphene::test::application_runner app(temp_dir); + graphene::test::application_runner app(temp_dir, std::stoi(my_port)); app.start(); std::string p2p_address = "127.0.0.1:" + std::to_string( app.p2p_port_number ); diff --git a/tests/common/application_helper.cpp b/tests/common/application_helper.cpp index 1882cb5d14..92ce6315dd 100644 --- a/tests/common/application_helper.cpp +++ b/tests/common/application_helper.cpp @@ -33,6 +33,12 @@ int sockQuit(void) namespace graphene { namespace test { +application_runner::application_runner(std::shared_ptr dir, int port) : application_runner() +{ + _dir = dir; + if (port != 0) + p2p_port_number = port; +} application_runner::application_runner() { _app = std::make_shared(); diff --git a/tests/common/application_helper.hpp b/tests/common/application_helper.hpp index a08bf4be0a..41d055ec9d 100644 --- a/tests/common/application_helper.hpp +++ b/tests/common/application_helper.hpp @@ -17,7 +17,7 @@ class application_runner { public: application_runner(); - application_runner(std::shared_ptr dir) : application_runner() { _dir = dir; } + application_runner(std::shared_ptr dir, int port); void start(); void start(const fc::path& data_path, const boost::filesystem::path& genesis_path); int rpc_port_number; From a11aba6c6c65b38308062ab6f8dddcdd58816550 Mon Sep 17 00:00:00 2001 From: John Jones Date: Mon, 16 Sep 2019 11:43:16 -0500 Subject: [PATCH 5/5] add timeout param --- tests/app/good_node.cpp | 24 +++++++++++++++++------- tests/common/application_helper.cpp | 2 +- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/tests/app/good_node.cpp b/tests/app/good_node.cpp index cfb2056f6e..b528477161 100644 --- a/tests/app/good_node.cpp +++ b/tests/app/good_node.cpp @@ -3,6 +3,7 @@ #include #include #include +#include namespace fc { extern std::unordered_map& get_logger_map(); @@ -15,16 +16,17 @@ int main(int argc, char** argv) std::shared_ptr temp_dir = nullptr; std::string remote_node_ip; std::string my_port = "0"; + int timeout = -1; for (int i = 1; i < argc; i++) { if (std::string(argv[i]) == "-d") - { temp_dir = std::make_shared( fc::path(argv[i+1])); - } if (std::string(argv[i]) == "-s") remote_node_ip = argv[i+1]; if (std::string(argv[i]) == "-p") my_port = argv[i+1]; + if (std::string(argv[i]) == "-t") + timeout = std::stoi(argv[i+1]); } // we were not passed a temp directory, create one if (!temp_dir) @@ -52,8 +54,16 @@ int main(int argc, char** argv) app.add_node(remote_node_ip); } - std::cout << "Press e [enter] to exit" << std::endl; - char c = 0; - while( c != 'e' ) - std::cin >> c; -} \ No newline at end of file + if (timeout == -1) + { + std::cout << "Press e [enter] to exit" << std::endl; + char c = 0; + while( c != 'e' ) + std::cin >> c; + } + else + { + std::this_thread::sleep_for(std::chrono::seconds(timeout)); + ::raise(SIGINT); + } +} diff --git a/tests/common/application_helper.cpp b/tests/common/application_helper.cpp index 92ce6315dd..2efa13e743 100644 --- a/tests/common/application_helper.cpp +++ b/tests/common/application_helper.cpp @@ -97,7 +97,7 @@ void application_runner::start(const fc::path& data_path, const boost::filesyste _app->initialize_plugins(cfg); _app->startup_plugins(); _app->startup(); - fc::usleep(fc::milliseconds(500)); + fc::usleep(fc::milliseconds(250)); } std::shared_ptr application_runner::get_app()