Exemplo n.º 1
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-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;
}
Exemplo n.º 2
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;
}