diff --git a/dap-sdk b/dap-sdk index bc994841a4d5ba3148f6d568db1014b4c3031ae5..ea267c0f9432a1fb94d70a4d400c265c63405ef8 160000 --- a/dap-sdk +++ b/dap-sdk @@ -1 +1 @@ -Subproject commit bc994841a4d5ba3148f6d568db1014b4c3031ae5 +Subproject commit ea267c0f9432a1fb94d70a4d400c265c63405ef8 diff --git a/modules/common/include/dap_chain_common.h b/modules/common/include/dap_chain_common.h index f3c8a93b92ebc504a91ae28894983090920a8539..5d538a307df9b7a82eb7a94b260c34e1b516e013 100644 --- a/modules/common/include/dap_chain_common.h +++ b/modules/common/include/dap_chain_common.h @@ -75,6 +75,20 @@ typedef union dap_chain_node_role{ uint8_t raw[DAP_CHAIN_NODE_ROLE_SIZE]; } DAP_ALIGN_PACKED dap_chain_node_role_t; +DAP_STATIC_INLINE const char *dap_chain_node_role_to_str(dap_chain_node_role_t a_node_role) +{ + switch (a_node_role.enums) { + case NODE_ROLE_ROOT_MASTER: return "NODE_ROLE_ROOT_MASTER"; + case NODE_ROLE_ROOT: return "NODE_ROLE_ROOT"; + case NODE_ROLE_ARCHIVE: return "NODE_ROLE_ARCHIVE"; + case NODE_ROLE_CELL_MASTER: return "NODE_ROLE_CELL_MASTER"; + case NODE_ROLE_MASTER: return "NODE_ROLE_MASTER"; + case NODE_ROLE_FULL: return "NODE_ROLE_FULL"; + case NODE_ROLE_LIGHT: return "NODE_ROLE_LIGHT"; + default: return "UNDEFINED"; + } +} + typedef dap_stream_node_addr_t dap_chain_node_addr_t; #define dap_chain_node_addr_str_check dap_stream_node_addr_str_check #define dap_chain_node_addr_from_str dap_stream_node_addr_from_str diff --git a/modules/net/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c index 9b7db963e587e3932d118cbdc5350ddcf8219c16..af0c71dcfaa156bc0d662b0b2f729584ec39d343 100644 --- a/modules/net/dap_chain_ledger.c +++ b/modules/net/dap_chain_ledger.c @@ -1618,7 +1618,8 @@ int dap_ledger_token_add(dap_ledger_t *a_ledger, byte_t *a_token, size_t a_token .token_emissions_rwlock = PTHREAD_RWLOCK_INITIALIZER, .token_ts_updated_rwlock = PTHREAD_RWLOCK_INITIALIZER, .auth_pkeys = DAP_NEW_Z_SIZE(dap_pkey_t*, sizeof(dap_pkey_t*) * l_token->signs_total), - .auth_pkey_hashes = DAP_NEW_Z_SIZE(dap_chain_hash_fast_t, sizeof(dap_chain_hash_fast_t) * l_token->signs_total) + .auth_pkey_hashes = DAP_NEW_Z_SIZE(dap_chain_hash_fast_t, sizeof(dap_chain_hash_fast_t) * l_token->signs_total), + .flags = 0 }; switch (l_token->subtype) { case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE: diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c index a0265e610a8d9620c9eeda3e32b7649e0a6075c7..b23b7b8b630f1f4b8f028c519d2b7405e62681f9 100644 --- a/modules/net/dap_chain_net.c +++ b/modules/net/dap_chain_net.c @@ -387,8 +387,10 @@ dap_stream_node_addr_t *dap_chain_net_get_authorized_nodes(dap_chain_net_t *a_ne int dap_chain_net_link_add(dap_chain_net_t *a_net, dap_stream_node_addr_t *a_addr, const char *a_host, uint16_t a_port) { bool l_is_link_present = dap_link_manager_link_find(a_addr, a_net->pub.id.uint64); - if (l_is_link_present || a_addr->uint64 == g_node_addr.uint64) + if (l_is_link_present || a_addr->uint64 == g_node_addr.uint64) { + debug_if(l_is_link_present, L_DEBUG, "Link to addr "NODE_ADDR_FP_STR" is already persent in net %s", NODE_ADDR_FP_ARGS(a_addr), a_net->pub.name); return -3; // Link is already found for this net or link is to yourself + } if (dap_link_manager_link_create(a_addr, a_net->pub.id.uint64)) { log_it(L_ERROR, "Can't create link to addr " NODE_ADDR_FP_STR, NODE_ADDR_FP_ARGS(a_addr)); return -1; @@ -462,8 +464,10 @@ static bool s_link_manager_callback_disconnected(dap_link_t *a_link, uint64_t a_ log_it(L_INFO, "%s."NODE_ADDR_FP_STR" can't connect for now. %s", l_net ? l_net->pub.name : "(unknown)" , NODE_ADDR_FP_ARGS_S(a_link->addr), l_link_is_permanent ? "Setting reconnection pause for it." : "Dropping it."); - if (!a_links_count && l_net_pvt->state == NET_STATE_ONLINE) + if (!a_links_count && l_net_pvt->state != NET_STATE_OFFLINE) { l_net_pvt->state = NET_STATE_LINKS_PREPARE; + s_net_states_proc(l_net); + } return l_link_is_permanent; } @@ -3061,9 +3065,10 @@ static void s_ch_in_pkt_callback(dap_stream_ch_t *a_ch, uint8_t a_type, const vo if (!dap_hash_fast_compare(&l_miss_info->missed_hash, &l_net_pvt->sync_context.requested_atom_hash)) { char l_missed_hash_str[DAP_HASH_FAST_STR_SIZE]; dap_hash_fast_to_str(&l_miss_info->missed_hash, l_missed_hash_str, DAP_HASH_FAST_STR_SIZE); - log_it(L_WARNING, "Get irrelevant chain sync MISSED packet with missed hash %s, but requested hash is %s", + log_it(L_WARNING, "Get irrelevant chain sync MISSED packet with missed hash %s, but requested hash is %s. Net %s chain %s", l_missed_hash_str, - dap_hash_fast_to_str_static(&l_net_pvt->sync_context.requested_atom_hash)); + dap_hash_fast_to_str_static(&l_net_pvt->sync_context.requested_atom_hash), + l_net->pub.name, l_net_pvt->sync_context.cur_chain->name); dap_stream_ch_write_error_unsafe(a_ch, l_net->pub.id, l_net_pvt->sync_context.cur_chain->id, l_net_pvt->sync_context.cur_cell @@ -3252,6 +3257,12 @@ static void s_sync_timer_callback(void *a_arg) l_net_pvt->sync_context.cur_chain->state = CHAIN_SYNC_STATE_SYNCED; return; } + // if sync more than 3 mins after online state, change state to SYNC + if (l_net_pvt->state == NET_STATE_ONLINE && l_net_pvt->sync_context.state == CHAIN_SYNC_STATE_WAITING && + dap_time_now() - l_net_pvt->sync_context.stage_last_activity > l_net_pvt->sync_context.sync_idle_time ) { + l_net_pvt->state = NET_STATE_SYNC_CHAINS; + s_net_states_proc(l_net); + } l_net_pvt->sync_context.cur_cell = l_net_pvt->sync_context.cur_chain->cells; l_net_pvt->sync_context.cur_chain->state = CHAIN_SYNC_STATE_WAITING; @@ -3401,4 +3412,4 @@ DAP_INLINE dap_chain_net_state_t dap_chain_net_get_target_state(dap_chain_net_t return PVT(a_net)->state_target; } -/*------------------------------------State machine block end---------------------------------*/ +/*------------------------------------State machine block end---------------------------------*/ \ No newline at end of file diff --git a/modules/net/dap_chain_net_balancer.c b/modules/net/dap_chain_net_balancer.c index bbd3dd7320599a509763cbe6ca94d132215b9c75..02dd26c1ad252ccc30f28083cc55c8505ee605c8 100644 --- a/modules/net/dap_chain_net_balancer.c +++ b/modules/net/dap_chain_net_balancer.c @@ -46,7 +46,6 @@ typedef struct dap_balancer_request_info { static_assert(sizeof(dap_chain_net_links_t) + sizeof(dap_chain_node_info_old_t) < DAP_BALANCER_MAX_REPLY_SIZE, "DAP_BALANCER_MAX_REPLY_SIZE cannot accommodate information minimum about 1 link"); static const size_t s_max_links_response_count = (DAP_BALANCER_MAX_REPLY_SIZE - sizeof(dap_chain_net_links_t)) / sizeof(dap_chain_node_info_old_t); -static const dap_time_t s_request_period = 5; // sec static dap_balancer_request_info_t* s_request_info_items = NULL; /** @@ -78,22 +77,30 @@ static dap_chain_net_links_t *s_get_ignored_node_addrs(dap_chain_net_t *a_net, s size_t l_size = 0, l_uplinks_count = 0, + l_downlinks_count = 0, + l_links_count = 0, l_low_availability_count = 0; const dap_stream_node_addr_t *l_curr_addr = &dap_chain_net_get_my_node_info(a_net)->address, - *l_uplinks = dap_link_manager_get_net_links_addrs(a_net->pub.id.uint64, &l_uplinks_count, NULL, true), + *l_links = dap_link_manager_get_net_links_addrs(a_net->pub.id.uint64, &l_uplinks_count, &l_downlinks_count, false), *l_low_availability = dap_link_manager_get_ignored_addrs(&l_low_availability_count, a_net->pub.id.uint64); - if(!l_curr_addr->uint64 && !l_uplinks && !l_low_availability) { + l_links_count = l_uplinks_count + l_downlinks_count; + if(!l_curr_addr->uint64 && !l_links && !l_low_availability) { log_it(L_WARNING, "Error forming ignore list in net %s, please check, should be minimum self addr", a_net->pub.name); return NULL; } + l_size = sizeof(dap_chain_net_links_t) + sizeof(dap_stream_node_addr_t) * (l_links_count + l_low_availability_count + 1); + // memory alloc + dap_chain_net_links_t *l_ret = NULL; + DAP_NEW_Z_SIZE_RET_VAL(l_ret, dap_chain_net_links_t, l_size, NULL, l_links, l_low_availability); + l_ret->count_node = l_links_count + l_low_availability_count + 1; if (dap_log_level_get() <= L_DEBUG ) { char *l_ignored_str = NULL; - DAP_NEW_Z_SIZE_RET_VAL(l_ignored_str, char, 50 * (l_uplinks_count + l_low_availability_count + 1) + 200 + strlen(a_net->pub.name), NULL, l_uplinks, l_low_availability); - sprintf(l_ignored_str + strlen(l_ignored_str), "Second %zu nodes will be ignored in balancer links preparing in net %s:\n\tSelf:\n\t\t"NODE_ADDR_FP_STR"\n", l_uplinks_count + l_low_availability_count + 1, a_net->pub.name, NODE_ADDR_FP_ARGS(l_curr_addr)); - sprintf(l_ignored_str + strlen(l_ignored_str), "\tUplinks (%zu):\n", l_uplinks_count); - for (size_t i = 0; i < l_uplinks_count; ++i) { - sprintf(l_ignored_str + strlen(l_ignored_str), "\t\t"NODE_ADDR_FP_STR"\n", NODE_ADDR_FP_ARGS(l_uplinks + i)); + DAP_NEW_Z_SIZE_RET_VAL(l_ignored_str, char, 50 * (l_ret->count_node) + 200 + strlen(a_net->pub.name), NULL, l_links, l_low_availability); + sprintf(l_ignored_str + strlen(l_ignored_str), "Second %zu nodes will be ignored in balancer links preparing in net %s:\n\tSelf:\n\t\t"NODE_ADDR_FP_STR"\n", l_ret->count_node, a_net->pub.name, NODE_ADDR_FP_ARGS(l_curr_addr)); + sprintf(l_ignored_str + strlen(l_ignored_str), "\tActive links (%zu):\n", l_links_count); + for (size_t i = 0; i < l_links_count; ++i) { + sprintf(l_ignored_str + strlen(l_ignored_str), "\t\t"NODE_ADDR_FP_STR"\n", NODE_ADDR_FP_ARGS(l_links + i)); } sprintf(l_ignored_str + strlen(l_ignored_str), "\tCooling (%zu):\n", l_low_availability_count); for (size_t i = 0; i < l_low_availability_count; ++i) { @@ -102,20 +109,15 @@ static dap_chain_net_links_t *s_get_ignored_node_addrs(dap_chain_net_t *a_net, s log_it(L_DEBUG, "%s", l_ignored_str); DAP_DELETE(l_ignored_str); } - l_size = sizeof(dap_chain_net_links_t) + sizeof(dap_stream_node_addr_t) * (l_uplinks_count + l_low_availability_count + 1); -// memory alloc - dap_chain_net_links_t *l_ret = NULL; - DAP_NEW_Z_SIZE_RET_VAL(l_ret, dap_chain_net_links_t, l_size, NULL, l_uplinks, l_low_availability); // func work memcpy(l_ret->nodes_info, l_curr_addr, sizeof(dap_stream_node_addr_t)); - if(l_uplinks) - memcpy(l_ret->nodes_info + sizeof(dap_stream_node_addr_t), l_uplinks, l_uplinks_count * sizeof(dap_stream_node_addr_t)); + if(l_links) + memcpy(l_ret->nodes_info + sizeof(dap_stream_node_addr_t), l_links, l_links_count * sizeof(dap_stream_node_addr_t)); if(l_low_availability) - memcpy(l_ret->nodes_info + (l_uplinks_count + 1) * sizeof(dap_stream_node_addr_t), l_low_availability, l_low_availability_count * sizeof(dap_stream_node_addr_t)); - l_ret->count_node = l_uplinks_count + l_low_availability_count + 1; + memcpy(l_ret->nodes_info + (l_links_count + 1) * sizeof(dap_stream_node_addr_t), l_low_availability, l_low_availability_count * sizeof(dap_stream_node_addr_t)); if (a_size) *a_size = l_size; - DAP_DEL_MULTY(l_uplinks, l_low_availability); + DAP_DEL_MULTY(l_links, l_low_availability); return l_ret; } diff --git a/modules/net/dap_chain_node.c b/modules/net/dap_chain_node.c index 11de1143ce2d11204b197d52f6e5ec0b1a81584a..48b64cbbe4be9dc8f9fe58d49e9c7997d949c87e 100644 --- a/modules/net/dap_chain_node.c +++ b/modules/net/dap_chain_node.c @@ -47,8 +47,12 @@ #include "dap_chain_ledger.h" #define LOG_TAG "dap_chain_node" +#define DAP_CHAIN_NODE_NET_STATES_INFO_CURRENT_VERSION 2 typedef struct dap_chain_node_net_states_info { + uint16_t version_info; + char version_node[16]; + dap_chain_node_role_t role; dap_chain_node_addr_t address; uint64_t events_count; uint64_t atoms_count; @@ -62,6 +66,8 @@ static const uint64_t s_cmp_delta_event = 0; static const uint64_t s_cmp_delta_atom = 10; static const uint64_t s_timer_update_states_info = 10 /*sec*/ * 1000; static const char s_states_group[] = ".nodes.states"; + // only add in version up, not change!!! +static const uint16_t s_states_version_size[DAP_CHAIN_NODE_NET_STATES_INFO_CURRENT_VERSION] = { 32, 54 }; /** * @brief get states info about current @@ -69,6 +75,10 @@ static const char s_states_group[] = ".nodes.states"; */ static void s_update_node_states_info(UNUSED_ARG void *a_arg) { +#ifndef DAP_VERSION +#pragma message "[!WRN!] DAP_VERSION IS NOT DEFINED. Manual override engaged." +#define DAP_VERSION "0.9-15" +#endif for (dap_chain_net_t *l_net = dap_chain_net_iter_start(); l_net; l_net = dap_chain_net_iter_next(l_net)) { if(dap_chain_net_get_state(l_net) != NET_STATE_OFFLINE) { size_t @@ -76,19 +86,22 @@ static void s_update_node_states_info(UNUSED_ARG void *a_arg) l_downlinks_count = 0, l_info_size = 0; // memory alloc first - dap_stream_node_addr_t *l_linked_node_addrs = dap_link_manager_get_net_links_addrs(l_net->pub.id.uint64, &l_uplinks_count, &l_downlinks_count, false); + dap_stream_node_addr_t *l_linked_node_addrs = dap_link_manager_get_net_links_addrs(l_net->pub.id.uint64, &l_uplinks_count, &l_downlinks_count, true); dap_chain_node_net_states_info_t *l_info = NULL; l_info_size = sizeof(dap_chain_node_net_states_info_t) + (l_uplinks_count + l_downlinks_count) * sizeof(dap_chain_node_addr_t); DAP_NEW_Z_SIZE_RET(l_info, dap_chain_node_net_states_info_t, l_info_size, l_linked_node_addrs); // func work // data preparing + l_info->version_info = DAP_CHAIN_NODE_NET_STATES_INFO_CURRENT_VERSION; + dap_strncpy(l_info->version_node, DAP_VERSION, sizeof(l_info->version_node) - 1); + l_info->role = dap_chain_net_get_role(l_net); l_info->address.uint64 = g_node_addr.uint64; l_info->uplinks_count = l_uplinks_count; l_info->downlinks_count = l_downlinks_count; dap_chain_t *l_chain = dap_chain_find_by_id(l_net->pub.id, (dap_chain_id_t){ .uint64 = 0 }); // zerochain l_info->events_count = (l_chain && l_chain->callback_count_atom) ? l_chain->callback_count_atom(l_chain) : 0; - l_chain = dap_chain_find_by_id(l_net->pub.id, (dap_chain_id_t){ .uint64 = 1 }); // mainchain + l_chain = l_chain ? l_chain->next : NULL; // mainchain l_info->atoms_count = (l_chain && l_chain->callback_count_atom) ? l_chain->callback_count_atom(l_chain) : 0; memcpy(l_info->links_addrs, l_linked_node_addrs, (l_info->uplinks_count + l_info->downlinks_count) * sizeof(dap_chain_node_addr_t)); @@ -110,16 +123,18 @@ static void s_states_info_to_str(dap_chain_net_t *a_net, const char *a_node_addr size_t l_data_size = 0; char *l_gdb_group = dap_strdup_printf("%s%s", a_net->pub.gdb_groups_prefix, s_states_group); dap_chain_node_net_states_info_t *l_store_obj = (dap_chain_node_net_states_info_t *)dap_global_db_get_sync(l_gdb_group, a_node_addr_str, &l_data_size, NULL, &l_timestamp); - if (!l_store_obj || l_data_size != sizeof(dap_chain_node_net_states_info_t) + (l_store_obj->uplinks_count + l_store_obj->downlinks_count) * sizeof(dap_chain_node_addr_t)) { - log_it(L_NOTICE, "Can't find state about %s node", a_node_addr_str); - DAP_DEL_Z(l_gdb_group); + if (!l_store_obj || l_store_obj->version_info != DAP_CHAIN_NODE_NET_STATES_INFO_CURRENT_VERSION || + l_data_size != s_states_version_size[DAP_CHAIN_NODE_NET_STATES_INFO_CURRENT_VERSION - 1] + (l_store_obj->uplinks_count + l_store_obj->downlinks_count) * sizeof(dap_chain_node_addr_t)) + { + log_it(L_ERROR, "Can't find state about %s node in net %s", a_node_addr_str, a_net->pub.name); + DAP_DELETE(l_gdb_group); return; } char l_ts[80] = { '\0' }; dap_nanotime_to_str_rfc822(l_ts, sizeof(l_ts), l_timestamp); dap_string_append_printf(l_info_str, - "Record timestamp: %s\nNode addr: %s\nNet: %s\nEvents count: %"DAP_UINT64_FORMAT_U"\nAtoms count: %"DAP_UINT64_FORMAT_U"\nUplinks count: %u\nDownlinks count: %u\n", - l_ts, a_node_addr_str, a_net->pub.name, l_store_obj->events_count, l_store_obj->atoms_count, l_store_obj->uplinks_count, l_store_obj->downlinks_count); + "Record timestamp: %s\nRecord version: %u\nNode version: %s\nNode addr: %s\nNet: %s\nRole: %s\nEvents count: %"DAP_UINT64_FORMAT_U"\nAtoms count: %"DAP_UINT64_FORMAT_U"\nUplinks count: %u\nDownlinks count: %u\n", + l_ts, l_store_obj->version_info, l_store_obj->version_node,a_node_addr_str, a_net->pub.name, dap_chain_node_role_to_str(l_store_obj->role), l_store_obj->events_count, l_store_obj->atoms_count, l_store_obj->uplinks_count, l_store_obj->downlinks_count); size_t l_max_links = dap_max(l_store_obj->uplinks_count, l_store_obj->downlinks_count); if(l_max_links) { dap_string_append_printf(l_info_str, @@ -422,6 +437,8 @@ static int s_node_states_info_cmp(dap_list_t *a_first, dap_list_t *a_second) if(b->events_count > a->events_count && b->events_count - a->events_count > s_cmp_delta_event) return 1; if(a->atoms_count > b->atoms_count && a->atoms_count - b->atoms_count > s_cmp_delta_atom) return -1; if(b->atoms_count > a->atoms_count && b->atoms_count - a->atoms_count > s_cmp_delta_atom) return 1; + if(a->role.enums == NODE_ROLE_ROOT) return 1; + if(b->role.enums == NODE_ROLE_ROOT) return -1; if(a->downlinks_count < b->downlinks_count) return -1; if(b->downlinks_count < a->downlinks_count) return 1; return 0; @@ -473,10 +490,15 @@ dap_list_t *dap_chain_node_get_states_list_sort(dap_chain_net_t *a_net, dap_chai if (!l_state_store_obj) { log_it(L_DEBUG, "Can't find state about %s node, apply low priority", l_objs[i].key); l_item->downlinks_count = (uint32_t)(-1); - } else if (l_data_size != sizeof(dap_chain_node_net_states_info_t) + (l_state_store_obj->uplinks_count + l_state_store_obj->downlinks_count) * sizeof(dap_chain_node_addr_t)) { - log_it(L_DEBUG, "Wrong %s node state record size, expected %zu, get %zu. Apply low priority", l_objs[i].key, sizeof(dap_chain_node_net_states_info_t) + (l_state_store_obj->uplinks_count + l_state_store_obj->downlinks_count) * sizeof(dap_chain_node_addr_t), l_data_size); + } else if ( + l_state_store_obj->version_info != DAP_CHAIN_NODE_NET_STATES_INFO_CURRENT_VERSION || + l_data_size != s_states_version_size[DAP_CHAIN_NODE_NET_STATES_INFO_CURRENT_VERSION - 1] + (l_state_store_obj->uplinks_count + l_state_store_obj->downlinks_count) * sizeof(dap_chain_node_addr_t) + ) { + log_it(L_DEBUG, "Wrong %s node state record size to state version %u, expected %zu, get %zu. Apply low priority", l_objs[i].key, l_state_store_obj->version_info, sizeof(dap_chain_node_net_states_info_t) + (l_state_store_obj->uplinks_count + l_state_store_obj->downlinks_count) * sizeof(dap_chain_node_addr_t), l_data_size); + l_item->role.enums = NODE_ROLE_ROOT; l_item->downlinks_count = (uint32_t)(-1); } else { + l_item->role.enums = l_state_store_obj->role.enums; l_item->atoms_count = l_state_store_obj->atoms_count; l_item->events_count = l_state_store_obj->events_count; l_item->downlinks_count = l_state_store_obj->downlinks_count; diff --git a/modules/net/include/dap_chain_node.h b/modules/net/include/dap_chain_node.h index 6aa06cce6f52db16434e987487561e8153b4837a..320748529e2f4747b4e5d5d46f30379baa4b87a4 100644 --- a/modules/net/include/dap_chain_node.h +++ b/modules/net/include/dap_chain_node.h @@ -56,6 +56,7 @@ typedef struct dap_chain_node_info { // using to easy sorting and formin in balancer typedef struct dap_chain_node_states_info { dap_link_info_t link_info; + dap_chain_node_role_t role; uint64_t events_count; uint64_t atoms_count; uint32_t downlinks_count;