int main( int argc, char** argv ) { // parse command-line options boost::program_options::options_description option_config("Allowed options"); option_config.add_options()("data-dir", boost::program_options::value<std::string>(), "configuration data directory") ("help", "display this help message") ("p2p-port", boost::program_options::value<uint16_t>()->default_value(5678), "set port to listen on") ("maximum-number-of-connections", boost::program_options::value<uint16_t>(), "set the maximum number of peers this node will accept at any one time") ("upnp", boost::program_options::value<bool>()->default_value(true), "Enable UPNP") ("connect-to", boost::program_options::value<std::vector<std::string> >(), "set remote host to connect to") ("server", "enable JSON-RPC server") ("daemon", "run in daemon mode with no CLI console") ("rpcuser", boost::program_options::value<std::string>(), "username for JSON-RPC") ("rpcpassword", boost::program_options::value<std::string>(), "password for JSON-RPC") ("rpcport", boost::program_options::value<uint16_t>()->default_value(5679), "port to listen for JSON-RPC connections") ("httpport", boost::program_options::value<uint16_t>()->default_value(5680), "port to listen for HTTP JSON-RPC connections") ("genesis-config", boost::program_options::value<std::string>()->default_value("genesis.dat"), "generate a genesis state with the given json file (only accepted when the blockchain is empty)") ("clear-peer-database", "erase all information in the peer database") ("resync-blockchain", "delete our copy of the blockchain at startup, and download a fresh copy of the entire blockchain from the network") ("version", "print the version information for bts_xt_client"); boost::program_options::positional_options_description positional_config; positional_config.add("data-dir", 1); boost::program_options::variables_map option_variables; try { boost::program_options::store(boost::program_options::command_line_parser(argc, argv). options(option_config).positional(positional_config).run(), option_variables); boost::program_options::notify(option_variables); } catch (boost::program_options::error&) { std::cerr << "Error parsing command-line options\n\n"; std::cerr << option_config << "\n"; return 1; } if (option_variables.count("help")) { std::cout << option_config << "\n"; return 0; } if (option_variables.count("version")) { std::cout << "bts_xt_client built on " << __DATE__ << " at " << __TIME__ << "\n"; std::cout << " bitshares_toolkit revision: " << bts::utilities::git_revision_sha << "\n"; std::cout << " committed " << fc::get_approximate_relative_time_string(fc::time_point_sec(bts::utilities::git_revision_unix_timestamp)) << "\n"; std::cout << " fc revision: " << fc::git_revision_sha << "\n"; std::cout << " committed " << fc::get_approximate_relative_time_string(fc::time_point_sec(bts::utilities::git_revision_unix_timestamp)) << "\n"; return 0; } try { print_banner(); fc::path datadir = get_data_dir(option_variables); ::configure_logging(datadir); auto cfg = load_config(datadir); auto chain = load_and_configure_chain_database(datadir, option_variables); auto wall = std::make_shared<bts::wallet::wallet>(chain); wall->set_data_directory( datadir ); bts::client::client_ptr client = std::make_shared<bts::client::client>( chain ); _global_client = client.get(); client->set_wallet( wall ); client->run_delegate(); bts::rpc::rpc_server_ptr rpc_server = std::make_shared<bts::rpc::rpc_server>(); rpc_server->set_client(client); if( option_variables.count("server") ) { // the user wants us to launch the RPC server. // First, override any config parameters they bts::rpc::rpc_server::config rpc_config(cfg.rpc); if (option_variables.count("rpcuser")) rpc_config.rpc_user = option_variables["rpcuser"].as<std::string>(); if (option_variables.count("rpcpassword")) rpc_config.rpc_password = option_variables["rpcpassword"].as<std::string>(); // for now, force binding to localhost only if (option_variables.count("rpcport")) rpc_config.rpc_endpoint = fc::ip::endpoint(fc::ip::address("127.0.0.1"), option_variables["rpcport"].as<uint16_t>()); else rpc_config.rpc_endpoint = fc::ip::endpoint(fc::ip::address("127.0.0.1"), uint16_t(9988)); if (option_variables.count("httpport")) rpc_config.httpd_endpoint = fc::ip::endpoint(fc::ip::address("127.0.0.1"), option_variables["httpport"].as<uint16_t>()); std::cout<<"Starting json rpc server on "<< std::string( rpc_config.rpc_endpoint ) <<"\n"; std::cout<<"Starting http json rpc server on "<< std::string( rpc_config.httpd_endpoint ) <<"\n"; bool rpc_success = rpc_server->configure(rpc_config); if (!rpc_success) { std::cerr << "Error starting rpc server\n\n"; } } else { std::cout << "Not starting rpc server, use --server to enable the rpc interface\n"; } client->configure( datadir ); if (option_variables.count("maximum-number-of-connections")) { fc::mutable_variant_object params; params["maximum_number_of_connections"] = option_variables["maximum-number-of-connections"].as<uint16_t>(); client->network_set_advanced_node_parameters(params); } if (option_variables.count("p2p-port")) { auto p2pport = option_variables["p2p-port"].as<uint16_t>(); std::cout << "Listening to P2P connections on port "<<p2pport<<"\n"; client->listen_on_port(p2pport); if( option_variables["upnp"].as<bool>() ) { std::cout << "Attempting to map UPNP port...\n"; auto upnp_service = new bts::net::upnp_service(); upnp_service->map_port( p2pport ); fc::usleep( fc::seconds(3) ); } } if (option_variables.count("clear-peer-database")) { std::cout << "Erasing old peer database\n"; client->get_node()->clear_peer_database(); } client->connect_to_p2p_network(); if (option_variables.count("connect-to")) { std::vector<std::string> hosts = option_variables["connect-to"].as<std::vector<std::string>>(); for( auto peer : hosts ) { client->connect_to_peer( peer ); } } else { client->connect_to_peer( "107.170.30.182:5678" ); } if( !option_variables.count("daemon") ) { auto cli = std::make_shared<bts::cli::cli>( client, rpc_server ); cli->wait(); } else if( option_variables.count( "server" ) ) // daemon & server { rpc_server->wait_on_quit(); } else // daemon !server { std::cerr << "You must start the rpc server in daemon mode\n"; } } catch ( const fc::exception& e ) { std::cerr << "------------ error --------------\n" << e.to_detail_string() << "\n"; wlog( "${e}", ("e", e.to_detail_string() ) ); } return 0; }
int main( int argc, char** argv ) { // parse command-line options boost::program_options::options_description option_config("Allowed options"); option_config.add_options()("data-dir", boost::program_options::value<std::string>(), "configuration data directory") ("help", "display this help message") ("p2p", "enable p2p mode") ("port", boost::program_options::value<uint16_t>(), "set port to listen on") ("connect-to", boost::program_options::value<std::string>(), "set remote host to connect to") ("server", "enable JSON-RPC server") ("rpcuser", boost::program_options::value<std::string>(), "username for JSON-RPC") ("rpcpassword", boost::program_options::value<std::string>(), "password for JSON-RPC") ("rpcport", boost::program_options::value<uint16_t>(), "port to listen for JSON-RPC connections") ("httpport", boost::program_options::value<uint16_t>(), "port to listen for HTTP JSON-RPC connections") ("trustee-private-key", boost::program_options::value<std::string>(), "act as a trustee using the given private key") ("trustee-address", boost::program_options::value<std::string>(), "trust the given BTS address to generate blocks") ("genesis-json", boost::program_options::value<std::string>(), "generate a genesis block with the given json file (only for testing, only accepted when the blockchain is empty)"); boost::program_options::positional_options_description positional_config; positional_config.add("data-dir", 1); boost::program_options::variables_map option_variables; try { boost::program_options::store(boost::program_options::command_line_parser(argc, argv). options(option_config).positional(positional_config).run(), option_variables); boost::program_options::notify(option_variables); } catch (boost::program_options::error&) { std::cerr << "Error parsing command-line options\n\n"; std::cerr << option_config << "\n"; return 1; } if (option_variables.count("help")) { std::cout << option_config << "\n"; return 0; } bool p2p_mode = option_variables.count("p2p") != 0; try { print_banner(); fc::path datadir = get_data_dir(option_variables); ::configure_logging(datadir); auto cfg = load_config(datadir); auto chain = load_and_configure_chain_database(datadir, option_variables); auto wall = std::make_shared<bts::wallet::wallet>(); wall->set_data_directory( datadir ); auto c = std::make_shared<bts::client::client>(p2p_mode); c->set_chain( chain ); c->set_wallet( wall ); if (option_variables.count("trustee-private-key")) { auto key = fc::variant(option_variables["trustee-private-key"].as<std::string>()).as<fc::ecc::private_key>(); c->run_trustee(key); } else if( fc::exists( "trustee.key" ) ) { auto key = fc::json::from_file( "trustee.key" ).as<fc::ecc::private_key>(); c->run_trustee(key); } bts::rpc::rpc_server_ptr rpc_server = std::make_shared<bts::rpc::rpc_server>(); rpc_server->set_client(c); if( option_variables.count("server") ) { // the user wants us to launch the RPC server. // First, override any config parameters they bts::rpc::rpc_server::config rpc_config(cfg.rpc); if (option_variables.count("rpcuser")) rpc_config.rpc_user = option_variables["rpcuser"].as<std::string>(); if (option_variables.count("rpcpassword")) rpc_config.rpc_password = option_variables["rpcpassword"].as<std::string>(); // for now, force binding to localhost only if (option_variables.count("rpcport")) rpc_config.rpc_endpoint = fc::ip::endpoint(fc::ip::address("127.0.0.1"), option_variables["rpcport"].as<uint16_t>()); if (option_variables.count("httpport")) rpc_config.httpd_endpoint = fc::ip::endpoint(fc::ip::address("127.0.0.1"), option_variables["httpport"].as<uint16_t>()); std::cerr<<"starting json rpc server on "<< std::string( rpc_config.rpc_endpoint ) <<"\n"; std::cerr<<"starting http json rpc server on "<< std::string( rpc_config.httpd_endpoint ) <<"\n"; rpc_server->configure(rpc_config); } if (p2p_mode) { c->configure( datadir ); if (option_variables.count("port")) c->listen_on_port(option_variables["port"].as<uint16_t>()); c->connect_to_p2p_network(); if (option_variables.count("connect-to")) c->connect_to_peer(option_variables["connect-to"].as<std::string>()); } else { if (option_variables.count("connect-to")) c->add_node(option_variables["connect-to"].as<std::string>()); else c->add_node( "127.0.0.1:4569" ); } auto cli = std::make_shared<bts::cli::cli>( c, rpc_server ); cli->wait(); } catch ( const fc::exception& e ) { wlog( "${e}", ("e", e.to_detail_string() ) ); } return 0; }