diff --git a/dap_chain_net.c b/dap_chain_net.c index 319779716d19f0539c85e16f1372b45a209e2144..92f0d6c74899c269e65ed0ccc339f2722b8c5e57 100644 --- a/dap_chain_net.c +++ b/dap_chain_net.c @@ -75,6 +75,11 @@ typedef struct dap_chain_net_pvt{ dap_chain_node_client_t * links; size_t links_count; + dap_chain_node_addr_t *links_addrs; + size_t links_addrs_count; + + size_t addr_request_attempts; + char ** seed_aliases; uint16_t seed_aliases_count; uint8_t padding2[6]; @@ -100,11 +105,13 @@ static dap_chain_net_item_t * s_net_items_ids = NULL; static const char * c_net_states[]={ [NET_STATE_OFFLINE] = "NET_STATE_OFFLINE", + [NET_STATE_LINKS_PREPARE ] = "NET_STATE_LINKS_PREPARE", [NET_STATE_LINKS_CONNECTING] = "NET_STATE_LINKS_CONNECTING", [NET_STATE_LINKS_ESTABLISHED]= "NET_STATE_LINKS_ESTABLISHED", [NET_STATE_SYNC_GDB]= "NET_STATE_SYNC_GDB", [NET_STATE_SYNC_CHAINS]= "NET_STATE_SYNC_CHAINS", - [NET_STATE_ONLINE]= "NET_STATE_STAND_BY" + [NET_STATE_ADDR_REQUEST]= "NET_STATE_ADDR_REQUEST", + [NET_STATE_ONLINE]= "NET_STATE_ONLINE" }; static dap_chain_net_t * s_net_new(const char * a_id, const char * a_name , const char * a_node_role); @@ -152,78 +159,207 @@ int dap_chain_net_state_go_to(dap_chain_net_t * a_net, dap_chain_net_state_t a_n static int s_net_states_proc(dap_chain_net_t * l_net) { int ret=0; - pthread_mutex_lock(&PVT(l_net)->state_mutex ); lb_proc_state: + pthread_mutex_lock(&PVT(l_net)->state_mutex ); switch ( PVT(l_net)->state ){ case NET_STATE_OFFLINE:{ log_it(L_NOTICE,"%s.state: NET_STATE_OFFLINE",l_net->pub.name); + dap_chain_node_client_t * l_node_client = NULL, *l_node_client_tmp = NULL; + HASH_ITER(hh,PVT(l_net)->links,l_node_client,l_node_client_tmp){ + HASH_DEL(PVT(l_net)->links, l_node_client); + dap_chain_node_client_close(l_node_client); + } + PVT(l_net)->links_addrs_count = 0; + if ( PVT(l_net)->links_addrs ) + DAP_DELETE(PVT(l_net)->links_addrs); + PVT(l_net)->links_addrs = NULL; + if ( PVT(l_net)->state_target != NET_STATE_OFFLINE ){ - PVT(l_net)->state = NET_STATE_LINKS_PING; + PVT(l_net)->state = NET_STATE_LINKS_PREPARE; + pthread_mutex_unlock(&PVT(l_net)->state_mutex ); goto lb_proc_state; } } break; - case NET_STATE_LINKS_PING:{ - log_it(L_NOTICE,"%s.state: NET_STATE_LINKS_PING",l_net->pub.name); - if ( PVT(l_net)->state_target != NET_STATE_LINKS_PING ){ - PVT(l_net)->state = NET_STATE_LINKS_CONNECTING; - goto lb_proc_state; - }else { - PVT(l_net)->state = NET_STATE_OFFLINE; - goto lb_proc_state; + case NET_STATE_LINKS_PREPARE:{ + log_it(L_NOTICE,"%s.state: NET_STATE_LINKS_PREPARE",l_net->pub.name); + switch (PVT(l_net)->node_role.enums) { + case NODE_ROLE_ROOT: + case NODE_ROLE_ROOT_MASTER: + case NODE_ROLE_ARCHIVE: + case NODE_ROLE_CELL_MASTER:{ + // This roles load predefined links from global_db + if ( PVT(l_net)->node_info ) { + if (PVT(l_net)->links_addrs ) + DAP_DELETE(PVT(l_net)->links_addrs); + PVT(l_net)->links_addrs_count = PVT(l_net)->node_info->hdr.links_number; + PVT(l_net)->links_addrs = DAP_NEW_Z_SIZE( dap_chain_node_addr_t, + PVT(l_net)->links_addrs_count); + for (size_t i =0 ; i < PVT(l_net)->node_info->hdr.links_number; i++ ){ + PVT(l_net)->links_addrs[i].uint64 = PVT(l_net)->node_info->links[i].uint64; + } + }else { + log_it(L_WARNING,"No nodeinfo in global_db to prepare links for connecting"); + } + } break; + case NODE_ROLE_FULL: + case NODE_ROLE_MASTER: + case NODE_ROLE_LIGHT:{ + // If we haven't any assigned shard - connect to root-0 + if ( l_net->pub.cell_id.uint64 == 0 ){ + PVT(l_net)->links_addrs_count=1; + PVT(l_net)->links_addrs = DAP_NEW_Z_SIZE(dap_chain_node_addr_t, + PVT(l_net)->links_addrs_count); + PVT(l_net)->links_addrs[0].uint64 = 1; // root-0 address + }else { + // TODO read cell's nodelist and populate array with it + } + } break; } - }break; - case NET_STATE_LINKS_PONG:{ - log_it(L_NOTICE,"%s.state: NET_STATE_LINKS_PONG",l_net->pub.name); - if ( ( PVT( l_net )->state_target != NET_STATE_LINKS_PONG ) && - ( PVT( l_net )->state_target != NET_STATE_OFFLINE ) ) { - PVT(l_net)->state = NET_STATE_LINKS_CONNECTING; - }else { // target was to have a pong + if ( PVT(l_net)->state_target != NET_STATE_LINKS_PREPARE ){ + if ( PVT(l_net)->links_addrs_count>0 ) { // If links are present + PVT(l_net)->state = NET_STATE_LINKS_CONNECTING; + log_it(L_DEBUG,"Prepared %u links, start to establish them", PVT(l_net)->links_addrs_count ); + } else { + log_it(L_WARNING,"No links for connecting, return back to OFFLINE state"); + PVT(l_net)->state = NET_STATE_OFFLINE; + } + }else { + log_it(L_WARNING,"Target state is NET_STATE_LINKS_PREPARE? Realy?"); PVT(l_net)->state = NET_STATE_OFFLINE; - goto lb_proc_state; } - } + } pthread_mutex_unlock(&PVT(l_net)->state_mutex ); goto lb_proc_state; case NET_STATE_LINKS_CONNECTING:{ log_it(L_NOTICE,"%s.state: NET_STATE_LINKS_CONNECTING",l_net->pub.name); - if ( PVT(l_net)->node_info ) { - size_t l_links_established = 0; - for (size_t i =0 ; i < PVT(l_net)->node_info->hdr.links_number; i++ ){ - dap_chain_node_info_t *l_link_node_info = dap_chain_node_info_read( &PVT(l_net)->node_info->links[i] ); - if ( l_link_node_info ) { - dap_chain_node_client_t *l_node_client = dap_chain_node_client_connect(l_link_node_info ); - if(!l_node_client) { - DAP_DELETE(l_link_node_info); - ret = -1; - break; - } - // wait connected - int timeout_ms = 15000; //15 sec = 15000 ms - int res = dap_chain_node_client_wait(l_node_client, NODE_CLIENT_STATE_CONNECTED, timeout_ms); - if (res == 0 ){ - log_it(L_NOTICE, "Connected link %u",i); - l_links_established++; - HASH_ADD(hh,PVT(l_net)->links, remote_node_addr,sizeof(l_node_client->remote_node_addr), l_node_client); - }else { - log_it(L_NOTICE, "Cant establish link %u",i); - dap_chain_node_client_close(l_node_client); - } + size_t l_links_established = 0; + for (size_t i =0 ; i < PVT(l_net)->links_addrs_count ; i++ ){ + log_it(L_INFO,"Establishing connection with ",PVT(l_net)->links_addrs[i].raw); + dap_chain_node_info_t *l_link_node_info = dap_chain_node_info_read( &PVT(l_net)->links_addrs[i] ); + if ( l_link_node_info ) { + dap_chain_node_client_t *l_node_client = dap_chain_node_client_connect(l_link_node_info ); + if(!l_node_client) { + DAP_DELETE(l_link_node_info); + ret = -1; + break; + } + // wait connected + int timeout_ms = 15000; //15 sec = 15000 ms + int res = dap_chain_node_client_wait(l_node_client, NODE_CLIENT_STATE_CONNECTED, timeout_ms); + if (res == 0 ){ + log_it(L_NOTICE, "Connected link %u",i); + l_links_established++; + HASH_ADD(hh,PVT(l_net)->links, remote_node_addr,sizeof(l_node_client->remote_node_addr), l_node_client); + }else { + log_it(L_NOTICE, "Cant establish link %u",i); + dap_chain_node_client_close(l_node_client); } - } - if (l_links_established >0 ){ - log_it(L_NOTICE, "Established %u links",l_links_established); - PVT(l_net)->state = NET_STATE_LINKS_ESTABLISHED; - goto lb_proc_state; } } - } break; + if (l_links_established >0 ){ + log_it(L_NOTICE, "Established %u links",l_links_established); + PVT(l_net)->state = NET_STATE_LINKS_ESTABLISHED; + }else { + log_it(L_NOTICE, "Can't establish links, go to offline"); + PVT(l_net)->state = NET_STATE_OFFLINE ; + PVT(l_net)->state_target = NET_STATE_OFFLINE ; + } + } pthread_mutex_unlock(&PVT(l_net)->state_mutex ); goto lb_proc_state; case NET_STATE_LINKS_ESTABLISHED:{ log_it(L_NOTICE,"%s.state: NET_STATE_LINKS_ESTABLISHED",l_net->pub.name); switch (PVT(l_net)->state_target) { - case NET_STATE_ONLINE: - case NET_STATE_SYNC_GDB: PVT(l_net)->state = NET_STATE_SYNC_GDB ; goto lb_proc_state; - case NET_STATE_SYNC_CHAINS: PVT(l_net)->state = NET_STATE_SYNC_CHAINS ; goto lb_proc_state; + case NET_STATE_ONLINE:{ // Online + switch ( PVT(l_net)->node_role.enums ){ + case NODE_ROLE_ROOT_MASTER: + case NODE_ROLE_ROOT:{ + dap_chain_node_client_t * l_node_client = NULL, *l_node_client_tmp = NULL; + + // Send everybody your address when linked + HASH_ITER(hh,PVT(l_net)->links,l_node_client,l_node_client_tmp){ + dap_stream_ch_chain_net_pkt_write(dap_client_get_stream_ch( + l_node_client->client, dap_stream_ch_chain_net_get_id()), + DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_NODE_ADDR, l_net->pub.id, + dap_chain_net_get_cur_addr(l_net), + sizeof (dap_chain_node_addr_t) ); + } + }break; + case NODE_ROLE_CELL_MASTER: + case NODE_ROLE_MASTER:{ + PVT(l_net)->state = NET_STATE_ADDR_REQUEST; + } break; + default: PVT( l_net)->state = NET_STATE_SYNC_GDB; + } + }pthread_mutex_unlock(&PVT(l_net)->state_mutex ); goto lb_proc_state; + case NET_STATE_SYNC_GDB: // we need only to sync gdb + PVT(l_net)->state = NET_STATE_SYNC_GDB ; + if ( PVT(l_net)->addr_request_attempts >=10 && PVT(l_net)->state == NET_STATE_ADDR_REQUEST){ + PVT(l_net)->addr_request_attempts = 0; + switch( PVT(l_net)->state_target){ + case NET_STATE_ONLINE: + case NET_STATE_SYNC_GDB: + PVT(l_net)->state = NET_STATE_SYNC_GDB; + pthread_mutex_unlock(&PVT(l_net)->state_mutex ); + goto lb_proc_state; + case NET_STATE_SYNC_CHAINS: + PVT(l_net)->state = NET_STATE_SYNC_CHAINS; + pthread_mutex_unlock(&PVT(l_net)->state_mutex ); + goto lb_proc_state; + default: { + PVT(l_net)->state = NET_STATE_OFFLINE; + PVT(l_net)->state_target = NET_STATE_OFFLINE; + } + } + } + pthread_mutex_unlock(&PVT(l_net)->state_mutex ); goto lb_proc_state; + case NET_STATE_SYNC_CHAINS: + PVT(l_net)->state = (PVT(l_net)->node_info && PVT(l_net)->node_info->hdr.address.uint64)? + NET_STATE_SYNC_CHAINS : NET_STATE_ADDR_REQUEST; + pthread_mutex_unlock(&PVT(l_net)->state_mutex ); goto lb_proc_state; + case NET_STATE_ADDR_REQUEST : + PVT(l_net)->state = NET_STATE_ADDR_REQUEST; + pthread_mutex_unlock(&PVT(l_net)->state_mutex ); goto lb_proc_state; default:{} } }break; + case NET_STATE_ADDR_REQUEST:{ + dap_chain_node_client_t * l_node_client = NULL, *l_node_client_tmp = NULL; + HASH_ITER(hh,PVT(l_net)->links,l_node_client,l_node_client_tmp){ + uint8_t l_ch_id = dap_stream_ch_chain_net_get_id(); // Channel id for chain net request + size_t res = dap_stream_ch_chain_net_pkt_write(dap_client_get_stream_ch(l_node_client->client, + l_ch_id), DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_NODE_ADDR_REQUEST, l_net->pub.id, + NULL, 0 ); + if(res == 0) { + log_it(L_WARNING,"Can't send NODE_ADDR_REQUEST packet"); + HASH_DEL(PVT(l_net)->links,l_node_client); + dap_chain_node_client_close(l_node_client); + continue; // try with another link + } + + // wait for finishing of request + int timeout_ms = 120000; // 2 min = 120 sec = 120 000 ms + // TODO add progress info to console + PVT(l_net)->addr_request_attempts++; + int l_res = dap_chain_node_client_wait(l_node_client, NODE_CLIENT_STATE_NODE_ADDR_LEASED, timeout_ms); + switch (l_res) { + case 0: + log_it(L_WARNING,"Timeout with addr leasing"); + continue; // try with another link + case 1: + log_it(L_INFO, "Node address leased"); + PVT(l_net)->state = NET_STATE_SYNC_GDB; + pthread_mutex_unlock(&PVT(l_net)->state_mutex ); goto lb_proc_state; + default: + if ( l_node_client->last_error[0] ){ + log_it(L_INFO, "Node address request error %d: \"%s\"",l_res, l_node_client->last_error ); + l_node_client->last_error[0]='\0'; + } + log_it(L_INFO, "Node address request error %d",l_res); + continue; + } + + log_it(L_WARNING,"Haven't received address from any links, return back to LINKS_ESTABLISHED"); + PVT(l_net)->state = NET_STATE_LINKS_ESTABLISHED; + pthread_mutex_unlock(&PVT(l_net)->state_mutex );goto lb_proc_state; // One address assigned its enought for now + } + }break; case NET_STATE_SYNC_GDB:{ // send request dap_chain_node_client_t * l_node_client = NULL, *l_node_client_tmp = NULL; @@ -232,11 +368,12 @@ lb_proc_state: // Get last timestamp in log l_sync_gdb.ts_start = (uint64_t) dap_db_log_get_last_timestamp_remote(l_node_client->remote_node_addr.uint64); l_sync_gdb.ts_end = (uint64_t) time(NULL); - uint8_t l_ch_id = dap_stream_ch_chain_get_id(); // Channel id for global_db sync - int res = dap_chain_node_client_send_ch_pkt(l_node_client, l_ch_id, - DAP_STREAM_CH_CHAIN_PKT_TYPE_SYNC_GLOBAL_DB , &l_sync_gdb, - sizeof (l_sync_gdb) ); - if(res != 1) { + + size_t l_res = dap_stream_ch_chain_pkt_write( dap_client_get_stream_ch(l_node_client->client, + dap_stream_ch_chain_get_id() ) , + DAP_STREAM_CH_CHAIN_PKT_TYPE_SYNC_GLOBAL_DB, l_net->pub.id, (dap_chain_id_t){{0}} , + l_net->pub.cell_id, &l_sync_gdb, sizeof (l_sync_gdb) ); + if(l_res == 0) { log_it(L_WARNING,"Can't send GDB sync request"); HASH_DEL(PVT(l_net)->links,l_node_client); dap_chain_node_client_close(l_node_client); @@ -246,7 +383,7 @@ lb_proc_state: // wait for finishing of request int timeout_ms = 120000; // 2 min = 120 sec = 120 000 ms // TODO add progress info to console - res = dap_chain_node_client_wait(l_node_client, NODE_CLIENT_STATE_SYNCED, timeout_ms); + int res = dap_chain_node_client_wait(l_node_client, NODE_CLIENT_STATE_SYNCED, timeout_ms); switch (res) { case 0: log_it(L_WARNING,"Timeout with link sync"); @@ -263,8 +400,8 @@ lb_proc_state: }else { PVT(l_net)->state = NET_STATE_ONLINE; } - goto lb_proc_state; - }break; + } pthread_mutex_unlock(&PVT(l_net)->state_mutex ); goto lb_proc_state; + case NET_STATE_SYNC_CHAINS:{ dap_chain_node_client_t * l_node_client = NULL, *l_node_client_tmp = NULL; uint8_t l_ch_id = dap_stream_ch_chain_get_id(); // Channel id for global_db sync @@ -303,11 +440,10 @@ lb_proc_state: } PVT(l_net)->state = NET_STATE_ONLINE; - goto lb_proc_state; + }pthread_mutex_unlock(&PVT(l_net)->state_mutex ); goto lb_proc_state; - }break; case NET_STATE_ONLINE:{ - + log_it(L_NOTICE,"State online"); } break; } pthread_mutex_unlock(&PVT(l_net)->state_mutex ); @@ -329,7 +465,7 @@ static void * s_net_proc_thread ( void * a_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"); + log_it( L_DEBUG, "Waked up net proHASH_COUNT( c thread"); } return NULL; @@ -436,6 +572,10 @@ void dap_chain_net_delete( dap_chain_net_t * a_net ) int dap_chain_net_init() { dap_chain_node_cli_cmd_item_create ("net", s_cli_net, "Network commands", + "net -net <chain net name> go < online | offline >\n" + "\tFind and establish links and stay online\n" + "net -net <chain net name> get status\n" + "\tLook at current status\n" "net -net <chain net name> sync < all | gdb | chains >\n" "\tSyncronyze gdb, chains or everything\n\n" "net -net <chain net name> link < list | add | del | info | establish >\n" @@ -460,10 +600,37 @@ static int s_cli_net(int argc, const char ** argv, char **a_str_reply) if ( l_net ){ const char * l_sync_str = NULL; const char * l_links_str = NULL; + const char * l_go_str = NULL; + const char * l_get_str = NULL; dap_chain_node_cli_find_option_val(argv, arg_index, argc, "sync", &l_sync_str); dap_chain_node_cli_find_option_val(argv, arg_index, argc, "link", &l_links_str); + dap_chain_node_cli_find_option_val(argv, arg_index, argc, "go", &l_go_str); + dap_chain_node_cli_find_option_val(argv, arg_index, argc, "get", &l_get_str); + + if ( l_go_str){ + if ( strcmp(l_go_str,"online") == 0 ) { + dap_chain_net_state_go_to(l_net, NET_STATE_ONLINE); + dap_chain_node_cli_set_reply_text(a_str_reply, "Network \"%s\" go from state %s to %s", + l_net->pub.name,c_net_states[PVT(l_net)->state], + c_net_states[PVT(l_net)->state_target]); + } else if ( strcmp(l_go_str,"offline") == 0 ) { + dap_chain_net_state_go_to(l_net, NET_STATE_OFFLINE); + dap_chain_node_cli_set_reply_text(a_str_reply, "Network \"%s\" go from state %s to %s", + l_net->pub.name,c_net_states[PVT(l_net)->state], + c_net_states[PVT(l_net)->state_target]); - if ( l_links_str ){ + } + + } else if ( l_get_str){ + if ( strcmp(l_get_str,"status") == 0 ) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Network \"%s\" has state %s (target state %s), active links %u from %u", + l_net->pub.name,c_net_states[PVT(l_net)->state], + c_net_states[PVT(l_net)->state_target], HASH_COUNT( PVT(l_net)->links), + PVT(l_net)->links_addrs_count + ); + ret = 0; + } + } else if ( l_links_str ){ if ( strcmp(l_links_str,"list") == 0 ) { } else if ( strcmp(l_links_str,"add") == 0 ) { diff --git a/dap_chain_net.h b/dap_chain_net.h index 9a37113b814077692cb0f070d86e31891505999a..077288c2f48d63dae48d2ab4007825eb9509b298 100644 --- a/dap_chain_net.h +++ b/dap_chain_net.h @@ -38,10 +38,10 @@ typedef enum dap_chain_net_state{ NET_STATE_OFFLINE = 0, - NET_STATE_LINKS_PING, - NET_STATE_LINKS_PONG, + NET_STATE_LINKS_PREPARE, NET_STATE_LINKS_CONNECTING, NET_STATE_LINKS_ESTABLISHED, + NET_STATE_ADDR_REQUEST, // Waiting for address assign NET_STATE_SYNC_GDB, NET_STATE_SYNC_CHAINS, NET_STATE_ONLINE, diff --git a/dap_chain_node_client.c b/dap_chain_node_client.c index ce380cab4433fb14add6166aae1698b74b4cfd4b..3af92430da4a3bc3b1bb809745552c13af1d302a 100644 --- a/dap_chain_node_client.c +++ b/dap_chain_node_client.c @@ -163,6 +163,22 @@ static void s_ch_chain_callback_notify_packet_in(dap_stream_ch_chain_t* a_ch_cha { dap_chain_node_client_t * l_node_client = (dap_chain_node_client_t *) a_arg; switch (a_pkt_type) { + case DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_ERROR: + pthread_mutex_lock(&l_node_client->wait_mutex); + l_node_client->state = NODE_CLIENT_STATE_ERROR ; + snprintf(l_node_client->last_error,sizeof (l_node_client->last_error), + "%s", (char*) a_pkt->data ); + log_it(L_WARNING,"Received packet DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_ERROR with error \"%s\"", + l_node_client->last_error); + pthread_mutex_unlock(&l_node_client->wait_mutex); + pthread_cond_signal(&l_node_client->wait_cond); + + case DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_NODE_ADDR_LEASE: + pthread_mutex_lock(&l_node_client->wait_mutex); + l_node_client->state = NODE_CLIENT_STATE_NODE_ADDR_LEASED; + pthread_mutex_unlock(&l_node_client->wait_mutex); + pthread_cond_signal(&l_node_client->wait_cond); + break; case DAP_STREAM_CH_CHAIN_PKT_TYPE_SYNCED_ALL: case DAP_STREAM_CH_CHAIN_PKT_TYPE_SYNCED_GLOBAL_DB: case DAP_STREAM_CH_CHAIN_PKT_TYPE_SYNCED_CHAINS:{ @@ -294,7 +310,6 @@ void dap_chain_node_client_close(dap_chain_node_client_t *a_client) if(a_client) { // clean client dap_client_delete(a_client->client); - dap_events_delete(a_client->events); pthread_cond_destroy(&a_client->wait_cond); pthread_mutex_destroy(&a_client->wait_mutex); DAP_DELETE(a_client); @@ -331,7 +346,7 @@ int dap_chain_node_client_send_ch_pkt(dap_chain_node_client_t *a_client, uint8_t * waited_state state which we will wait, sample NODE_CLIENT_STATE_CONNECT or NODE_CLIENT_STATE_SENDED * return -1 false, 0 timeout, 1 end of connection or sending data */ -int dap_chain_node_client_wait(dap_chain_node_client_t *a_client, int a_waited_state, int timeout_ms) +int dap_chain_node_client_wait(dap_chain_node_client_t *a_client, int a_waited_state, int a_timeout_ms) { int ret = -1; if(!a_client) @@ -345,7 +360,7 @@ int dap_chain_node_client_wait(dap_chain_node_client_t *a_client, int a_waited_s // prepare for signal waiting struct timespec to; clock_gettime(CLOCK_MONOTONIC, &to); - int64_t nsec_new = to.tv_nsec + timeout_ms * 1000000ll; + int64_t nsec_new = to.tv_nsec + a_timeout_ms * 1000000ll; // if the new number of nanoseconds is more than a second if(nsec_new > (long) 1e9) { to.tv_sec += nsec_new / (long) 1e9; @@ -357,8 +372,11 @@ int dap_chain_node_client_wait(dap_chain_node_client_t *a_client, int a_waited_s do { int wait = pthread_cond_timedwait(&a_client->wait_cond, &a_client->wait_mutex, &to); - if(wait == 0 && a_client->state == a_waited_state) { - ret = 1; + if(wait == 0 && ( + a_client->state == a_waited_state || + a_client->state == NODE_CLIENT_STATE_ERROR ) + ) { + ret = a_client->state == a_waited_state ? 1 : -2; break; } else if(wait == ETIMEDOUT) { // 110 260 diff --git a/dap_chain_node_client.h b/dap_chain_node_client.h index b3714608357eb997d87cb3514a6bd8db1e58f6a5..6f79407f027e7465eb51c8941f2cbb790b5d2ce8 100644 --- a/dap_chain_node_client.h +++ b/dap_chain_node_client.h @@ -33,7 +33,7 @@ typedef enum dap_chain_node_client_state{ NODE_CLIENT_STATE_ERROR = -1, NODE_CLIENT_STATE_INIT=0, NODE_CLIENT_STATE_GET_NODE_ADDR=1, - NODE_CLIENT_STATE_SET_NODE_ADDR=2, + NODE_CLIENT_STATE_NODE_ADDR_LEASED=2, NODE_CLIENT_STATE_PING=3, NODE_CLIENT_STATE_PONG=4, NODE_CLIENT_STATE_CONNECT=5, @@ -55,6 +55,7 @@ typedef struct dap_chain_node_client { dap_chain_cell_id_t cell_id; dap_client_t *client; dap_events_t *events; + char last_error[128]; dap_chain_node_client_callback_t callback_connected; pthread_cond_t wait_cond; @@ -102,5 +103,5 @@ int dap_chain_node_client_send_ch_pkt(dap_chain_node_client_t *a_client, uint8_t * waited_state state which we will wait, sample NODE_CLIENT_STATE_CONNECT or NODE_CLIENT_STATE_SENDED * return -1 false, 0 timeout, 1 end of connection or sending data */ -int dap_chain_node_client_wait(dap_chain_node_client_t *client, dap_chain_node_client_state_t waited_state, int timeout_ms); +int dap_chain_node_client_wait(dap_chain_node_client_t *a_client, int a_waited_state, int a_timeout_ms);