Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #1690 cli_wallet crashes on quit #1695

Merged
merged 7 commits into from
May 28, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion libraries/app/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ std::vector<fc::ip::endpoint> application_impl::resolve_string_to_ip_endpoints(c

void application_impl::new_connection( const fc::http::websocket_connection_ptr& c )
{
auto wsc = std::make_shared<fc::rpc::websocket_api_connection>(*c, GRAPHENE_NET_MAX_NESTED_OBJECTS);
auto wsc = std::make_shared<fc::rpc::websocket_api_connection>(c, GRAPHENE_NET_MAX_NESTED_OBJECTS);
auto login = std::make_shared<graphene::app::login_api>( std::ref(*_self) );
login->enable_api("database_api");

Expand Down
4 changes: 3 additions & 1 deletion libraries/plugins/delayed_node/delayed_node_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ void delayed_node_plugin::plugin_set_program_options(bpo::options_description& c

void delayed_node_plugin::connect()
{
my->client_connection = std::make_shared<fc::rpc::websocket_api_connection>(*my->client.connect(my->remote_endpoint), GRAPHENE_NET_MAX_NESTED_OBJECTS);
my->client_connection = std::make_shared<fc::rpc::websocket_api_connection>(
my->client.connect(my->remote_endpoint),
GRAPHENE_NET_MAX_NESTED_OBJECTS );
my->database_api = my->client_connection->get_remote_api<graphene::app::database_api>(0);
my->client_connection_closed = my->client_connection->closed.connect([this] {
connection_failed();
Expand Down
2 changes: 1 addition & 1 deletion libraries/wallet/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@

// explicit instantiation for later use
namespace fc {
template class api<graphene::wallet::wallet_api, identity_member>;
template class api<graphene::wallet::wallet_api, identity_member_with_optionals>;
}

#define BRAIN_KEY_WORD_COUNT 16
Expand Down
128 changes: 79 additions & 49 deletions programs/cli_wallet/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ int main( int argc, char** argv )
fc::http::websocket_client client;
idump((wdata.ws_server));
auto con = client.connect( wdata.ws_server );
auto apic = std::make_shared<fc::rpc::websocket_api_connection>(*con, GRAPHENE_MAX_NESTED_OBJECTS);
auto apic = std::make_shared<fc::rpc::websocket_api_connection>(con, GRAPHENE_MAX_NESTED_OBJECTS);

auto remote_api = apic->get_remote_api< login_api >(1);
edump((wdata.ws_user)(wdata.ws_password) );
Expand All @@ -205,32 +205,11 @@ int main( int argc, char** argv )

fc::api<wallet_api> wapi(wapiptr);

auto wallet_cli = std::make_shared<fc::rpc::cli>( GRAPHENE_MAX_NESTED_OBJECTS );
for( auto& name_formatter : wapiptr->get_result_formatters() )
wallet_cli->format_result( name_formatter.first, name_formatter.second );

boost::signals2::scoped_connection closed_connection(con->closed.connect([wallet_cli]{
cerr << "Server has disconnected us.\n";
wallet_cli->stop();
}));
(void)(closed_connection);

if( wapiptr->is_new() )
{
std::cout << "Please use the set_password method to initialize a new wallet before continuing\n";
wallet_cli->set_prompt( "new >>> " );
} else
wallet_cli->set_prompt( "locked >>> " );

boost::signals2::scoped_connection locked_connection(wapiptr->lock_changed.connect([&](bool locked) {
wallet_cli->set_prompt( locked ? "locked >>> " : "unlocked >>> " );
}));

auto _websocket_server = std::make_shared<fc::http::websocket_server>();
if( options.count("rpc-endpoint") )
{
_websocket_server->on_connection([&wapi]( const fc::http::websocket_connection_ptr& c ){
auto wsc = std::make_shared<fc::rpc::websocket_api_connection>(*c, GRAPHENE_MAX_NESTED_OBJECTS);
auto wsc = std::make_shared<fc::rpc::websocket_api_connection>(c, GRAPHENE_MAX_NESTED_OBJECTS);
wsc->register_api(wapi);
c->set_session_data( wsc );
});
Expand All @@ -247,19 +226,21 @@ int main( int argc, char** argv )
if( options.count("rpc-tls-endpoint") )
{
_websocket_tls_server->on_connection([&wapi]( const fc::http::websocket_connection_ptr& c ){
auto wsc = std::make_shared<fc::rpc::websocket_api_connection>(*c, GRAPHENE_MAX_NESTED_OBJECTS);
auto wsc = std::make_shared<fc::rpc::websocket_api_connection>(c, GRAPHENE_MAX_NESTED_OBJECTS);
wsc->register_api(wapi);
c->set_session_data( wsc );
});
ilog( "Listening for incoming TLS RPC requests on ${p}", ("p", options.at("rpc-tls-endpoint").as<string>() ));
ilog( "Listening for incoming TLS RPC requests on ${p}",
("p", options.at("rpc-tls-endpoint").as<string>()) );
_websocket_tls_server->listen( fc::ip::endpoint::from_string(options.at("rpc-tls-endpoint").as<string>()) );
_websocket_tls_server->start_accept();
}

auto _http_server = std::make_shared<fc::http::server>();
if( options.count("rpc-http-endpoint" ) )
{
ilog( "Listening for incoming HTTP RPC requests on ${p}", ("p", options.at("rpc-http-endpoint").as<string>() ) );
ilog( "Listening for incoming HTTP RPC requests on ${p}",
("p", options.at("rpc-http-endpoint").as<string>()) );
_http_server->listen( fc::ip::endpoint::from_string( options.at( "rpc-http-endpoint" ).as<string>() ) );
//
// due to implementation, on_request() must come AFTER listen()
Expand All @@ -276,43 +257,92 @@ int main( int argc, char** argv )

if( !options.count( "daemon" ) )
{
wallet_cli->register_api( wapi );
wallet_cli->start();
auto wallet_cli = std::make_shared<fc::rpc::cli>( GRAPHENE_MAX_NESTED_OBJECTS );
for( auto& name_formatter : wapiptr->get_result_formatters() )
wallet_cli->format_result( name_formatter.first, name_formatter.second );

fc::set_signal_handler([](int signal) {
ilog( "Captured SIGINT not in daemon mode" );
fclose(stdin);
}, SIGINT);

fc::set_signal_handler([](int signal) {
ilog( "Captured SIGTERM not in daemon mode" );
fclose(stdin);
}, SIGTERM);
if( wapiptr->is_new() )
{
std::cout << "Please use the set_password method to initialize a new wallet before continuing\n";
wallet_cli->set_prompt( "new >>> " );
}
else
wallet_cli->set_prompt( "locked >>> " );

boost::signals2::scoped_connection locked_connection( wapiptr->lock_changed.connect(
[wallet_cli](bool locked) {
wallet_cli->set_prompt( locked ? "locked >>> " : "unlocked >>> " );
}));

auto sig_set = fc::set_signal_handler( [wallet_cli](int signal) {
ilog( "Captured SIGINT not in daemon mode, exiting" );
fc::set_signal_handler( [](int sig) {}, SIGINT ); // reinstall an empty SIGINT handler
wallet_cli->cancel();
}, SIGINT );

fc::set_signal_handler( [wallet_cli,sig_set](int signal) {
ilog( "Captured SIGTERM not in daemon mode, exiting" );
sig_set->cancel();
fc::set_signal_handler( [](int sig) {}, SIGINT ); // reinstall an empty SIGINT handler
wallet_cli->cancel();
}, SIGTERM );

fc::set_signal_handler( [wallet_cli,sig_set](int signal) {
ilog( "Captured SIGQUIT not in daemon mode, exiting" );
sig_set->cancel();
fc::set_signal_handler( [](int sig) {}, SIGINT ); // reinstall an empty SIGINT handler
wallet_cli->cancel();
}, SIGQUIT );

boost::signals2::scoped_connection closed_connection( con->closed.connect( [wallet_cli,sig_set] {
elog( "Server has disconnected us." );
sig_set->cancel();
fc::set_signal_handler( [](int sig) {}, SIGINT ); // reinstall an empty SIGINT handler
wallet_cli->cancel();
}));

wallet_cli->register_api( wapi );
wallet_cli->start();
wallet_cli->wait();

locked_connection.disconnect();
closed_connection.disconnect();
}
else
{
fc::promise<int>::ptr exit_promise = new fc::promise<int>("UNIX Signal Handler");
fc::set_signal_handler([&exit_promise](int signal) {
exit_promise->set_value(signal);
}, SIGINT);
fc::promise<int>::ptr exit_promise = new fc::promise<int>("UNIX Signal Handler");

fc::set_signal_handler( [&exit_promise](int signal) {
ilog( "Captured SIGINT in daemon mode, exiting" );
exit_promise->set_value(signal);
}, SIGINT );

fc::set_signal_handler( [&exit_promise](int signal) {
ilog( "Captured SIGTERM in daemon mode, exiting" );
exit_promise->set_value(signal);
}, SIGTERM );

fc::set_signal_handler( [&exit_promise](int signal) {
ilog( "Captured SIGQUIT in daemon mode, exiting" );
exit_promise->set_value(signal);
}, SIGQUIT );

boost::signals2::scoped_connection closed_connection( con->closed.connect( [&exit_promise] {
elog( "Server has disconnected us." );
exit_promise->set_value(0);
}));

fc::set_signal_handler([&exit_promise](int signal) {
exit_promise->set_value(signal);
}, SIGTERM);
ilog( "Entering Daemon Mode, ^C to exit" );
exit_promise->wait();

ilog( "Entering Daemon Mode, ^C to exit" );
exit_promise->wait();
closed_connection.disconnect();
}

wapi->save_wallet_file(wallet_file.generic_string());
locked_connection.disconnect();
closed_connection.disconnect();
}
catch ( const fc::exception& e )
{
std::cout << e.to_detail_string() << "\n";
std::cerr << e.to_detail_string() << "\n";
return -1;
}
return 0;
Expand Down
3 changes: 2 additions & 1 deletion tests/cli/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,8 @@ class client_connection
wallet_data.ws_password = "";
websocket_connection = websocket_client.connect( wallet_data.ws_server );

api_connection = std::make_shared<fc::rpc::websocket_api_connection>(*websocket_connection, GRAPHENE_MAX_NESTED_OBJECTS);
api_connection = std::make_shared<fc::rpc::websocket_api_connection>( websocket_connection,
GRAPHENE_MAX_NESTED_OBJECTS );

remote_login_api = api_connection->get_remote_api< graphene::app::login_api >(1);
BOOST_CHECK(remote_login_api->login( wallet_data.ws_user, wallet_data.ws_password ) );
Expand Down