2018-12-27 18:50:45 +03:00
// Copyright (c) 2014-2018 Zano Project
// Copyright (c) 2014-2018 The Louisdor Project
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
# include "include_base_utils.h"
# include "version.h"
using namespace epee ;
# include <boost/program_options.hpp>
# include "p2p/p2p_protocol_defs.h"
# include "common/command_line.h"
# include "currency_core/currency_core.h"
# include "currency_protocol/currency_protocol_handler.h"
# include "net/levin_client.h"
# include "storages/levin_abstract_invoke2.h"
# include "currency_core/currency_core.h"
# include "storages/portable_storage_template_helper.h"
# include "crypto/crypto.h"
# include "storages/http_abstract_invoke.h"
# include "net/http_client.h"
# include "currency_core/genesis_acc.h"
namespace po = boost : : program_options ;
using namespace currency ;
using namespace nodetool ;
namespace
{
const command_line : : arg_descriptor < std : : string > arg_ip = { " ip " , " set ip " } ;
const command_line : : arg_descriptor < size_t > arg_port = { " port " , " set port " } ;
const command_line : : arg_descriptor < size_t > arg_rpc_port = { " rpc-port " , " set rpc port " , RPC_DEFAULT_PORT } ;
const command_line : : arg_descriptor < uint32_t > arg_timeout = { " timeout " , " set timeout " , 5000 } ;
const command_line : : arg_descriptor < std : : string > arg_priv_key = { " private-key " , " private key to subscribe debug command " , " " , true } ;
const command_line : : arg_descriptor < uint64_t > arg_peer_id = { " peer-id " , " peerid if known(if not - will be requested) " , 0 } ;
const command_line : : arg_descriptor < bool > arg_generate_keys = { " generate-keys-pair " , " generate private and public keys pair " } ;
const command_line : : arg_descriptor < bool > arg_request_stat_info = { " request-stat-info " , " request statistics information " } ;
const command_line : : arg_descriptor < uint64_t > arg_log_journal_len = { " log-journal-len " , " Specify length of list of last error messages in log " , 0 , true } ;
const command_line : : arg_descriptor < bool > arg_request_net_state = { " request-net-state " , " request network state information (peer list, connections count) " } ;
const command_line : : arg_descriptor < bool > arg_get_daemon_info = { " rpc-get-daemon-info " , " request daemon state info vie rpc (--rpc-port option should be set ). " , " " , true } ;
const command_line : : arg_descriptor < bool > arg_get_aliases = { " rpc-get-aliases " , " request daemon aliases all list " , " " , true } ;
const command_line : : arg_descriptor < std : : string > arg_increment_build_no = { " increment-build-no " , " Increment build nimber " , " " , true } ;
const command_line : : arg_descriptor < std : : string > arg_upate_maintainers_info = { " update-maintainers-info " , " Push maintainers info into the network, update-maintainers-info=file-with-info.json " , " " , true } ;
const command_line : : arg_descriptor < std : : string > arg_update_build_no = { " update-build-no " , " Updated version number in version template file " , " " , true } ;
const command_line : : arg_descriptor < std : : string > arg_generate_genesis = { " generate-genesis " , " Generate genesis coinbase based on config file " , " " , true } ;
const command_line : : arg_descriptor < uint64_t > arg_genesis_split_amount = { " genesis-split-amount " , " Set split amount for generating genesis block " , 0 , true } ;
const command_line : : arg_descriptor < std : : string > arg_get_info_flags = { " getinfo-flags-hex " , " Set of bits for rpc-get-daemon-info " , " " , true } ;
2019-02-16 03:04:08 +03:00
const command_line : : arg_descriptor < int64_t > arg_set_peer_log_level = { " set-peer-log-level " , " Set log level for remote peer " , 0 , true } ;
const command_line : : arg_descriptor < uint64_t > arg_download_peer_log = { " download-peer-log " , " Download log from remote peer (starting offset) " , 0 , true } ;
2019-04-12 00:00:36 +02:00
const command_line : : arg_descriptor < bool > arg_do_consloe_log = { " do-console-log " , " Tool generates debug console output(debug purposes) " , " " , true } ;
2018-12-27 18:50:45 +03:00
}
typedef COMMAND_REQUEST_STAT_INFO_T < t_currency_protocol_handler < core > : : stat_info > COMMAND_REQUEST_STAT_INFO ;
struct response_schema
{
std : : string status ;
std : : string COMMAND_REQUEST_STAT_INFO_status ;
std : : string COMMAND_REQUEST_NETWORK_STATE_status ;
enableable < COMMAND_REQUEST_STAT_INFO : : response > si_rsp ;
enableable < COMMAND_REQUEST_NETWORK_STATE : : response > ns_rsp ;
BEGIN_KV_SERIALIZE_MAP ( )
KV_SERIALIZE ( status )
KV_SERIALIZE ( COMMAND_REQUEST_STAT_INFO_status )
KV_SERIALIZE ( COMMAND_REQUEST_NETWORK_STATE_status )
KV_SERIALIZE ( si_rsp )
KV_SERIALIZE ( ns_rsp )
END_KV_SERIALIZE_MAP ( )
} ;
std : : string get_response_schema_as_json ( response_schema & rs )
{
std : : stringstream ss ;
ss < < " { " < < ENDL
< < " \" status \" : \" " < < rs . status < < " \" , " < < ENDL
< < " \" COMMAND_REQUEST_NETWORK_STATE_status \" : \" " < < rs . COMMAND_REQUEST_NETWORK_STATE_status < < " \" , " < < ENDL
< < " \" COMMAND_REQUEST_STAT_INFO_status \" : \" " < < rs . COMMAND_REQUEST_STAT_INFO_status < < " \" " ;
if ( rs . si_rsp . enabled )
{
ss < < " , " < < ENDL < < " \" si_rsp \" : " < < epee : : serialization : : store_t_to_json ( rs . si_rsp . v , 1 ) ;
}
if ( rs . ns_rsp . enabled )
{
ss < < " , " < < ENDL < < " \" ns_rsp \" : { " < < ENDL
< < " \" local_time \" : " < < rs . ns_rsp . v . local_time < < " , " < < ENDL
< < " \" my_id \" : \" " < < rs . ns_rsp . v . my_id < < " \" , " < < ENDL
< < " \" up_time \" : \" " < < rs . ns_rsp . v . up_time < < " \" , " < < ENDL
< < " \" connections_list \" : [ " < < ENDL ;
size_t i = 0 ;
for ( const connection_entry & ce : rs . ns_rsp . v . connections_list )
{
ss < < " { "
" \" peer_id \" : \" " < < ce . id < < " \" , "
" \" ip \" : \" " < < string_tools : : get_ip_string_from_int32 ( ce . adr . ip ) < < " \" , "
" \" port \" : " < < ce . adr . port < < " , "
" \" time_started \" : " < < ce . time_started < < " , "
" \" last_recv \" : " < < ce . last_recv < < " , "
" \" last_send \" : " < < ce . last_send < < " , "
2019-01-28 17:34:04 +03:00
" \" version \" : \" " < < ce . version < < " \" , "
2018-12-27 18:50:45 +03:00
" \" is_income \" : " < < ce . is_income < < " } " ;
if ( rs . ns_rsp . v . connections_list . size ( ) - 1 ! = i )
ss < < " , " ;
ss < < ENDL ;
i + + ;
}
ss < < " ], " < < ENDL ;
ss < < " \" local_peerlist_white \" : [ " < < ENDL ;
i = 0 ;
for ( const peerlist_entry & pe : rs . ns_rsp . v . local_peerlist_white )
{
ss < < " { \" peer_id \" : \" " < < pe . id < < " \" , \" ip \" : \" " < < string_tools : : get_ip_string_from_int32 ( pe . adr . ip ) < < " \" , \" port \" : " < < pe . adr . port < < " , \" last_seen \" : " < < rs . ns_rsp . v . local_time - pe . last_seen < < " } " ;
if ( rs . ns_rsp . v . local_peerlist_white . size ( ) - 1 ! = i )
ss < < " , " ;
ss < < ENDL ;
i + + ;
}
ss < < " ], " < < ENDL ;
ss < < " \" local_peerlist_gray \" : [ " < < ENDL ;
i = 0 ;
for ( const peerlist_entry & pe : rs . ns_rsp . v . local_peerlist_gray )
{
ss < < " { \" peer_id \" : \" " < < pe . id < < " \" , \" ip \" : \" " < < string_tools : : get_ip_string_from_int32 ( pe . adr . ip ) < < " \" , \" port \" : " < < pe . adr . port < < " , \" last_seen \" : " < < rs . ns_rsp . v . local_time - pe . last_seen < < " } " ;
if ( rs . ns_rsp . v . local_peerlist_gray . size ( ) - 1 ! = i )
ss < < " , " ;
ss < < ENDL ;
i + + ;
}
ss < < " ] " < < ENDL < < " } " < < ENDL ;
}
ss < < " } " < < ENDL ;
return ss . str ( ) ;
}
//---------------------------------------------------------------------------------------------------------------
bool print_COMMAND_REQUEST_STAT_INFO ( const COMMAND_REQUEST_STAT_INFO : : response & si )
{
std : : cout < < " ------ COMMAND_REQUEST_STAT_INFO ------ " < < ENDL ;
std : : cout < < " Version: " < < si . version < < ENDL ;
std : : cout < < " Connections: " < < si . connections_count < < ENDL ;
std : : cout < < " INC Connections: " < < si . incoming_connections_count < < ENDL ;
std : : cout < < " Tx pool size: " < < si . payload_info . tx_pool_size < < ENDL ;
std : : cout < < " BC height: " < < si . payload_info . blockchain_height < < ENDL ;
std : : cout < < " Mining speed: " < < si . payload_info . mining_speed < < ENDL ;
std : : cout < < " Alternative blocks: " < < si . payload_info . alternative_blocks < < ENDL ;
std : : cout < < " Top block id: " < < si . payload_info . top_block_id_str < < ENDL ;
return true ;
}
//---------------------------------------------------------------------------------------------------------------
bool print_COMMAND_REQUEST_NETWORK_STATE ( const COMMAND_REQUEST_NETWORK_STATE : : response & ns )
{
std : : cout < < " ------ COMMAND_REQUEST_NETWORK_STATE ------ " < < ENDL ;
std : : cout < < " Peer id: " < < ns . my_id < < ENDL ;
std : : cout < < " Active connections: " < < ENDL ;
BOOST_FOREACH ( const connection_entry & ce , ns . connections_list )
{
std : : cout < < ce . id < < " \t " < < string_tools : : get_ip_string_from_int32 ( ce . adr . ip ) < < " : " < < ce . adr . port < < ( ce . is_income ? " (INC) " : " (OUT) " ) < < ENDL ;
}
std : : cout < < " Peer list white: " < < ns . my_id < < ENDL ;
BOOST_FOREACH ( const peerlist_entry & pe , ns . local_peerlist_white )
{
std : : cout < < pe . id < < " \t " < < string_tools : : get_ip_string_from_int32 ( pe . adr . ip ) < < " : " < < pe . adr . port < < " \t " < < misc_utils : : get_time_interval_string ( ns . local_time - pe . last_seen ) < < ENDL ;
}
std : : cout < < " Peer list gray: " < < ns . my_id < < ENDL ;
BOOST_FOREACH ( const peerlist_entry & pe , ns . local_peerlist_gray )
{
std : : cout < < pe . id < < " \t " < < string_tools : : get_ip_string_from_int32 ( pe . adr . ip ) < < " : " < < pe . adr . port < < " \t " < < misc_utils : : get_time_interval_string ( ns . local_time - pe . last_seen ) < < ENDL ;
}
return true ;
}
std : : string split_to_c_literal_lines ( const std : : string & str , size_t line_len )
{
std : : stringstream res ;
size_t current_offset = 0 ;
while ( current_offset < str . size ( ) )
{
if ( current_offset + line_len > str . size ( ) )
line_len = str . size ( ) - current_offset ;
res < < " \" " < < str . substr ( current_offset , line_len ) < < " \" " < < ENDL ;
current_offset + = line_len ;
}
return res . str ( ) ;
}
template < class t_pod >
std : : string pod_to_uint8_array ( const t_pod & v )
{
using namespace std ;
uint8_t * parray = ( uint8_t * ) & v ;
size_t count = sizeof ( t_pod ) ;
std : : stringstream ss ;
for ( size_t i = 0 ; i ! = count ; i + + )
{
ss < < ( i = = 0 ? " 0x " : " ,0x " ) < < hex < < setw ( 2 ) < < setfill ( ' 0 ' ) < < + parray [ i ] ;
}
return ss . str ( ) ;
}
template < class CharT >
std : : basic_string < CharT > buff_to_uint64_array ( const std : : basic_string < CharT > & s )
{
using namespace std ;
uint64_t * parray = ( uint64_t * ) s . data ( ) ;
size_t count = s . size ( ) / sizeof ( uint64_t ) ;
size_t rest_bytes = s . size ( ) - count * sizeof ( uint64_t ) ;
basic_stringstream < CharT > hexStream ;
hexStream < < " --------- genesis.h--------- " < < ENDL
< < " #pragma pack(push, 1) " < < ENDL
< < " struct genesis_tx_raw_data " < < ENDL
< < " { " < < ENDL
< < " uint64_t const v[ " < < count < < " ]; " < < ENDL
< < " uint8_t const r[ " < < rest_bytes < < " ]; " < < ENDL
< < " }; " < < ENDL
< < " #pragma pack(pop) " < < ENDL
< < " extern const genesis_tx_raw_data ggenesis_tx_raw; " < < ENDL
< < ENDL
< < " --------- genesis.cpp--------- " < < ENDL
< < " const genesis_tx_raw_data ggenesis_tx_raw = {{ " < < ENDL ;
;
//hexStream << hex << ; //<< noshowbase;
for ( size_t i = 0 ; i ! = count ; i + + )
{
hexStream < < ( i = = 0 ? " 0x " : " ,0x " ) < < hex < < setw ( 16 ) < < setfill ( ' 0 ' ) < < parray [ i ] ;
}
hexStream < < " }, " < < ENDL < < " { " ;
uint8_t * ptail_array = ( uint8_t * ) & parray [ count ] ;
for ( size_t i = 0 ; i ! = rest_bytes ; i + + )
{
hexStream < < ( i = = 0 ? " 0x " : " ,0x " ) < < hex < < setw ( 2 ) < < setfill ( ' 0 ' ) < < + ptail_array [ i ] ;
}
hexStream < < " }}; " < < ENDL ;
return hexStream . str ( ) ;
}
struct payment_method_summary
{
double amount_total ;
uint64_t amount_paid_this ;
double amount_usd_eq ;
} ;
void process_payment_entrie ( payment_method_summary & pms , const std : : string & amount_in_coin , uint64_t amount_in_this , const std : : string & to_usd_rate )
{
double d_amount_in_coin = std : : stod ( amount_in_coin ) ;
2019-02-21 10:27:57 +03:00
// double d_to_usd_rate = std::stod(to_usd_rate);
2018-12-27 18:50:45 +03:00
//CHECK_AND_ASSERT_THROW_MES(d_amount_in_coin, "unable to parse amount_in_coin: " << amount_in_coin);
CHECK_AND_ASSERT_THROW_MES ( amount_in_this , " unable to parse amount_this " ) ;
//CHECK_AND_ASSERT_THROW_MES(d_to_usd_rate, "unable to parse to_usd_rate: " << to_usd_rate);
pms . amount_total + = d_amount_in_coin ;
pms . amount_paid_this + = amount_in_this ;
pms . amount_usd_eq + = d_amount_in_coin * d_amount_in_coin ;
}
uint64_t get_total_from_payments_stat ( const std : : map < std : : string , payment_method_summary > & payments_stat )
{
uint64_t total_this = 0 ;
for ( const auto & se : payments_stat )
{
total_this + = se . second . amount_paid_this ;
}
return total_this ;
}
bool generate_genesis ( const std : : string & path_config , uint64_t premine_split_amount )
{
TIME_MEASURE_START_MS ( load_json_time ) ;
currency : : genesis_config_json_struct gcp = AUTO_VAL_INIT ( gcp ) ;
if ( ! epee : : serialization : : load_t_from_json_file ( gcp , path_config ) )
{
LOG_ERROR ( " Failed to open JSON file from " < < path_config ) ;
return false ;
}
TIME_MEASURE_FINISH_MS ( load_json_time ) ;
TIME_MEASURE_START_MS ( loading_to_map ) ;
std : : map < std : : string , uint64_t > amounts_map ;
for ( auto & p : gcp . payments )
{
p . amount_this_coin_int = std : : round ( p . amount_this_coin_fl * COIN ) ;
amounts_map [ p . address_this ] = p . amount_this_coin_int ;
}
TIME_MEASURE_FINISH_MS ( loading_to_map ) ;
TIME_MEASURE_START_MS ( loading_to_map2 ) ;
std : : map < std : : string , uint64_t > amounts_map2 ;
auto hint_it = amounts_map2 . insert ( * amounts_map . begin ( ) ) . first ;
for ( auto it = + + amounts_map . begin ( ) ; it ! = amounts_map . end ( ) ; it + + )
{
hint_it = amounts_map2 . insert ( hint_it , * it ) ;
}
TIME_MEASURE_FINISH_MS ( loading_to_map2 ) ;
std : : cout < < " path: " < < path_config < < ENDL < < " items " < < amounts_map . size ( )
< < " , load_json_time: " < < load_json_time
< < " , loading_to_map: " < < loading_to_map
< < " , loading_to_map2: " < < loading_to_map2 < < ENDL ;
currency : : block bl = boost : : value_initialized < block > ( ) ;
std : : vector < tx_destination_entry > destinations ;
tx_destination_entry de = AUTO_VAL_INIT ( de ) ;
de . addr . resize ( 1 ) ;
std : : map < std : : string , payment_method_summary > payments_stat ;
//make sure it initialized with zeros
payments_stat [ " qtum " ] = payments_stat [ " bch " ]
= payments_stat [ " rep " ] = payments_stat [ " dash " ]
= payments_stat [ " ltc " ] = payments_stat [ " eos " ]
= payments_stat [ " eth " ] = payments_stat [ " btc " ]
= payments_stat [ " prm " ]
= AUTO_VAL_INIT_T ( payment_method_summary ) ;
uint64_t summary_premine_coins = 0 ;
for ( auto & p : gcp . payments )
{
bool r = get_account_address_from_str ( de . addr . back ( ) , p . address_this ) ;
CHECK_AND_ASSERT_MES ( r , false , " wrong address string: " < < p . address_this ) ;
de . amount = p . amount_this_coin_int ; //std::cout << de.amount << ENDL;
summary_premine_coins + = de . amount ;
destinations . push_back ( de ) ;
# define PROCESS_XXX_COIN_ENTRIE(ticker) else if (!p.paid_ ## ticker.empty()) \
{ \
process_payment_entrie ( payments_stat [ # ticker ] , p . paid_ # # ticker , p . amount_this_coin_int , p . ticker # # _usd_price ) ; \
}
if ( false ) { }
PROCESS_XXX_COIN_ENTRIE ( qtum )
PROCESS_XXX_COIN_ENTRIE ( bch )
PROCESS_XXX_COIN_ENTRIE ( rep )
PROCESS_XXX_COIN_ENTRIE ( dash )
PROCESS_XXX_COIN_ENTRIE ( ltc )
PROCESS_XXX_COIN_ENTRIE ( eos )
PROCESS_XXX_COIN_ENTRIE ( eth )
PROCESS_XXX_COIN_ENTRIE ( btc )
PROCESS_XXX_COIN_ENTRIE ( prm )
PROCESS_XXX_COIN_ENTRIE ( xmr )
// self check
if ( summary_premine_coins ! = get_total_from_payments_stat ( payments_stat ) )
{
LOG_ERROR ( " Internal error: missmatch of balances " ) ;
}
}
uint64_t total_this = 0 ;
double total_usd_eq = 0 ;
2019-01-14 22:38:44 +03:00
# define COLUMN_INTERVAL_LAYOUT 30
2018-12-27 18:50:45 +03:00
std : : stringstream ss ;
ss . precision ( 10 ) ;
2019-01-14 22:38:44 +03:00
ss < < std : : setw ( COLUMN_INTERVAL_LAYOUT ) < < std : : left < < " NAME " < < std : : setw ( COLUMN_INTERVAL_LAYOUT ) < < std : : left < < " AMOUNT " < < std : : setw ( COLUMN_INTERVAL_LAYOUT ) < < std : : left < < " AMOUNT THIS " < < std : : setw ( COLUMN_INTERVAL_LAYOUT ) < < std : : left < < " USD EQ " < < ENDL ;
2018-12-27 18:50:45 +03:00
for ( auto & se : payments_stat )
{
2019-01-14 22:38:44 +03:00
ss < < std : : setw ( COLUMN_INTERVAL_LAYOUT ) < < std : : left < < se . first < < std : : setw ( COLUMN_INTERVAL_LAYOUT ) < < std : : fixed < < std : : left < < se . second . amount_total < < std : : setw ( COLUMN_INTERVAL_LAYOUT ) < < std : : fixed < < std : : left < < print_money ( se . second . amount_paid_this ) < < std : : setw ( COLUMN_INTERVAL_LAYOUT ) < < std : : fixed < < std : : left < < se . second . amount_usd_eq < < ENDL ;
2018-12-27 18:50:45 +03:00
total_this + = se . second . amount_paid_this ;
total_usd_eq + = se . second . amount_usd_eq ;
}
2019-01-14 22:38:44 +03:00
ss < < ENDL < < std : : setw ( COLUMN_INTERVAL_LAYOUT ) < < std : : left < < " TOTAL " < < std : : setw ( COLUMN_INTERVAL_LAYOUT ) < < std : : fixed < < std : : left < < " " < < std : : setw ( COLUMN_INTERVAL_LAYOUT ) < < std : : fixed < < std : : left < < print_money ( total_this ) < < std : : setw ( COLUMN_INTERVAL_LAYOUT ) < < std : : fixed < < std : : left < < total_usd_eq < < ENDL ;
2018-12-27 18:50:45 +03:00
2019-01-14 22:38:44 +03:00
ss < < ENDL < < std : : setw ( COLUMN_INTERVAL_LAYOUT ) < < std : : left < < " PREMINE_AMOUNT " < < std : : setw ( COLUMN_INTERVAL_LAYOUT ) < < std : : fixed < < std : : left < < " " < < std : : setw ( COLUMN_INTERVAL_LAYOUT ) < < std : : fixed < < std : : left < < total_this < < " ( " < < print_money ( total_this ) < < " THIS) " < < ENDL ;
2018-12-27 18:50:45 +03:00
epee : : log_space : : set_console_color ( epee : : log_space : : console_colors : : console_color_magenta , true ) ;
std : : cout < < " GENESIS STAT: " < < ENDL < < ss . str ( ) ;
epee : : log_space : : set_console_color ( epee : : log_space : : console_colors : : console_color_default , false ) ;
bool r = file_io_utils : : save_string_to_file ( path_config + " .premine_stat.txt " , ss . str ( ) ) ;
ss . str ( " " ) ;
ss . clear ( ) ;
2019-05-08 17:20:43 +02:00
std : : cout < < ENDL < < " PROOF PHRASE: " < < gcp . proof_string < < ENDL ;
2018-12-27 18:50:45 +03:00
construct_miner_tx ( 0 , 0 , 0 , 0 , 0 , destinations , bl . miner_tx , gcp . proof_string , CURRENCY_MINER_TX_MAX_OUTS ) ;
currency : : blobdata txb = tx_to_blob ( bl . miner_tx ) ;
//self validate block
if ( currency : : get_outs_money_amount ( bl . miner_tx ) ! = total_this | | summary_premine_coins ! = total_this )
{
LOG_ERROR ( " Internal error: total_this = " < < total_this < < " didn't match with miner_tx total = " < < currency : : get_outs_money_amount ( bl . miner_tx ) ) ;
}
std : : string hex_tx_represent = string_tools : : buff_to_hex_nodelimer ( txb ) ;
std : : string uint64_t_array_represent = /*string_tools::*/ buff_to_uint64_array ( txb ) ;
r = file_io_utils : : save_string_to_file ( path_config + " .genesis.txt " , hex_tx_represent ) ;
CHECK_AND_ASSERT_MES_NO_RET ( r , " failed to create " < < path_config < < " .genesis.txt " ) ;
r = file_io_utils : : save_string_to_file ( path_config + " .genesis.uint64.array.txt " , uint64_t_array_represent ) ;
CHECK_AND_ASSERT_MES_NO_RET ( r , " failed to create " < < path_config < < " .genesis.uint64.array.txt " ) ;
//generate address dictionary
std : : map < uint64_t , uint64_t > ordered_keys ;
uint64_t i = 0 ;
for ( auto & p : gcp . payments )
{
uint64_t key = currency : : get_string_uint64_hash ( p . address_this ) ;
auto it = ordered_keys . find ( key ) ;
if ( it ! = ordered_keys . end ( ) )
{
LOG_ERROR ( " Collision found on address " < < p . address_this < < " key: " < < key < < " offset_associated: " < < it - > second ) ;
return false ;
}
ordered_keys [ key ] = i ;
i + + ;
}
//dump it to file
ss < < " -------------genesis_acc.cpp------------- " < < ENDL
< < " const std::string ggenesis_tx_pub_key_str = \" " < < string_tools : : pod_to_hex ( get_tx_pub_key_from_extra ( bl . miner_tx ) ) < < " \" ; " < < ENDL ;
ss < < " const crypto::public_key ggenesis_tx_pub_key = epee::string_tools::parse_tpod_from_hex_string<crypto::public_key>(ggenesis_tx_pub_key_str); " < < ENDL
< < " extern const genesis_tx_dictionary_entry ggenesis_dict[ " < < ordered_keys . size ( ) < < " ]; " < < ENDL
< < " const genesis_tx_dictionary_entry ggenesis_dict[ " < < ordered_keys . size ( ) < < " ] = { " ;
for ( auto it = ordered_keys . begin ( ) ; it ! = ordered_keys . end ( ) ; it + + )
{
ss < < ( it = = ordered_keys . begin ( ) ? " " : " , " ) < < ENDL < < " { " < < it - > first < < " ULL, " < < it - > second < < " } " ;
}
ss < < ENDL < < " }; " < < ENDL ;
r = file_io_utils : : save_string_to_file ( path_config + " .genesis.dictionary.txt " , ss . str ( ) ) ;
CHECK_AND_ASSERT_MES_NO_RET ( r , " failed to create " < < path_config < < " .genesis.dictionary.txt " ) ;
return true ;
}
2019-01-14 22:38:44 +03:00
# undef COLUMN_INTERVAL_LAYOUT
2018-12-27 18:50:45 +03:00
//---------------------------------------------------------------------------------------------------------------
bool handle_get_aliases ( po : : variables_map & vm )
{
if ( ! command_line : : has_arg ( vm , arg_rpc_port ) )
{
std : : cout < < " { " < < ENDL < < " \" status \" : \" ERROR: " < < " RPC port not set \" " < < ENDL < < " } " < < ENDL ;
return false ;
}
epee : : net_utils : : http : : http_simple_client http_client ;
currency : : COMMAND_RPC_GET_ALL_ALIASES : : request req = AUTO_VAL_INIT ( req ) ;
currency : : COMMAND_RPC_GET_ALL_ALIASES : : response res = AUTO_VAL_INIT ( res ) ;
std : : string daemon_addr = command_line : : get_arg ( vm , arg_ip ) + " : " + std : : to_string ( command_line : : get_arg ( vm , arg_rpc_port ) ) ;
bool r = epee : : net_utils : : invoke_http_json_rpc ( daemon_addr + " /json_rpc " , " get_all_alias_details " , req , res , http_client , command_line : : get_arg ( vm , arg_timeout ) ) ;
if ( ! r )
{
std : : cout < < " { " < < ENDL < < " \" status \" : \" ERROR: " < < " Failed to invoke request \" " < < ENDL < < " } " < < ENDL ;
return false ;
}
std : : cout < < epee : : serialization : : store_t_to_json ( res ) ;
return true ;
}
//---------------------------------------------------------------------------------------------------------------
bool handle_get_daemon_info ( po : : variables_map & vm )
{
if ( ! command_line : : has_arg ( vm , arg_rpc_port ) )
{
std : : cout < < " ERROR: rpc port not set " < < ENDL ;
return false ;
}
currency : : COMMAND_RPC_GET_INFO : : request req = AUTO_VAL_INIT ( req ) ;
currency : : COMMAND_RPC_GET_INFO : : response res = AUTO_VAL_INIT ( res ) ;
if ( command_line : : has_arg ( vm , arg_get_info_flags ) )
{
std : : string flags_str = command_line : : get_arg ( vm , arg_get_info_flags ) ;
if ( ! epee : : string_tools : : get_xnum_from_hex_string ( flags_str , req . flags ) )
{
LOG_ERROR ( " Wrong flags specified, reset to all flags " ) ;
req . flags = COMMAND_RPC_GET_INFO_FLAG_ALL_FLAGS ;
}
}
else
{
//very slow case
req . flags = COMMAND_RPC_GET_INFO_FLAG_ALL_FLAGS ;
}
epee : : net_utils : : http : : http_simple_client http_client ;
std : : string daemon_addr = command_line : : get_arg ( vm , arg_ip ) + " : " + std : : to_string ( command_line : : get_arg ( vm , arg_rpc_port ) ) ;
std : : string url = daemon_addr + " /getinfo " ;
bool r = net_utils : : invoke_http_json_remote_command2 ( url , req , res , http_client , command_line : : get_arg ( vm , arg_timeout ) ) ;
if ( ! r )
{
std : : cout < < " ERROR: failed to invoke request to " < < url < < ENDL ;
return false ;
}
# define PRINT_FIELD_NAME(owner_object, prefix, field_name) << prefix #field_name ": " << owner_object.field_name << ENDL
std : : cout < < " OK " < < ENDL
< < " height: " < < res . height < < ENDL
< < " pos_difficulty: " < < res . pos_difficulty < < ENDL
< < " pow_difficulty: " < < res . pow_difficulty < < ENDL
< < " tx_count: " < < res . tx_count < < ENDL
< < " tx_pool_size: " < < res . tx_pool_size < < ENDL
< < " alt_blocks_count: " < < res . alt_blocks_count < < ENDL
< < " outgoing_connections_count: " < < res . outgoing_connections_count < < ENDL
< < " incoming_connections_count: " < < res . incoming_connections_count < < ENDL
< < " white_peerlist_size: " < < res . white_peerlist_size < < ENDL
< < " grey_peerlist_size: " < < res . grey_peerlist_size < < ENDL
< < " current_network_hashrate_50: " < < res . current_network_hashrate_50 < < ENDL
< < " current_network_hashrate_350: " < < res . current_network_hashrate_350 < < ENDL
< < " seconds_between_10_blocks: " < < res . seconds_for_10_blocks < < ENDL
< < " seconds_between_30_blocks: " < < res . seconds_for_30_blocks < < ENDL
< < " alias_count: " < < res . alias_count < < ENDL
< < " transactions_cnt_per_day: " < < res . transactions_cnt_per_day < < ENDL
< < " transactions_volume_per_day: " < < res . transactions_volume_per_day < < ENDL
< < " pos_sequence_factor: " < < res . pos_sequence_factor < < ENDL
< < " pow_sequence_factor: " < < res . pow_sequence_factor < < ENDL
< < " last_pos_timestamp: " < < res . last_pos_timestamp < < ENDL
< < " last_pow_timestamp: " < < res . last_pow_timestamp < < ENDL
2019-04-10 22:44:57 +02:00
< < " total_coins: " < < res . total_coins < < ENDL
2018-12-27 18:50:45 +03:00
< < " pos_difficulty_in_coins: " < < currency : : wide_difficulty_type ( res . pos_difficulty ) / COIN < < ENDL
< < " block_reward: " < < res . block_reward < < ENDL
< < " last_block_total_reward: " < < res . last_block_total_reward < < ENDL
< < " outs_stat_amount1_0_001: " < < res . outs_stat . amount_0_001 < < ENDL
< < " outs_stat_amount2_0_01: " < < res . outs_stat . amount_0_01 < < ENDL
< < " outs_stat_amount3_0_1: " < < res . outs_stat . amount_0_1 < < ENDL
< < " outs_stat_amount4_1: " < < res . outs_stat . amount_10 < < ENDL
< < " outs_stat_amount5_10: " < < res . outs_stat . amount_10 < < ENDL
< < " outs_stat_amount6_100: " < < res . outs_stat . amount_100 < < ENDL
< < " outs_stat_amount7_1000: " < < res . outs_stat . amount_1000 < < ENDL
< < " outs_stat_amount8_10000: " < < res . outs_stat . amount_10000 < < ENDL
< < " outs_stat_amount9_100000: " < < res . outs_stat . amount_100000 < < ENDL
< < " outs_stat_amount10_1000000: " < < res . outs_stat . amount_1000000 < < ENDL
< < " current_max_allowed_block_size: " < < res . current_max_allowed_block_size < < ENDL
< < " last_block_size: " < < res . last_block_size < < ENDL
< < " tx_count_in_last_block: " < < res . tx_count_in_last_block < < ENDL
< < " pos_diff_total_coins_rate: " < < res . pos_diff_total_coins_rate < < ENDL
< < " pos_block_ts_shift_vs_actual: " < < res . pos_block_ts_shift_vs_actual < < ENDL
< < " block_processing_time_0: " < < res . performance_data . block_processing_time_0 < < ENDL
< < " block_processing_time_1: " < < res . performance_data . block_processing_time_1 < < ENDL
< < " etc_stuff_6: " < < res . performance_data . etc_stuff_6 < < ENDL
< < " insert_time_4: " < < res . performance_data . insert_time_4 < < ENDL
< < " longhash_calculating_time_3: " < < res . performance_data . longhash_calculating_time_3 < < ENDL
< < " raise_block_core_event: " < < res . performance_data . raise_block_core_event < < ENDL
< < " target_calculating_time_2: " < < res . performance_data . target_calculating_time_2 < < ENDL
2019-04-17 19:22:51 +02:00
< < " target_calculating_enum_blocks: " < < res . performance_data . target_calculating_enum_blocks < < ENDL
< < " target_calculating_calc: " < < res . performance_data . target_calculating_calc < < ENDL
2018-12-27 18:50:45 +03:00
< < " all_txs_insert_time_5: " < < res . performance_data . all_txs_insert_time_5 < < ENDL
< < " tx_add_one_tx_time: " < < res . performance_data . tx_add_one_tx_time < < ENDL
< < " tx_check_inputs_time: " < < res . performance_data . tx_check_inputs_time < < ENDL
< < " tx_process_attachment: " < < res . performance_data . tx_process_attachment < < ENDL
< < " tx_process_extra: " < < res . performance_data . tx_process_extra < < ENDL
< < " tx_process_inputs: " < < res . performance_data . tx_process_inputs < < ENDL
< < " tx_push_global_index: " < < res . performance_data . tx_push_global_index < < ENDL
< < " tx_check_exist: " < < res . performance_data . tx_check_exist < < ENDL
< < " tx_store_db: " < < res . performance_data . tx_store_db < < ENDL
< < " db_tx_count: " < < res . performance_data . tx_count < < ENDL
< < " db_writer_tx_count: " < < res . performance_data . writer_tx_count < < ENDL
< < " db_map_size: " < < res . performance_data . map_size < < ENDL
< < " market_size: " < < res . offers_count < < ENDL
PRINT_FIELD_NAME ( res . performance_data , " " , tx_print_log )
PRINT_FIELD_NAME ( res . performance_data , " " , tx_prapare_append )
PRINT_FIELD_NAME ( res . performance_data , " " , tx_append_time )
PRINT_FIELD_NAME ( res . performance_data , " " , tx_append_rl_wait )
PRINT_FIELD_NAME ( res . performance_data , " " , tx_append_is_expired )
PRINT_FIELD_NAME ( res . performance_data , " " , tx_check_inputs_prefix_hash )
PRINT_FIELD_NAME ( res . performance_data , " " , tx_check_inputs_attachment_check )
PRINT_FIELD_NAME ( res . performance_data , " " , tx_check_inputs_loop )
PRINT_FIELD_NAME ( res . performance_data , " " , tx_check_inputs_loop_kimage_check )
PRINT_FIELD_NAME ( res . performance_data , " " , tx_check_inputs_loop_ch_in_val_sig )
PRINT_FIELD_NAME ( res . performance_data , " " , tx_check_inputs_loop_scan_outputkeys_get_item_size )
PRINT_FIELD_NAME ( res . performance_data , " " , tx_check_inputs_loop_scan_outputkeys_relative_to_absolute )
PRINT_FIELD_NAME ( res . performance_data , " " , tx_check_inputs_loop_scan_outputkeys_loop )
PRINT_FIELD_NAME ( res . performance_data , " " , tx_check_inputs_loop_scan_outputkeys_loop_get_subitem )
PRINT_FIELD_NAME ( res . performance_data , " " , tx_check_inputs_loop_scan_outputkeys_loop_find_tx )
PRINT_FIELD_NAME ( res . performance_data , " " , tx_check_inputs_loop_scan_outputkeys_loop_handle_output )
PRINT_FIELD_NAME ( res . tx_pool_performance_data , " pool_ " , tx_processing_time )
PRINT_FIELD_NAME ( res . tx_pool_performance_data , " pool_ " , check_inputs_types_supported_time )
PRINT_FIELD_NAME ( res . tx_pool_performance_data , " pool_ " , expiration_validate_time )
PRINT_FIELD_NAME ( res . tx_pool_performance_data , " pool_ " , validate_amount_time )
PRINT_FIELD_NAME ( res . tx_pool_performance_data , " pool_ " , validate_alias_time )
PRINT_FIELD_NAME ( res . tx_pool_performance_data , " pool_ " , check_keyimages_ws_ms_time )
PRINT_FIELD_NAME ( res . tx_pool_performance_data , " pool_ " , check_inputs_time )
PRINT_FIELD_NAME ( res . tx_pool_performance_data , " pool_ " , begin_tx_time )
PRINT_FIELD_NAME ( res . tx_pool_performance_data , " pool_ " , update_db_time )
PRINT_FIELD_NAME ( res . tx_pool_performance_data , " pool_ " , db_commit_time ) ;
return true ;
}
//---------------------------------------------------------------------------------------------------------------
bool handle_request_stat ( po : : variables_map & vm , peerid_type peer_id )
{
if ( ! command_line : : has_arg ( vm , arg_priv_key ) )
{
std : : cout < < " { " < < ENDL < < " \" status \" : \" ERROR: " < < " secret key not set \" " < < ENDL < < " } " < < ENDL ;
return false ;
}
crypto : : secret_key prvk = AUTO_VAL_INIT ( prvk ) ;
if ( ! string_tools : : hex_to_pod ( command_line : : get_arg ( vm , arg_priv_key ) , prvk ) )
{
std : : cout < < " { " < < ENDL < < " \" status \" : \" ERROR: " < < " wrong secret key set \" " < < ENDL < < " } " < < ENDL ;
return false ;
}
response_schema rs = AUTO_VAL_INIT ( rs ) ;
levin : : levin_client_impl2 transport ;
if ( ! transport . connect ( command_line : : get_arg ( vm , arg_ip ) , static_cast < int > ( command_line : : get_arg ( vm , arg_port ) ) , static_cast < int > ( command_line : : get_arg ( vm , arg_timeout ) ) ) )
{
std : : cout < < " { " < < ENDL < < " \" status \" : \" ERROR: " < < " Failed to connect to " < < command_line : : get_arg ( vm , arg_ip ) < < " : " < < command_line : : get_arg ( vm , arg_port ) < < " \" " < < ENDL < < " } " < < ENDL ;
return false ;
} else
rs . status = " OK " ;
if ( ! peer_id )
{
COMMAND_REQUEST_PEER_ID : : request req = AUTO_VAL_INIT ( req ) ;
COMMAND_REQUEST_PEER_ID : : response rsp = AUTO_VAL_INIT ( rsp ) ;
if ( ! net_utils : : invoke_remote_command2 ( COMMAND_REQUEST_PEER_ID : : ID , req , rsp , transport ) )
{
std : : cout < < " { " < < ENDL < < " \" status \" : \" ERROR: " < < " Failed to connect to " < < command_line : : get_arg ( vm , arg_ip ) < < " : " < < command_line : : get_arg ( vm , arg_port ) < < " \" " < < ENDL < < " } " < < ENDL ;
return false ;
} else
{
peer_id = rsp . my_id ;
}
}
nodetool : : proof_of_trust pot = AUTO_VAL_INIT ( pot ) ;
pot . peer_id = peer_id ;
pot . time = time ( NULL ) ;
crypto : : public_key pubk = AUTO_VAL_INIT ( pubk ) ;
string_tools : : hex_to_pod ( P2P_MAINTAINERS_PUB_KEY , pubk ) ;
crypto : : hash h = tools : : get_proof_of_trust_hash ( pot ) ;
crypto : : generate_signature ( h , pubk , prvk , pot . sign ) ;
if ( command_line : : get_arg ( vm , arg_request_stat_info ) )
{
uint64_t log_journal_len = 10 ;
if ( command_line : : has_arg ( vm , arg_log_journal_len ) )
log_journal_len = command_line : : get_arg ( vm , arg_log_journal_len ) ;
COMMAND_REQUEST_STAT_INFO : : request req = AUTO_VAL_INIT ( req ) ;
req . pr . chain_len = 3 ;
req . pr . logs_journal_len = log_journal_len ;
req . tr = pot ;
if ( ! net_utils : : invoke_remote_command2 ( COMMAND_REQUEST_STAT_INFO : : ID , req , rs . si_rsp . v , transport ) )
{
std : : stringstream ss ;
ss < < " ERROR: " < < " Failed to invoke remote command COMMAND_REQUEST_STAT_INFO to " < < command_line : : get_arg ( vm , arg_ip ) < < " : " < < command_line : : get_arg ( vm , arg_port ) ;
rs . COMMAND_REQUEST_STAT_INFO_status = ss . str ( ) ;
} else
{
rs . si_rsp . enabled = true ;
rs . COMMAND_REQUEST_STAT_INFO_status = " OK " ;
}
}
if ( command_line : : get_arg ( vm , arg_request_net_state ) )
{
+ + pot . time ;
h = tools : : get_proof_of_trust_hash ( pot ) ;
crypto : : generate_signature ( h , pubk , prvk , pot . sign ) ;
COMMAND_REQUEST_NETWORK_STATE : : request req = AUTO_VAL_INIT ( req ) ;
req . tr = pot ;
if ( ! net_utils : : invoke_remote_command2 ( COMMAND_REQUEST_NETWORK_STATE : : ID , req , rs . ns_rsp . v , transport ) )
{
std : : stringstream ss ;
ss < < " ERROR: " < < " Failed to invoke remote command COMMAND_REQUEST_NETWORK_STATE to " < < command_line : : get_arg ( vm , arg_ip ) < < " : " < < command_line : : get_arg ( vm , arg_port ) ;
rs . COMMAND_REQUEST_NETWORK_STATE_status = ss . str ( ) ;
} else
{
rs . ns_rsp . enabled = true ;
rs . COMMAND_REQUEST_NETWORK_STATE_status = " OK " ;
}
}
std : : cout < < get_response_schema_as_json ( rs ) ;
return true ;
}
//---------------------------------------------------------------------------------------------------------------
bool get_private_key ( crypto : : secret_key & pk , po : : variables_map & vm )
{
if ( ! command_line : : has_arg ( vm , arg_priv_key ) )
{
std : : cout < < " ERROR: secret key not set " < < ENDL ;
return false ;
}
if ( ! string_tools : : hex_to_pod ( command_line : : get_arg ( vm , arg_priv_key ) , pk ) )
{
std : : cout < < " ERROR: wrong secret key set " < < ENDL ;
return false ;
}
crypto : : public_key pubkey = AUTO_VAL_INIT ( pubkey ) ;
if ( ! crypto : : secret_key_to_public_key ( pk , pubkey ) )
{
std : : cout < < " ERROR: wrong secret key set(secret_key_to_public_key failed) " < < ENDL ;
return false ;
}
if ( pubkey ! = tools : : get_public_key_from_string ( P2P_MAINTAINERS_PUB_KEY ) )
{
std : : cout < < " ERROR: wrong secret key set(public keys not match) " < < ENDL ;
return false ;
}
return true ;
}
//---------------------------------------------------------------------------------------------------------------
bool handle_increment_build_no ( po : : variables_map & vm )
{
std : : string path = command_line : : get_arg ( vm , arg_increment_build_no ) ;
if ( ! path . size ( ) )
{
std : : cout < < " no argument for increment_build_no " < < ENDL ;
return false ;
}
std : : string target_buff ;
if ( ! file_io_utils : : load_file_to_string ( path , target_buff ) )
{
std : : cout < < " noFailed to read file " < < path < < ENDL ;
return false ;
}
std : : string pattern = " #define PROJECT_VERSION_BUILD_NO " ;
std : : string : : size_type templ_offet = target_buff . find ( pattern ) ;
if ( templ_offet = = std : : string : : npos )
{
std : : cout < < " Filed to find pattern in " < < path < < ENDL ;
return false ;
}
std : : string : : size_type p = target_buff . find ( ' \n ' , templ_offet + pattern . size ( ) ) ;
if ( p = = std : : string : : npos )
{
std : : cout < < " Filed to find pattern in " < < path < < ENDL ;
return false ;
}
//for windows-like line endings
if ( target_buff [ p - 1 ] = = ' \r ' )
- - p ;
std : : string build_no_str = target_buff . substr ( templ_offet + pattern . size ( ) , p - ( templ_offet + pattern . size ( ) ) ) ;
build_no_str = string_tools : : trim ( build_no_str ) ;
uint64_t build_num = 0 ;
if ( ! string_tools : : get_xtype_from_string ( build_num , build_no_str ) )
{
std : : cout < < " Filed to find pattern in " < < path < < ENDL ;
return false ;
}
+ + build_num ;
target_buff . erase ( templ_offet + pattern . size ( ) , p - ( templ_offet + pattern . size ( ) ) ) ;
target_buff . insert ( templ_offet + pattern . size ( ) , std : : to_string ( build_num ) ) ;
if ( ! file_io_utils : : save_string_to_file ( path , target_buff ) )
{
std : : cout < < " Filed to save file " < < path < < ENDL ;
return false ;
}
std : : cout < < " SUCCESSFULLY INCREMENTED: " < < build_num < < ENDL ;
return true ;
}
//---------------------------------------------------------------------------------------------------------------
bool handle_update_maintainers_info ( po : : variables_map & vm )
{
if ( ! command_line : : has_arg ( vm , arg_rpc_port ) )
{
std : : cout < < " ERROR: rpc port not set " < < ENDL ;
return false ;
}
crypto : : secret_key prvk = AUTO_VAL_INIT ( prvk ) ;
if ( ! get_private_key ( prvk , vm ) )
{
std : : cout < < " ERROR: secret key error " < < ENDL ;
return false ;
}
std : : string path = command_line : : get_arg ( vm , arg_upate_maintainers_info ) ;
epee : : net_utils : : http : : http_simple_client http_client ;
currency : : COMMAND_RPC_SET_MAINTAINERS_INFO : : request req = AUTO_VAL_INIT ( req ) ;
currency : : COMMAND_RPC_SET_MAINTAINERS_INFO : : response res = AUTO_VAL_INIT ( res ) ;
maintainers_info mi = AUTO_VAL_INIT ( mi ) ;
bool r = epee : : serialization : : load_t_from_json_file ( mi , path ) ;
CHECK_AND_ASSERT_MES ( r , false , " Failed to load maintainers_info from json file: " < < path ) ;
mi . timestamp = time ( NULL ) ;
std : : cout < < " timestamp: " < < mi . timestamp < < ENDL ;
epee : : serialization : : store_t_to_binary ( mi , req . maintainers_info_buff ) ;
crypto : : generate_signature ( currency : : get_blob_hash ( req . maintainers_info_buff ) , tools : : get_public_key_from_string ( P2P_MAINTAINERS_PUB_KEY ) , prvk , req . sign ) ;
std : : string daemon_addr = command_line : : get_arg ( vm , arg_ip ) + " : " + std : : to_string ( command_line : : get_arg ( vm , arg_rpc_port ) ) ;
r = net_utils : : invoke_http_bin_remote_command2 ( daemon_addr + " /set_maintainers_info.bin " , req , res , http_client , command_line : : get_arg ( vm , arg_timeout ) ) ;
if ( ! r )
{
std : : cout < < " ERROR: failed to invoke request " < < ENDL ;
return false ;
}
if ( res . status ! = CORE_RPC_STATUS_OK )
{
std : : cout < < " ERROR: failed to update maintainers info: " < < res . status < < ENDL ;
return false ;
}
std : : cout < < " OK " < < ENDL ;
return true ;
}
//---------------------------------------------------------------------------------------------------------------
bool generate_and_print_keys ( )
{
crypto : : public_key pk = AUTO_VAL_INIT ( pk ) ;
crypto : : secret_key sk = AUTO_VAL_INIT ( sk ) ;
generate_keys ( pk , sk ) ;
std : : cout < < " PUBLIC KEY: " < < epee : : string_tools : : pod_to_hex ( pk ) < < ENDL
< < " PRIVATE KEY: " < < epee : : string_tools : : pod_to_hex ( sk ) ;
return true ;
}
2019-02-16 03:04:08 +03:00
//---------------------------------------------------------------------------------------------------------------
template < class command_t >
bool invoke_debug_command ( po : : variables_map & vm , const crypto : : secret_key & sk , levin : : levin_client_impl2 & transport , peerid_type & peer_id , typename command_t : : request & req , typename command_t : : response & rsp )
{
if ( ! transport . is_connected ( ) )
{
if ( ! transport . connect ( command_line : : get_arg ( vm , arg_ip ) , static_cast < int > ( command_line : : get_arg ( vm , arg_port ) ) , static_cast < int > ( command_line : : get_arg ( vm , arg_timeout ) ) ) )
{
std : : cout < < " { " < < ENDL < < " \" status \" : \" ERROR: " < < " Failed to connect to " < < command_line : : get_arg ( vm , arg_ip ) < < " : " < < command_line : : get_arg ( vm , arg_port ) < < " \" " < < ENDL < < " } " < < ENDL ;
return false ;
}
}
if ( ! peer_id )
{
COMMAND_REQUEST_PEER_ID : : request id_req = AUTO_VAL_INIT ( id_req ) ;
COMMAND_REQUEST_PEER_ID : : response id_rsp = AUTO_VAL_INIT ( id_rsp ) ;
if ( ! net_utils : : invoke_remote_command2 ( COMMAND_REQUEST_PEER_ID : : ID , id_req , id_rsp , transport ) )
{
std : : cout < < " { " < < ENDL < < " \" status \" : \" ERROR: " < < " Failed to connect to " < < command_line : : get_arg ( vm , arg_ip ) < < " : " < < command_line : : get_arg ( vm , arg_port ) < < " \" " < < ENDL < < " } " < < ENDL ;
return false ;
}
else
{
peer_id = id_rsp . my_id ;
}
}
nodetool : : proof_of_trust pot = AUTO_VAL_INIT ( pot ) ;
pot . peer_id = peer_id ;
pot . time = time ( NULL ) ;
crypto : : public_key pubk = AUTO_VAL_INIT ( pubk ) ;
string_tools : : hex_to_pod ( P2P_MAINTAINERS_PUB_KEY , pubk ) ;
crypto : : hash h = tools : : get_proof_of_trust_hash ( pot ) ;
crypto : : generate_signature ( h , pubk , sk , pot . sign ) ;
req . tr = pot ;
return net_utils : : invoke_remote_command2 ( command_t : : ID , req , rsp , transport ) ;
}
//---------------------------------------------------------------------------------------------------------------
bool handle_set_peer_log_level ( po : : variables_map & vm )
{
crypto : : secret_key sk = AUTO_VAL_INIT ( sk ) ;
if ( ! get_private_key ( sk , vm ) )
{
std : : cout < < " ERROR: secret key error " < < ENDL ;
return false ;
}
int64_t log_level = command_line : : get_arg ( vm , arg_set_peer_log_level ) ;
if ( log_level < LOG_LEVEL_0 | | log_level > LOG_LEVEL_MAX )
{
std : : cout < < " Error: invalid log level value: " < < log_level < < ENDL ;
return false ;
}
2018-12-27 18:50:45 +03:00
2019-02-16 03:04:08 +03:00
levin : : levin_client_impl2 transport ;
peerid_type peer_id = 0 ;
COMMAND_SET_LOG_LEVEL : : request req = AUTO_VAL_INIT ( req ) ;
req . new_log_level = log_level ;
COMMAND_SET_LOG_LEVEL : : response rsp = AUTO_VAL_INIT ( rsp ) ;
if ( ! invoke_debug_command < COMMAND_SET_LOG_LEVEL > ( vm , sk , transport , peer_id , req , rsp ) )
{
std : : cout < < " ERROR: invoking COMMAND_SET_LOG_LEVEL failed " < < ENDL ;
return false ;
}
std : : cout < < " OK! Log level changed: " < < rsp . old_log_level < < " -> " < < rsp . current_log_level < < ENDL ;
return true ;
}
//---------------------------------------------------------------------------------------------------------------
bool handle_download_peer_log ( po : : variables_map & vm )
{
crypto : : secret_key sk = AUTO_VAL_INIT ( sk ) ;
if ( ! get_private_key ( sk , vm ) )
{
std : : cout < < " ERROR: secret key error " < < ENDL ;
return false ;
}
uint64_t start_offset = command_line : : get_arg ( vm , arg_download_peer_log ) ;
levin : : levin_client_impl2 transport ;
peerid_type peer_id = 0 ;
COMMAND_REQUEST_LOG : : request req = AUTO_VAL_INIT ( req ) ;
COMMAND_REQUEST_LOG : : response rsp = AUTO_VAL_INIT ( rsp ) ;
if ( ! invoke_debug_command < COMMAND_REQUEST_LOG > ( vm , sk , transport , peer_id , req , rsp ) | | ! rsp . error . empty ( ) )
{
std : : cout < < " ERROR: invoking COMMAND_REQUEST_LOG failed: " < < rsp . error < < ENDL ;
return false ;
}
std : : cout < < " Current log level: " < < rsp . current_log_level < < ENDL ;
std : : cout < < " Current log size: " < < rsp . current_log_size < < ENDL ;
if ( start_offset > = rsp . current_log_size )
{
std : : cout < < " ERROR: invalid start offset: " < < start_offset < < " , log size: " < < rsp . current_log_size < < ENDL ;
return false ;
}
std : : cout < < " Downloading... " < < ENDL ;
std : : string local_filename = tools : : get_default_data_dir ( ) + " /log_ " + epee : : string_tools : : num_to_string_fast ( peer_id ) + " .log " ;
std : : ofstream log { local_filename , std : : ifstream : : binary } ;
if ( ! log )
{
std : : cout < < " Couldn't open " < < local_filename < < " for writing. " < < ENDL ;
return false ;
}
const uint64_t chunk_size = 1024 * 1024 * 5 ;
uint64_t end_offset = start_offset ;
while ( true )
{
req . log_chunk_offset = end_offset ;
req . log_chunk_size = std : : min ( chunk_size , rsp . current_log_size - req . log_chunk_offset ) ;
if ( req . log_chunk_size = = 0 )
break ;
std : : this_thread : : sleep_for ( std : : chrono : : seconds ( 1 ) ) ;
if ( ! invoke_debug_command < COMMAND_REQUEST_LOG > ( vm , sk , transport , peer_id , req , rsp ) | | ! rsp . error . empty ( ) )
{
std : : cout < < " ERROR: invoking COMMAND_REQUEST_LOG failed: " < < rsp . error < < ENDL ;
return false ;
}
if ( ! epee : : zlib_helper : : unpack ( rsp . log_chunk ) )
{
std : : cout < < " ERROR: zip unpack failed " < < ENDL ;
return false ;
}
if ( rsp . log_chunk . size ( ) ! = req . log_chunk_size )
{
std : : cout < < " ERROR: unpacked size: " < < rsp . log_chunk . size ( ) < < " , requested: " < < req . log_chunk_size < < ENDL ;
return false ;
}
log . write ( rsp . log_chunk . c_str ( ) , rsp . log_chunk . size ( ) ) ;
end_offset + = req . log_chunk_size ;
std : : cout < < end_offset - start_offset < < " bytes downloaded " < < ENDL ;
}
std : : cout < < " Remote log from offset " < < start_offset < < " to offset " < < end_offset < < " ( " < < end_offset - start_offset < < " bytes) " < <
2019-02-19 21:42:41 +03:00
" was successfully downloaded to " < < local_filename < < ENDL ;
2019-02-16 03:04:08 +03:00
return true ;
}
//---------------------------------------------------------------------------------------------------------------
2018-12-27 18:50:45 +03:00
int main ( int argc , char * argv [ ] )
{
string_tools : : set_module_name_and_folder ( argv [ 0 ] ) ;
2019-04-12 00:00:36 +02:00
log_space : : get_set_log_detalisation_level ( true , LOG_LEVEL_2 ) ;
2018-12-27 18:50:45 +03:00
tools : : signal_handler : : install_fatal ( [ ] ( int sig_number , void * address ) {
LOG_ERROR ( " \n \n FATAL ERROR \n sig: " < < sig_number < < " , address: " < < address ) ;
std : : fflush ( nullptr ) ; // all open output streams are flushed
} ) ;
// Declare the supported options.
po : : options_description desc_general ( " General options " ) ;
command_line : : add_arg ( desc_general , command_line : : arg_help ) ;
po : : options_description desc_params ( " Connectivity options " ) ;
command_line : : add_arg ( desc_params , arg_ip ) ;
command_line : : add_arg ( desc_params , arg_port ) ;
command_line : : add_arg ( desc_params , arg_rpc_port ) ;
command_line : : add_arg ( desc_params , arg_timeout ) ;
command_line : : add_arg ( desc_params , arg_request_stat_info ) ;
command_line : : add_arg ( desc_params , arg_request_net_state ) ;
command_line : : add_arg ( desc_params , arg_generate_keys ) ;
command_line : : add_arg ( desc_params , arg_peer_id ) ;
command_line : : add_arg ( desc_params , arg_priv_key ) ;
command_line : : add_arg ( desc_params , arg_get_daemon_info ) ;
command_line : : add_arg ( desc_params , arg_get_aliases ) ;
command_line : : add_arg ( desc_params , arg_upate_maintainers_info ) ;
command_line : : add_arg ( desc_params , arg_increment_build_no ) ;
command_line : : add_arg ( desc_params , command_line : : arg_version ) ;
command_line : : add_arg ( desc_params , arg_generate_genesis ) ;
command_line : : add_arg ( desc_params , arg_genesis_split_amount ) ;
command_line : : add_arg ( desc_params , arg_get_info_flags ) ;
command_line : : add_arg ( desc_params , arg_log_journal_len ) ;
2019-02-16 03:04:08 +03:00
command_line : : add_arg ( desc_params , arg_set_peer_log_level ) ;
command_line : : add_arg ( desc_params , arg_download_peer_log ) ;
2019-04-12 00:00:36 +02:00
command_line : : add_arg ( desc_params , arg_do_consloe_log ) ;
2019-02-16 03:04:08 +03:00
2018-12-27 18:50:45 +03:00
po : : options_description desc_all ;
desc_all . add ( desc_general ) . add ( desc_params ) ;
po : : variables_map vm ;
bool r = command_line : : handle_error_helper ( desc_all , [ & ] ( )
{
po : : store ( command_line : : parse_command_line ( argc , argv , desc_general , true ) , vm ) ;
if ( command_line : : get_arg ( vm , command_line : : arg_help ) )
{
std : : cout < < desc_all < < ENDL ;
return false ;
}
po : : store ( command_line : : parse_command_line ( argc , argv , desc_params , false ) , vm ) ;
po : : notify ( vm ) ;
return true ;
} ) ;
if ( ! r )
return 1 ;
2019-04-12 00:00:36 +02:00
if ( command_line : : has_arg ( vm , arg_do_consloe_log ) & & command_line : : get_arg ( vm , arg_do_consloe_log ) )
{
log_space : : log_singletone : : add_logger ( LOGGER_CONSOLE , NULL , NULL ) ;
}
2018-12-27 18:50:45 +03:00
if ( command_line : : get_arg ( vm , command_line : : arg_version ) )
{
std : : cout < < CURRENCY_NAME < < " v " < < PROJECT_VERSION_LONG < < ENDL ;
return 0 ;
}
if ( command_line : : has_arg ( vm , arg_request_stat_info ) | | command_line : : has_arg ( vm , arg_request_net_state ) )
{
return handle_request_stat ( vm , command_line : : get_arg ( vm , arg_peer_id ) ) ? 0 : 1 ;
}
if ( command_line : : has_arg ( vm , arg_get_daemon_info ) )
{
return handle_get_daemon_info ( vm ) ? 0 : 1 ;
}
else if ( command_line : : has_arg ( vm , arg_generate_keys ) )
{
return generate_and_print_keys ( ) ? 0 : 1 ;
}
else if ( command_line : : has_arg ( vm , arg_get_aliases ) )
{
return handle_get_aliases ( vm ) ? 0 : 1 ;
}
else if ( command_line : : has_arg ( vm , arg_upate_maintainers_info ) )
{
return handle_update_maintainers_info ( vm ) ? 0 : 1 ;
}
else if ( command_line : : has_arg ( vm , arg_increment_build_no ) )
{
return handle_increment_build_no ( vm ) ? 0 : 1 ;
}
else if ( command_line : : has_arg ( vm , arg_generate_genesis ) )
{
return generate_genesis ( command_line : : get_arg ( vm , arg_generate_genesis ) , 10000000000000000 ) ? 0 : 1 ;
}
2019-02-16 03:04:08 +03:00
else if ( command_line : : has_arg ( vm , arg_set_peer_log_level ) )
{
return handle_set_peer_log_level ( vm ) ? 0 : 1 ;
}
else if ( command_line : : has_arg ( vm , arg_download_peer_log ) )
{
return handle_download_peer_log ( vm ) ? 0 : 1 ;
}
2018-12-27 18:50:45 +03:00
else
{
std : : cerr < < " Not enough arguments. " < < ENDL ;
std : : cerr < < desc_all < < ENDL ;
}
return 1 ;
}