diff --git a/modules/channel/chain/dap_stream_ch_chain.c b/modules/channel/chain/dap_stream_ch_chain.c index 562b8c3a52391f259f3ddb16810fa38af9c50a4f..11cf1f2f667b866973a061acbda49434a55b7901 100644 --- a/modules/channel/chain/dap_stream_ch_chain.c +++ b/modules/channel/chain/dap_stream_ch_chain.c @@ -445,12 +445,18 @@ static bool s_sync_update_gdb_proc_callback(dap_proc_thread_t *a_thread, void *a struct sync_request *l_sync_request = (struct sync_request *)a_arg; log_it(L_DEBUG, "Prepare request to gdb sync from %s", l_sync_request->request.id_start ? "last sync" : "zero"); dap_chain_net_t *l_net = dap_chain_net_by_id(l_sync_request->request_hdr.net_id); + if (!l_net) { + log_it(L_ERROR, "Network ID 0x%016"DAP_UINT64_FORMAT_x" not found", l_sync_request->request_hdr.net_id.uint64); + DAP_DELETE(l_sync_request); + return true; + } dap_stream_ch_t *l_ch = dap_stream_ch_find_by_uuid_unsafe(DAP_STREAM_WORKER(l_sync_request->worker), l_sync_request->ch_uuid); if (!l_ch) { log_it(L_INFO, "Client disconnected before we sent the reply"); DAP_DELETE(l_sync_request); return true; } + dap_chain_net_add_downlink(l_net, l_ch->stream_worker, l_ch->uuid); dap_stream_ch_chain_t *l_ch_chain = DAP_STREAM_CH_CHAIN(l_ch); int l_flags = 0; if (dap_chain_net_get_add_gdb_group(l_net, l_sync_request->request.node_addr)) diff --git a/modules/consensus/block-ton/include/dap_chain_cs_block_ton.h b/modules/consensus/block-ton/include/dap_chain_cs_block_ton.h index e884b112361c85395178a374970c63e0fb18044f..821714b28b30d4e83f2786a6203311bc2ed5f8f1 100644 --- a/modules/consensus/block-ton/include/dap_chain_cs_block_ton.h +++ b/modules/consensus/block-ton/include/dap_chain_cs_block_ton.h @@ -124,7 +124,7 @@ typedef struct dap_chain_cs_block_ton_message_item { dap_chain_cs_block_ton_message_t *message; dap_chain_hash_fast_t message_hash; UT_hash_handle hh; -} DAP_ALIGN_PACKED dap_chain_cs_block_ton_message_item_t; +} dap_chain_cs_block_ton_message_item_t; // struct for get info from any messages typedef struct dap_chain_cs_block_ton_message_getinfo { diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c index 786217b3192b5116da70bddab36144f472161f0e..b7be1723e8a7fbe53de3176c4cf44c0c5b8c47b1 100644 --- a/modules/net/dap_chain_net.c +++ b/modules/net/dap_chain_net.c @@ -128,6 +128,12 @@ struct net_link { dap_chain_node_client_t *link; }; +struct downlink { + dap_stream_worker_t *worker; + dap_stream_ch_uuid_t uuid; + UT_hash_handle hh; +}; + /** * @struct dap_chain_net_pvt * @details Private part of chain_net dap object @@ -157,6 +163,8 @@ typedef struct dap_chain_net_pvt{ size_t links_connected_count; bool only_static_links; + struct downlink *downlinks; // List of links who sent SYNC REQ, it used for sync broadcasting + atomic_uint links_dns_requests; bool load_mode; @@ -396,6 +404,28 @@ void dap_chain_net_add_gdb_notify_callback(dap_chain_net_t *a_net, dap_global_db PVT(a_net)->gdb_notifiers = dap_list_append(PVT(a_net)->gdb_notifiers, l_notifier); } +int dap_chain_net_add_downlink(dap_chain_net_t *a_net, dap_stream_worker_t *a_worker, dap_stream_ch_uuid_t a_ch_uuid) +{ + if (!a_net || !a_worker) + return -1; + dap_chain_net_pvt_t *l_net_pvt = PVT(a_net); + unsigned a_hash_value; + HASH_VALUE(&a_ch_uuid, sizeof(a_ch_uuid), a_hash_value); + struct downlink *l_downlink = NULL; + pthread_rwlock_rdlock(&l_net_pvt->rwlock); + HASH_FIND_BYHASHVALUE(hh, l_net_pvt->downlinks, &a_ch_uuid, sizeof(a_ch_uuid), a_hash_value, l_downlink); + if (l_downlink) { + pthread_rwlock_unlock(&l_net_pvt->rwlock); + return -2; + } + l_downlink = DAP_NEW_Z(struct downlink); + l_downlink->worker = a_worker; + l_downlink->uuid = a_ch_uuid; + HASH_ADD_BYHASHVALUE(hh, l_net_pvt->downlinks, uuid, sizeof(a_ch_uuid), a_hash_value, l_downlink); + pthread_rwlock_unlock(&l_net_pvt->rwlock); + return 0; +} + /** * @brief if current network in ONLINE state send to all connected node * executes, when you add data to gdb chain (class=gdb in chain config) @@ -412,6 +442,8 @@ void dap_chain_net_sync_gdb_broadcast(void *a_arg, const char a_op_code, const c UNUSED(a_value); UNUSED(a_value_len); dap_chain_net_t *l_net = (dap_chain_net_t *)a_arg; + if (!HASH_COUNT(PVT(l_net)->downlinks)) + return; if (PVT(l_net)->state == NET_STATE_ONLINE) { dap_store_obj_t *l_obj = NULL; if (a_op_code == DAP_DB$K_OPTYPE_DEL) { @@ -441,14 +473,15 @@ void dap_chain_net_sync_gdb_broadcast(void *a_arg, const char a_op_code, const c dap_chain_cell_id_t l_cell_id = l_chain ? l_chain->cells->id : (dap_chain_cell_id_t){}; pthread_rwlock_rdlock(&PVT(l_net)->rwlock); - for (dap_list_t *l_tmp = PVT(l_net)->net_links; l_tmp; l_tmp = dap_list_next(l_tmp)) { - dap_chain_node_client_t *l_node_client = ((struct net_link *)l_tmp->data)->link; - if (!l_node_client) - continue; - dap_stream_worker_t *l_stream_worker = dap_client_get_stream_worker(l_node_client->client); - if (!l_stream_worker) + struct downlink *l_link, *l_tmp; + HASH_ITER(hh, PVT(l_net)->downlinks, l_link, l_tmp) { + dap_stream_ch_t *l_ch = dap_stream_ch_find_by_uuid_unsafe(l_link->worker, l_link->uuid); + if (!l_ch) { + HASH_DEL(PVT(l_net)->downlinks, l_link); + DAP_DELETE(l_link); continue; - dap_stream_ch_chain_pkt_write_mt(l_stream_worker, l_node_client->ch_chain_uuid, DAP_STREAM_CH_CHAIN_PKT_TYPE_GLOBAL_DB, l_net->pub.id.uint64, + } + dap_stream_ch_chain_pkt_write_mt(l_link->worker, l_link->uuid, DAP_STREAM_CH_CHAIN_PKT_TYPE_GLOBAL_DB, l_net->pub.id.uint64, l_chain_id.uint64, l_cell_id.uint64, l_data_out, sizeof(dap_store_obj_pkt_t) + l_data_out->data_size); } @@ -540,26 +573,20 @@ static void s_chain_callback_notify(void * a_arg, dap_chain_t *a_chain, dap_chai dap_chain_net_t *l_net = (dap_chain_net_t *)a_arg; if (PVT(l_net)->state == NET_STATE_ONLINE) { pthread_rwlock_rdlock(&PVT(l_net)->rwlock); - for (dap_list_t *l_tmp = PVT(l_net)->net_links; l_tmp; l_tmp = dap_list_next(l_tmp)) { - dap_chain_node_client_t *l_node_client = ((struct net_link *)l_tmp->data)->link; - if (l_node_client) { - dap_stream_worker_t * l_worker = dap_client_get_stream_worker(l_node_client->client); - if (s_debug_more){ - if (!l_worker->channels && l_worker->worker){ - log_it(L_WARNING, "Worker id = %d hasn't active channels", l_worker->worker->id); - s_print_workers_channels(); - } - } - if(l_worker) - dap_stream_ch_chain_pkt_write_mt(l_worker, l_node_client->ch_chain_uuid, DAP_STREAM_CH_CHAIN_PKT_TYPE_CHAIN, - l_net->pub.id.uint64, a_chain->id.uint64, a_id.uint64, a_atom, a_atom_size); + struct downlink *l_link, *l_tmp; + HASH_ITER(hh, PVT(l_net)->downlinks, l_link, l_tmp) { + dap_stream_ch_t *l_ch = dap_stream_ch_find_by_uuid_unsafe(l_link->worker, l_link->uuid); + if (!l_ch) { + HASH_DEL(PVT(l_net)->downlinks, l_link); + DAP_DELETE(l_link); + continue; } + dap_stream_ch_chain_pkt_write_mt(l_link->worker, l_link->uuid, DAP_STREAM_CH_CHAIN_PKT_TYPE_CHAIN, + l_net->pub.id.uint64, a_chain->id.uint64, a_id.uint64, a_atom, a_atom_size); } pthread_rwlock_unlock(&PVT(l_net)->rwlock); - }else{ - if (s_debug_more) - log_it(L_WARNING,"Node current state is %s. Real-time syncing is possible when you in NET_STATE_LINKS_ESTABLISHED (and above) state", s_net_state_to_str(PVT(l_net)->state)); - } + } else if (s_debug_more) + log_it(L_WARNING,"Node current state is %s. Real-time syncing is possible when you in NET_STATE_ONLINE state", s_net_state_to_str(PVT(l_net)->state)); } static dap_chain_node_info_t *s_get_dns_link_from_cfg(dap_chain_net_t *a_net) @@ -2418,14 +2445,14 @@ int s_net_load(const char * a_net_name, uint16_t a_acl_idx) if (l_chain != l_chain02){ if (l_chain->id.uint64 == l_chain02->id.uint64) { - log_it(L_ERROR, "Your network %s has chains with duplicate ids: 0x%llx, chain01: %s, chain02: %s", l_chain->net_name, + log_it(L_ERROR, "Your network %s has chains with duplicate ids: 0x%"DAP_UINT64_FORMAT_U", chain01: %s, chain02: %s", l_chain->net_name, l_chain->id.uint64, l_chain->name,l_chain02->name); log_it(L_ERROR, "Please, fix your configs and restart node"); return -2; } if (!dap_strcmp(l_chain->name, l_chain02->name)) { - log_it(L_ERROR, "Your network %s has chains with duplicate names %s: chain01 id = 0x%llx, chain02 id = 0x%llx",l_chain->net_name, + log_it(L_ERROR, "Your network %s has chains with duplicate names %s: chain01 id = 0x%"DAP_UINT64_FORMAT_U", chain02 id = 0x%"DAP_UINT64_FORMAT_U"",l_chain->net_name, l_chain->name, l_chain->id.uint64, l_chain02->id.uint64); log_it(L_ERROR, "Please, fix your configs and restart node"); return -2; diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c index f9cafe4717c9a02a111a3e41be6e290e0fb8ebd6..75b166da84e2e7a0a67be9810e0d5461c3fea971 100644 --- a/modules/net/dap_chain_node_cli_cmd_tx.c +++ b/modules/net/dap_chain_node_cli_cmd_tx.c @@ -484,7 +484,8 @@ char* dap_db_history_addr(dap_chain_addr_t * a_addr, dap_chain_t * a_chain, cons if ( l_tx->header.ts_created) { struct tm l_tm; /* Convert ts to Sat May 17 01:17:08 2014 */ - if ( (localtime_r((time_t *) &l_tx->header.ts_created, &l_tm )) ) + uint64_t l_ts = l_tx->header.ts_created; + if ( (localtime_r((time_t *) &l_ts, &l_tm )) ) asctime_r (&l_tm, l_time_str); } diff --git a/modules/net/include/dap_chain_net.h b/modules/net/include/dap_chain_net.h index dc0a4bebcf88ff6baf006d5c27a07e3b9e0849e0..908cc70e159e4cfe3b14872163b5d81f75b6da8a 100644 --- a/modules/net/include/dap_chain_net.h +++ b/modules/net/include/dap_chain_net.h @@ -28,6 +28,7 @@ along with any CellFrame SDK based project. If not, see <http://www.gnu.org/lic #include <stdint.h> #include <string.h> #include "dap_net.h" +#include "dap_stream.h" #include "dap_strfuncs.h" #include "dap_string.h" #include "dap_chain_common.h" @@ -186,6 +187,7 @@ bool dap_chain_net_get_add_gdb_group(dap_chain_net_t *a_net, dap_chain_node_addr int dap_chain_net_verify_datum_for_add(dap_chain_net_t *a_net, dap_chain_datum_t * a_datum ); void dap_chain_net_dump_datum(dap_string_t *a_str_out, dap_chain_datum_t *a_datum, const char *a_hash_out_type); +int dap_chain_net_add_downlink(dap_chain_net_t *a_net, dap_stream_worker_t *a_worker, dap_stream_ch_uuid_t a_ch_uuid); void dap_chain_net_add_gdb_notify_callback(dap_chain_net_t *a_net, dap_global_db_obj_callback_notify_t a_callback, void *a_cb_arg); void dap_chain_net_sync_gdb_broadcast(void *a_arg, const char a_op_code, const char *a_group, const char *a_key, const void *a_value, const size_t a_value_len); diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c index a7d08c72a9a8abf12b653901461a4b0ae1b414e2..349fbacab50b3437aa62457cc5790983dc4e7a39 100644 --- a/modules/type/blocks/dap_chain_cs_blocks.c +++ b/modules/type/blocks/dap_chain_cs_blocks.c @@ -566,9 +566,9 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply) HASH_ITER(hh,PVT(l_blocks)->block_cache_first,l_block_cache, l_block_cache_tmp ) { char l_buf[50]; - ctime_r((time_t *)&l_block_cache->block->hdr.ts_created, l_buf); + time_t l_ts = l_block_cache->block->hdr.ts_created; dap_string_append_printf(l_str_tmp,"\t%s: ts_create=%s", - l_block_cache->block_hash_str, l_buf); + l_block_cache->block_hash_str, ctime_r(&l_ts, l_buf)); } pthread_rwlock_unlock(&PVT(l_blocks)->rwlock); diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c index 6af62fb8e0b63995f3b6b02c548b364ddca0538e..f9f095ebe7ce8b077bb7dbd05cb4cf7ebb31308f 100644 --- a/modules/type/dag/dap_chain_cs_dag.c +++ b/modules/type/dag/dap_chain_cs_dag.c @@ -1688,13 +1688,12 @@ static int s_cli_dag(int argc, char ** argv, char **a_str_reply) char * l_hash_str = dap_chain_hash_fast_to_str_new(&l_round_item->round_info.first_event_hash); dap_string_append_printf(l_str_tmp, "\t\t\t\tfirst_event_hash: %s\n", l_hash_str); DAP_DELETE(l_hash_str); - dap_string_append_printf(l_str_tmp, - "\t\t\t\tts_update: %s", - dap_ctime_r((time_t *)&l_round_item->round_info.ts_update, buf) ); - if (l_round_item->round_info.ts_confirmations_minimum_completed != 0) - dap_string_append_printf(l_str_tmp, - "\t\t\t\tts_confirmations_minimum_completed: %s", - dap_ctime_r((time_t *)&l_round_item->round_info.ts_confirmations_minimum_completed, buf) ); + time_t l_ts = l_round_item->round_info.ts_update; + dap_string_append_printf(l_str_tmp,"\t\t\t\tts_update: %s", dap_ctime_r(&l_ts, buf)); + if (l_round_item->round_info.ts_confirmations_minimum_completed != 0) { + l_ts = l_round_item->round_info.ts_confirmations_minimum_completed; + dap_string_append_printf(l_str_tmp,"\t\t\t\tts_confirmations_minimum_completed: %s", dap_ctime_r(&l_ts, buf)); + } } // Header