diff --git a/dap_chain_net.c b/dap_chain_net.c index 4cdd3189d02ae668bab77786317a7f023c5b0319..a03e3d404558f355ed56fa9032d85624e1446e41 100644 --- a/dap_chain_net.c +++ b/dap_chain_net.c @@ -54,8 +54,8 @@ */ typedef struct dap_chain_net_pvt{ pthread_t proc_tid; - pthread_cond_t proc_cond; - pthread_mutex_t proc_mutex; + pthread_cond_t state_proc_cond; + pthread_mutex_t state_mutex; dap_chain_node_role_t node_role; uint8_t padding[4]; @@ -64,6 +64,10 @@ typedef struct dap_chain_net_pvt{ dap_chain_node_client_t * clients_by_ipv6; size_t clients_count; + char ** seed_aliases; + uint16_t seed_aliases_count; + uint8_t padding2[6]; + dap_chain_net_state_t state; dap_chain_net_state_t state_target; } dap_chain_net_pvt_t; @@ -100,6 +104,7 @@ static void s_net_proc_kill( dap_chain_net_t * a_net ); static int s_cli_net(int argc, const char ** argv, char **str_reply); +static bool s_seed_mode = false; /** * @brief s_net_state_to_str * @param l_state @@ -117,11 +122,14 @@ inline static const char * s_net_state_to_str(dap_chain_net_state_t l_state) */ int dap_chain_net_state_go_to(dap_chain_net_t * a_net, dap_chain_net_state_t a_new_state) { + pthread_mutex_lock( &PVT(a_net)->state_mutex); if (PVT(a_net)->state_target == a_new_state){ log_it(L_WARNING,"Already going to state %s",s_net_state_to_str(a_new_state)); } PVT(a_net)->state_target = a_new_state; - return s_net_states_proc(a_net); + pthread_mutex_unlock( &PVT(a_net)->state_mutex); + pthread_cond_signal(&PVT(a_net)->state_proc_cond); + return 0; } @@ -135,9 +143,34 @@ static int s_net_states_proc(dap_chain_net_t * l_net) switch ( PVT(l_net)->state ){ case NET_STATE_OFFLINE:{ if ( PVT(l_net)->state_target != NET_STATE_OFFLINE ){ - + // Check if there are root nodes in list + switch ( PVT(l_net)->node_role.enums){ + case NODE_ROLE_ROOT_MASTER: + case NODE_ROLE_ROOT:{ + }break; + case NODE_ROLE_ARCHIVE: + case NODE_ROLE_CELL_MASTER: + case NODE_ROLE_MASTER: + case NODE_ROLE_FULL: + case NODE_ROLE_LIGHT: + default:{}; + }; } }break; + case NET_STATE_LINKS_PINGING:{ + switch ( PVT(l_net)->node_role.enums){ + case NODE_ROLE_ROOT_MASTER: + case NODE_ROLE_ROOT:{ + }break; + case NODE_ROLE_ARCHIVE: + case NODE_ROLE_CELL_MASTER: + case NODE_ROLE_MASTER: + case NODE_ROLE_FULL: + case NODE_ROLE_LIGHT: + default:{} + }; + + }break; case NET_STATE_LINKS_CONNECTING:{ log_it(L_DEBUG,"Connected %u/% links", PVT(l_net)->clients_count ); @@ -170,12 +203,12 @@ static void * s_net_proc_thread ( void * a_net) dap_chain_net_t * l_net = (dap_chain_net_t *) a_net; bool is_looping = true ; while( is_looping ) { - pthread_mutex_lock( &PVT(l_net)->proc_mutex ); - pthread_cond_wait(&PVT(l_net)->proc_cond,&PVT(l_net)->proc_mutex); - pthread_mutex_unlock( &PVT(l_net)->proc_mutex ); + s_net_states_proc(l_net); + pthread_mutex_lock( &PVT(l_net)->state_mutex ); + pthread_cond_wait(&PVT(l_net)->state_proc_cond,&PVT(l_net)->state_mutex); + pthread_mutex_unlock( &PVT(l_net)->state_mutex ); log_it( L_DEBUG, "Waked up net proc thread"); - s_net_states_proc(l_net); } return NULL; } @@ -198,7 +231,7 @@ static void s_net_proc_thread_start( dap_chain_net_t * a_net ) static void s_net_proc_kill( dap_chain_net_t * a_net ) { if ( PVT(a_net)->proc_tid ) { - pthread_cond_signal(& PVT(a_net)->proc_cond); + pthread_cond_signal(& PVT(a_net)->state_proc_cond); log_it(L_NOTICE,"Sent KILL signal to the net process thread %d, waiting for shutdown...",PVT(a_net)->proc_tid); pthread_join( PVT(a_net)->proc_tid , NULL); log_it(L_NOTICE,"Net process thread %d shutted down",PVT(a_net)->proc_tid); @@ -219,8 +252,8 @@ static dap_chain_net_t * s_net_new(const char * a_id, const char * a_name , { dap_chain_net_t * ret = DAP_NEW_Z_SIZE (dap_chain_net_t, sizeof (ret->pub)+ sizeof (dap_chain_net_pvt_t) ); ret->pub.name = strdup( a_name ); - pthread_mutex_init( &PVT(ret)->proc_mutex, NULL); - pthread_cond_init( &PVT(ret)->proc_cond, NULL); + pthread_mutex_init( &PVT(ret)->state_mutex, NULL); + pthread_cond_init( &PVT(ret)->state_proc_cond, NULL); if ( sscanf(a_id,"0x%016lx", &ret->pub.id.uint64 ) == 1 ){ if (strcmp (a_node_role, "root_master")==0){ PVT(ret)->node_role.enums = NODE_ROLE_ROOT_MASTER; @@ -269,6 +302,7 @@ static dap_chain_net_t * s_net_new(const char * a_id, const char * a_name , */ void dap_chain_net_delete( dap_chain_net_t * a_net ) { + if (PVT(a_net)->seed_aliases) DAP_DELETE( PVT(a_net) ); } @@ -285,7 +319,8 @@ int dap_chain_net_init() "net -net <chain net name> link < list | add | del | info | establish >\n" "\tList,add,del, dump or establish links\n\n" ); - + s_seed_mode = dap_config_get_item_bool_default(g_config,"general","seed_mode",false); + return 0; } /** @@ -403,7 +438,9 @@ int dap_chain_net_load(const char * a_net_name) } dap_chain_utxo_init(l_utxo_flags); - + // Check if seed nodes are present in local db alias + PVT(l_net)->seed_aliases = dap_config_get_array_str( l_cfg , "general" ,"seed_nodes_aliases" + ,&PVT(l_net)->seed_aliases_count); // Init chains size_t l_chains_path_size =strlen(dap_config_path())+1+strlen(l_net->pub.name)+1+strlen("network")+1; @@ -450,12 +487,15 @@ int dap_chain_net_load(const char * a_net_name) dap_chain_t * l_chain = NULL; DL_FOREACH(l_net->pub.chains, l_chain ) l_chain->is_datum_pool_proc = true; log_it(L_INFO,"Root master node role established"); - } break; + } // Master root includes root case NODE_ROLE_ROOT:{ // Set to process only zerochain dap_chain_id_t l_chain_id = {{0}}; dap_chain_t * l_chain = dap_chain_find_by_id(l_net->pub.id,l_chain_id); - l_chain->is_datum_pool_proc = true; + if (l_chain ) + l_chain->is_datum_pool_proc = true; + + PVT(l_net)->state_target = NET_STATE_SYNC_ALL; log_it(L_INFO,"Root node role established"); } break; case NODE_ROLE_CELL_MASTER: @@ -464,11 +504,12 @@ int dap_chain_net_load(const char * a_net_name) dap_chain_id_t l_chain_id = { .raw = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x01} }; dap_chain_t * l_chain = dap_chain_find_by_id(l_net->pub.id, l_chain_id ); l_chain->is_datum_pool_proc = true; - + PVT(l_net)->state_target = NET_STATE_SYNC_ALL; log_it(L_INFO,"Master node role established"); } break; case NODE_ROLE_FULL:{ log_it(L_INFO,"Full node role established"); + PVT(l_net)->state_target = NET_STATE_SYNC_ALL; } break; case NODE_ROLE_LIGHT: default: @@ -476,6 +517,9 @@ int dap_chain_net_load(const char * a_net_name) } + if (s_seed_mode) { // If we seed we do everything manual. First think - prefil list of node_addrs and its aliases + PVT(l_net)->state_target = NET_STATE_OFFLINE; + } // Add network to the list dap_chain_net_item_t * l_net_item = DAP_NEW_Z( dap_chain_net_item_t); dap_chain_net_item_t * l_net_item2 = DAP_NEW_Z( dap_chain_net_item_t); diff --git a/dap_chain_net.h b/dap_chain_net.h index 042d13f77278c3629731ac6ef450ee0f810dd110..e738dd252771315d0a12191692c94491a45d3c6a 100644 --- a/dap_chain_net.h +++ b/dap_chain_net.h @@ -35,6 +35,7 @@ typedef enum dap_chain_net_state{ NET_STATE_OFFLINE = 0, + NET_STATE_LINKS_PINGING, NET_STATE_LINKS_CONNECTING, NET_STATE_LINKS_ESTABLISHED, NET_STATE_SYNC_GDB, diff --git a/dap_chain_node.c b/dap_chain_node.c index f1cee2def4fb832c125acac598553646664d2a42..980ce0bd52e15a45e7d15e6641ac1e7dddfbff85 100644 --- a/dap_chain_node.c +++ b/dap_chain_node.c @@ -76,6 +76,19 @@ bool dap_chain_node_alias_register(const char *alias, dap_chain_node_addr_t *add return res; } +/** + * @brief dap_chain_node_alias_find + * @param alias + * @return + */ +dap_chain_node_addr_t * dap_chain_node_alias_find(const char *a_alias) +{ + size_t l_addr_size =0; + dap_chain_node_addr_t * l_addr = (dap_chain_node_addr_t *) + dap_chain_global_db_gr_get(a_alias, &l_addr_size, GROUP_ALIAS); + return l_addr; +} + /** * Delete alias from base */ diff --git a/dap_chain_node.h b/dap_chain_node.h index 6f73b44fb53baff9ec49f36be232f43892753ac9..62b3f3a44a8aae24815849f3e6fb1323ef187393 100644 --- a/dap_chain_node.h +++ b/dap_chain_node.h @@ -80,6 +80,7 @@ typedef struct dap_chain_node_info uint32_t links_number; struct in_addr ext_addr_v4; struct in6_addr ext_addr_v6; + uint16_t ext_port; // Port thats node listening char alias[256]; } DAP_ALIGN_PACKED hdr; dap_chain_node_addr_t links[]; // dap_chain_addr_t @@ -119,7 +120,7 @@ dap_chain_node_addr_t* dap_chain_node_gen_addr(dap_chain_cell_id_t *shard_id); */ bool dap_chain_node_check_addr(dap_chain_node_addr_t *addr, dap_chain_cell_id_t *shard_id); - +dap_chain_node_addr_t * dap_chain_node_alias_find(const char *alias); bool dap_chain_node_alias_register(const char *alias, dap_chain_node_addr_t *addr); bool dap_chain_node_alias_delete(const char *alias); diff --git a/dap_chain_node_cli.c b/dap_chain_node_cli.c index be7a283764cdb94d970cf9f6502b5e0078807c18..4913852c03a7f9f15a013a65904addba881f2d94 100644 --- a/dap_chain_node_cli.c +++ b/dap_chain_node_cli.c @@ -485,8 +485,8 @@ int dap_chain_node_cli_init(dap_config_t * g_config) // Token commands dap_chain_node_cli_cmd_item_create ("token_decl", com_token_decl, "Token declaration", - "token_decl -net <net name> -chain <chain name> token <token ticker> total_supply <total supply> sign_total <sign total> sign_valid <sign valid> certs <certs list>\n" - "\t Declare new token for <netname>:<chain name> with ticker <token ticker>, maximum emission <total supply> and <sign valid> from <sign total> signatures on valid emission\n" + "token_decl -net <net name> -chain <chain name> token <token ticker> total_supply <total supply> signs_total <sign total> signs_emission <signs for emission> certs <certs list>\n" + "\t Declare new token for <netname>:<chain name> with ticker <token ticker>, maximum emission <total supply> and <signs for emission> from <signs total> signatures on valid emission\n" "token_decl_sign -net <net name> -chain <chain name> datum <datum_hash> certs <certs list>\n" "\t Sign existent <datum hash> in mempool with <certs list>\n" ); @@ -503,8 +503,10 @@ int dap_chain_node_cli_init(dap_config_t * g_config) "mempool_list -net <net name> -chain <chain name>\n"); dap_chain_node_cli_cmd_item_create ("mempool_proc", com_mempool_proc, "Proc mempool entries for selected chain network and chain id", - "mempool_list -net <net name> -chain <chain name>\n"); + "mempool_proc -net <net name> -chain <chain name>\n"); + dap_chain_node_cli_cmd_item_create ("mempool_delete", com_mempool_delete, "Delete datum with hash <datum hash>", + "mempool_delete -net <net name> -chain <chain name> -datum <datum hash>\n"); // Transaction commands diff --git a/dap_chain_node_cli_cmd.c b/dap_chain_node_cli_cmd.c index 3453a004c3bcdb1ee8ebea8bb6c61cb49ef82fc2..97d0935e7fc346ab9ababded622f9665a5e27bc5 100644 --- a/dap_chain_node_cli_cmd.c +++ b/dap_chain_node_cli_cmd.c @@ -1647,29 +1647,81 @@ int com_token_decl_sign(int argc, const char ** argv, char ** a_str_reply) int com_mempool_list(int argc, const char ** argv, char ** a_str_reply) { int arg_index = 1; - dap_chain_t * l_chain; + dap_chain_t * l_chain = NULL; dap_chain_net_t * l_net = NULL; - if (dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index,argc,argv,a_str_reply,&l_chain, &l_net) < 0) + if (dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index,argc,argv,a_str_reply,&l_chain, &l_net) != 0){ + dap_chain_node_cli_set_reply_text(a_str_reply, "Error! Need both -net <network name> and -chain <chain name> params\n"); return -1; + } - char * l_gdb_group_mempool = dap_chain_net_get_gdb_group_mempool(l_chain); - size_t l_objs_size = 0; - dap_global_db_obj_t ** l_objs = dap_chain_global_db_gr_load(l_gdb_group_mempool,&l_objs_size); - dap_string_t * l_str_tmp = dap_string_new(NULL); - dap_string_append_printf(l_str_tmp,"%s.%s: Found %u records :\n",l_net->pub.name,l_chain->name,l_objs_size); - for ( size_t i = 0; i< l_objs_size; i++){ - dap_chain_datum_t * l_datum =(dap_chain_datum_t* ) l_objs[i]->value; - char buf[50]; - time_t l_ts_create = (time_t) l_datum->header.ts_create; - dap_string_append_printf(l_str_tmp,"0x%s: type_id=%s ts_create=%s data_size=%u\n", - l_objs[i]->key, c_datum_type_str[l_datum->header.type_id], - ctime_r( &l_ts_create,buf ),l_datum->header.data_size ); - } - dap_chain_global_db_objs_delete(l_objs); - dap_chain_node_cli_set_reply_text(a_str_reply, l_str_tmp->str); - dap_string_free(l_str_tmp,false); - return 0; + if ( l_chain && l_net ){ + char * l_gdb_group_mempool = dap_chain_net_get_gdb_group_mempool(l_chain); + dap_string_t * l_str_tmp = dap_string_new(NULL); + + size_t l_objs_size = 0; + + dap_global_db_obj_t ** l_objs = dap_chain_global_db_gr_load(l_gdb_group_mempool,&l_objs_size); + dap_string_append_printf(l_str_tmp,"%s.%s: Found %u records :\n",l_net->pub.name,l_chain->name,l_objs_size); + for ( size_t i = 0; i< l_objs_size; i++){ + dap_chain_datum_t * l_datum =(dap_chain_datum_t* ) l_objs[i]->value; + char buf[50]; + time_t l_ts_create = (time_t) l_datum->header.ts_create; + dap_string_append_printf(l_str_tmp,"%s: type_id=%s data_size=%u ts_create=%s", + l_objs[i]->key, c_datum_type_str[l_datum->header.type_id], + l_datum->header.data_size,ctime_r( &l_ts_create,buf ) ); + } + + // Clean up + dap_chain_node_cli_set_reply_text(a_str_reply, l_str_tmp->str); + dap_chain_global_db_objs_delete(l_objs); + dap_string_free(l_str_tmp,false); + + return 0; + }else { + dap_chain_node_cli_set_reply_text(a_str_reply, "Error! Need both -net <network name> and -chain <chain name> params\n"); + return -2; + } +} + +/** + * @brief com_mempool_delete + * @param argc + * @param argv + * @param a_str_reply + * @return + */ +int com_mempool_delete(int argc, const char ** argv, char ** a_str_reply) +{ + int arg_index = 1; + dap_chain_t * l_chain = NULL; + dap_chain_net_t * l_net = NULL; + + if (dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index,argc,argv,a_str_reply,&l_chain, &l_net) != 0){ + dap_chain_node_cli_set_reply_text(a_str_reply, "Error! Need both -net <network name> and -chain <chain name> params\n"); + return -1; + } + + if ( l_chain && l_net ){ + const char * l_datum_hash_str = NULL; + dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-datum", &l_datum_hash_str); + if ( l_datum_hash_str ){ + char * l_gdb_group_mempool = dap_chain_net_get_gdb_group_mempool(l_chain); + if ( dap_chain_global_db_gr_del(l_datum_hash_str,l_gdb_group_mempool) ) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Datum %s deleted",l_datum_hash_str); + return 0; + }else { + dap_chain_node_cli_set_reply_text(a_str_reply, "Error! Can't find datum %s",l_datum_hash_str); + return -4; + } + }else { + dap_chain_node_cli_set_reply_text(a_str_reply, "Error! %s requires -datum <datum hash> option",argv[0]); + return -3; + } + }else { + dap_chain_node_cli_set_reply_text(a_str_reply, "Error! Need both -net <network name> and -chain <chain name> params\n"); + return -2; + } } /** @@ -1723,6 +1775,8 @@ int com_mempool_proc(int argc, const char ** argv, char ** a_str_reply) return 0; } + + /** * @brief com_token_decl * @param argc