diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c index 5a40f88dc5cba7c894b469c858eaf0f3bb2dc5bc..3f30402bb4f9b5d9cb6e59e276a6e5086d4cade6 100644 --- a/modules/net/dap_chain_net.c +++ b/modules/net/dap_chain_net.c @@ -184,17 +184,10 @@ typedef struct dap_chain_net_pvt{ anchor_table_t *anchors; } dap_chain_net_pvt_t; -typedef struct dap_chain_net_item{ - char name[DAP_CHAIN_NET_NAME_MAX + 1]; - dap_chain_net_id_t net_id; - dap_chain_net_t *chain_net; - UT_hash_handle hh, hh2; -} dap_chain_net_item_t; - #define PVT(a) ((dap_chain_net_pvt_t *)a->pvt) #define PVT_S(a) ((dap_chain_net_pvt_t *)a.pvt) -static dap_chain_net_item_t *s_net_items = NULL, *s_net_ids = NULL; +static dap_chain_net_t *s_nets_by_name = NULL, *s_nets_by_id = NULL; static pthread_mutex_t s_net_cond_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t s_net_cond = PTHREAD_COND_INITIALIZER; static uint16_t s_net_loading_count = 0; @@ -341,13 +334,36 @@ char *dap_chain_net_get_gdb_group_acl(dap_chain_net_t *a_net) return NULL; } +DAP_STATIC_INLINE struct request_link_info *s_net_resolve_host(const char *a_addr) { + char l_host[DAP_HOSTADDR_STRLEN + 1] = { '\0' }; uint16_t l_port = 0; + struct sockaddr_storage l_saddr; + if ( dap_net_parse_config_address(a_addr, l_host, &l_port, NULL, NULL) < 0 + || dap_net_resolve_host(l_host, dap_itoa(l_port), false, &l_saddr, NULL) < 0 ) + return NULL; + struct request_link_info *l_ret = DAP_NEW_Z(struct request_link_info); + l_ret->port = l_port; + dap_strncpy(l_ret->addr, l_host, DAP_HOSTADDR_STRLEN); + return l_ret; +} + static struct request_link_info *s_balancer_link_from_cfg(dap_chain_net_t *a_net) { + uint16_t l_idx; switch (PVT(a_net)->seed_nodes_count) { case 0: return log_it(L_ERROR, "No available links in net %s! Add them in net config", a_net->pub.name), NULL; - case 1: return PVT(a_net)->seed_nodes_info[0]; - default: return PVT(a_net)->seed_nodes_info[dap_random_uint16() % PVT(a_net)->seed_nodes_count]; + case 1: + l_idx = 0; + break; + default: + l_idx = dap_random_uint16() % PVT(a_net)->seed_nodes_count; + break; + } + if ( !PVT(a_net)->seed_nodes_info[l_idx] ) { + // Unresolved before? Let's try again + const char **l_seed_nodes_hosts = dap_config_get_array_str(a_net->pub.config, "general", "seed_nodes_hosts", NULL); + PVT(a_net)->seed_nodes_info[l_idx] = s_net_resolve_host(l_seed_nodes_hosts[l_idx]); } + return PVT(a_net)->seed_nodes_info[l_idx]; } dap_chain_node_info_t *dap_chain_net_get_my_node_info(dap_chain_net_t *a_net) @@ -511,15 +527,15 @@ int s_link_manager_fill_net_info(dap_link_t *a_link) // sanity check dap_return_val_if_pass(!a_link, -1); // func work - dap_chain_net_item_t *l_net_item = NULL, *l_tmp = NULL; dap_chain_node_info_t *l_node_info = NULL; - HASH_ITER(hh, s_net_items, l_net_item, l_tmp) - if ((l_node_info = dap_chain_node_info_read(l_net_item->chain_net, &a_link->addr))) + for (dap_chain_net_t *net = s_nets_by_name; net; net = net->hh.next) { + if (( l_node_info = dap_chain_node_info_read(net, &a_link->addr) )) break; + } if (!l_node_info) return -3; a_link->uplink.ready = true; - if (dap_link_manager_link_update(&a_link->addr, l_node_info->ext_host, l_node_info->ext_port)) + if ( dap_link_manager_link_update(&a_link->addr, l_node_info->ext_host, l_node_info->ext_port) ) a_link->uplink.ready = true; DAP_DELETE(l_node_info); return 0; @@ -622,18 +638,35 @@ dap_chain_node_role_t dap_chain_net_get_role(dap_chain_net_t * a_net) * @param a_node_role * @return dap_chain_net_t* */ -static dap_chain_net_t *s_net_new(dap_chain_net_id_t *a_id, const char *a_name, - const char *a_native_ticker, const char *a_node_role) +static dap_chain_net_t *s_net_new(const char *a_net_name, dap_config_t *a_cfg) { -// sanity check - dap_return_val_if_pass(!a_id || !a_name || !a_native_ticker || !a_node_role, NULL); + dap_return_val_if_fail(a_cfg, NULL); dap_chain_net_t *l_ret = NULL; -// memory alloc + const char *l_net_name_str = dap_config_get_item_str_default(a_cfg, "general", "name", a_net_name), + *l_net_id_str = dap_config_get_item_str(a_cfg, "general", "id"), + *a_node_role = dap_config_get_item_str(a_cfg, "general", "node-role" ), + *a_native_ticker= dap_config_get_item_str(a_cfg, "general", "native_ticker"); + dap_chain_net_id_t l_net_id; + + if(!l_net_name_str || !l_net_id_str || dap_chain_net_id_parse(l_net_id_str, &l_net_id)) + return log_it(L_ERROR, "Can't create l_net, can't read name or ID config"), NULL; + + dap_chain_net_t *l_net_sought = NULL; + HASH_FIND_STR(s_nets_by_name, l_net_name_str, l_net_sought); + if (!l_net_sought) + HASH_FIND(hh2, s_nets_by_id, &l_net_id, sizeof(l_net_id), l_net_sought); + if (l_net_sought) { + log_it(L_ERROR, "Can't create net %s ID %"DAP_UINT64_FORMAT_U", an already existent net " + "%s ID %"DAP_UINT64_FORMAT_U" has the same name or ID.\n"\ + "Please, fix your configs and restart node", + l_net_name_str, l_net_id.uint64, l_net_sought->pub.name, + l_net_sought->pub.id.uint64); + return NULL; + } DAP_NEW_Z_SIZE_RET_VAL(l_ret, dap_chain_net_t, sizeof(dap_chain_net_t) + sizeof(dap_chain_net_pvt_t), NULL, NULL); DAP_NEW_Z_SIZE_RET_VAL(PVT(l_ret)->node_info, dap_chain_node_info_t, sizeof(dap_chain_node_info_t) + DAP_HOSTADDR_STRLEN + 1, NULL, l_ret); -// func work - l_ret->pub.id.uint64 = a_id->uint64; + l_ret->pub.id = l_net_id; if (strcmp (a_node_role, "root_master")==0){ PVT(l_ret)->node_role.enums = NODE_ROLE_ROOT_MASTER; } else if (strcmp( a_node_role,"root") == 0){ @@ -649,15 +682,24 @@ static dap_chain_net_t *s_net_new(dap_chain_net_id_t *a_id, const char *a_name, }else if (strcmp( a_node_role,"light") == 0){ PVT(l_ret)->node_role.enums = NODE_ROLE_LIGHT; }else{ - log_it(L_ERROR,"Unknown node role \"%s\" for network '%s'", a_node_role, a_name); + log_it(L_ERROR,"Unknown node role \"%s\" for network '%s'", a_node_role, l_net_name_str); DAP_DELETE(l_ret); return NULL; } - - if (!(l_ret->pub.name = dap_strdup(a_name)) || - !(l_ret->pub.native_ticker = dap_strdup( a_native_ticker ))) - DAP_DEL_MULTY(l_ret->pub.name, l_ret->pub.native_ticker, l_ret); - log_it (L_NOTICE, "Node role \"%s\" selected for network '%s'", a_node_role, a_name); + if (!( l_net_name_str )) + return DAP_DELETE(l_ret), log_it(L_ERROR, "Invalid net name, check [general] \"name\" in netconfig"), NULL; + dap_strncpy(l_ret->pub.name, l_net_name_str, sizeof(l_ret->pub.name)); + if (!( l_ret->pub.native_ticker = a_native_ticker )) + return DAP_DEL_MULTY(l_ret->pub.name, l_ret), + log_it(L_ERROR, "Invalid native ticker, check [general] \"native_ticker\" in %s.cfg", + l_net_name_str), + NULL; + log_it (L_NOTICE, "Node role \"%s\" selected for network '%s'", a_node_role, l_net_name_str); + l_ret->pub.config = a_cfg; + l_ret->pub.gdb_groups_prefix + = dap_config_get_item_str_default( a_cfg, "general", "gdb_groups_prefix", dap_config_get_item_str(a_cfg, "general", "name") ); + HASH_ADD_STR(s_nets_by_name, pub.name, l_ret); + HASH_ADD(hh2, s_nets_by_id, pub.id, sizeof(dap_chain_net_id_t), l_ret); return l_ret; } @@ -668,15 +710,14 @@ static dap_chain_net_t *s_net_new(dap_chain_net_id_t *a_id, const char *a_name, void dap_chain_net_load_all() { pthread_mutex_lock(&s_net_cond_lock); - s_net_loading_count = HASH_COUNT(s_net_items); + s_net_loading_count = HASH_COUNT(s_nets_by_name); if (!s_net_loading_count) { log_it(L_ERROR, "Can't find any nets"); pthread_mutex_unlock(&s_net_cond_lock); return; } - dap_chain_net_item_t *l_net_items_current = NULL, *l_net_items_tmp = NULL; - HASH_ITER(hh, s_net_items, l_net_items_current, l_net_items_tmp) - dap_proc_thread_callback_add(NULL, s_net_load, l_net_items_current->chain_net); + for (dap_chain_net_t *net = s_nets_by_name; net; net = net->hh.next) + dap_proc_thread_callback_add(NULL, s_net_load, net); while (s_net_loading_count) pthread_cond_wait(&s_net_cond, &s_net_cond_lock); pthread_mutex_unlock(&s_net_cond_lock); @@ -684,19 +725,16 @@ void dap_chain_net_load_all() dap_string_t* dap_cli_list_net() { - dap_chain_net_item_t * l_net_item, *l_net_item_tmp; dap_string_t *l_string_ret = dap_string_new(""); dap_chain_net_t * l_net = NULL; - int l_net_i = 0; - dap_string_append(l_string_ret,"Available networks and chains:\n"); - HASH_ITER(hh, s_net_items, l_net_item, l_net_item_tmp){ - l_net = l_net_item->chain_net; - dap_string_append_printf(l_string_ret, "\t%s:\n", l_net_item->name); - l_net_i++; - - dap_chain_t * l_chain = l_net->pub.chains; + unsigned l_net_i = 0; + dap_string_append(l_string_ret, "Available networks and chains:\n"); + for (dap_chain_net_t *net = s_nets_by_name; net; net = net->hh.next) { + dap_string_append_printf(l_string_ret, "\t%s:\n", l_net->pub.name); + ++l_net_i; + dap_chain_t *l_chain = l_net->pub.chains; while (l_chain) { - dap_string_append_printf(l_string_ret, "\t\t%s\n", l_chain->name ); + dap_string_append_printf( l_string_ret, "\t\t%s\n", l_chain->name ); l_chain = l_chain->next; } } @@ -963,13 +1001,11 @@ static int s_cli_net(int argc, char **argv, void **reply) json_object_object_add(l_jobj_return, "net", l_jobj_net_name); json_object_object_add(l_jobj_return, "chains", l_jobj_chains); }else{ - dap_chain_net_item_t * l_net_item, *l_net_item_tmp; json_object *l_jobj_networks = json_object_new_array(); - HASH_ITER(hh, s_net_items, l_net_item, l_net_item_tmp){ + for (dap_chain_net_t *l_net = s_nets_by_name; l_net; l_net = l_net->hh.next) { json_object *l_jobj_network = json_object_new_object(); json_object *l_jobj_chains = json_object_new_array(); - l_net = l_net_item->chain_net; - json_object *l_jobj_network_name = json_object_new_string(l_net_item->name); + json_object *l_jobj_network_name = json_object_new_string(l_net->pub.name); if (!l_jobj_network || !l_jobj_chains || !l_jobj_network_name) { json_object_put(l_jobj_return); json_object_put(l_jobj_network); @@ -1041,9 +1077,8 @@ static int s_cli_net(int argc, char **argv, void **reply) json_object *l_jobj_networks = json_object_new_array(); // show list of nets - dap_chain_net_item_t * l_net_item, *l_net_item_tmp; - HASH_ITER(hh, s_net_items, l_net_item, l_net_item_tmp){ - json_object *l_jobj_network_name = json_object_new_string(l_net_item->name); + for (dap_chain_net_t *l_net = s_nets_by_name; l_net; l_net = l_net->hh.next) { + json_object *l_jobj_network_name = json_object_new_string(l_net->pub.name); json_object_array_add(l_jobj_networks, l_jobj_network_name); } json_object_object_add(l_jobj_return, "networks", l_jobj_networks); @@ -1662,11 +1697,11 @@ void dap_chain_net_deinit() { dap_link_manager_deinit(); dap_chain_net_balancer_deinit(); - dap_chain_net_item_t *l_current_item, *l_tmp; - HASH_ITER(hh, s_net_ids, l_current_item, l_tmp) - HASH_DELETE(hh2, s_net_ids, l_current_item); - HASH_ITER(hh, s_net_items, l_current_item, l_tmp) { - dap_chain_net_delete(l_current_item->chain_net); + dap_chain_net_t *l_net, *l_tmp; + HASH_ITER(hh2, s_nets_by_id, l_net, l_tmp) { + HASH_DEL(s_nets_by_name, l_net); + HASH_DELETE(hh2, s_nets_by_id, l_net); + dap_chain_net_delete(l_net); } dap_http_ban_list_client_deinit(); } @@ -1692,15 +1727,8 @@ void dap_chain_net_delete(dap_chain_net_t *a_net) dap_global_db_cluster_delete(PVT(a_net)->nodes_states); dap_global_db_cluster_delete(PVT(a_net)->common_orders); - dap_chain_net_item_t *l_net_item = NULL; - HASH_FIND(hh, s_net_items, a_net->pub.name, strlen(a_net->pub.name), l_net_item); - if (l_net_item) { - HASH_DEL(s_net_items, l_net_item); - HASH_DELETE(hh2, s_net_ids, l_net_item); - DAP_DELETE(l_net_item); - } - DAP_DEL_Z(PVT(a_net)->authorized_nodes_addrs); - DAP_DEL_Z(PVT(a_net)->node_info); + DAP_DELETE(PVT(a_net)->authorized_nodes_addrs); + DAP_DELETE(PVT(a_net)->node_info); if (a_net->pub.ledger) { dap_ledger_purge(a_net->pub.ledger, true); dap_ledger_handle_free(a_net->pub.ledger); @@ -1711,22 +1739,15 @@ void dap_chain_net_delete(dap_chain_net_t *a_net) #ifdef DAP_LEDGER_TEST int dap_chain_net_test_init() { - dap_chain_net_id_t l_iddn = {0}; - sscanf("0xFA0", "0x%16"DAP_UINT64_FORMAT_x, &l_iddn.uint64); - dap_chain_net_t *l_net = s_net_new(&l_iddn, "Snet", "TestCoin", "root"); - - - // l_net->pub.id.uint64 = l_iddn.uint64; - // l_net->pub.native_ticker = "TestCoin"; - // l_net->pub.name = "Snet"; - - dap_chain_net_item_t *l_net_item = DAP_NEW_Z(dap_chain_net_item_t); - dap_strncpy(l_net_item->name, "Snet", DAP_CHAIN_NET_NAME_MAX); - l_net_item->chain_net = l_net; - l_net_item->net_id.uint64 = l_net->pub.id.uint64; - - HASH_ADD(hh2, s_net_ids, net_id, sizeof(l_net_item->net_id), l_net_item); - + dap_chain_net_t *l_net = DAP_NEW_Z_SIZE( sizeof(dap_chain_net_t) + sizeof(dap_chain_net_pvt_t) ); + PVT(l_net)->node_info = DAP_NEW_Z_SIZE( sizeof(dap_chain_node_info_t) + DAP_HOSTADDR_STRLEN + 1 ); + l_net->pub.id.uint64 = 0xFA0; + strcpy(l_net->pub.name, "Snet"); + l_net->pub.gdb_groups_prefix = (const char*)l_net->pub.name; + l_net->pub.native_ticker = "TestCoin"; + PVT(l_net)->node_role.enums = NODE_ROLE_ROOT; + HASH_ADD(hh2, s_nets_by_id, pub.id, sizeof(dap_chain_net_id_t), l_net); + HASH_ADD_STR(s_nets_by_name, pub.name, l_net); return 0; } #endif @@ -1743,76 +1764,36 @@ int s_net_init(const char *a_net_name, uint16_t a_acl_idx) { char *l_cfg_path = dap_strdup_printf("network/%s", a_net_name); dap_config_t *l_cfg = dap_config_open(l_cfg_path); - if (!l_cfg) { - log_it(L_ERROR,"Can't open default network config %s", l_cfg_path); - DAP_DEL_Z(l_cfg_path); - return -1; - } DAP_DELETE(l_cfg_path); + if ( !l_cfg ) + return log_it(L_ERROR,"Can't open default network config %s", l_cfg_path), -1; - const char *l_net_name_str = dap_config_get_item_str(l_cfg , "general", "name"); - const char *l_net_id_str = dap_config_get_item_str(l_cfg , "general", "id"); - dap_chain_net_id_t l_net_id; - if(!l_net_name_str || !l_net_id_str || dap_chain_net_id_parse(l_net_id_str, &l_net_id)) { - log_it(L_ERROR,"Can't create l_net, can't read name or ID config"); - return -1; - } - - dap_chain_net_item_t *l_net_item_finded = NULL; - HASH_FIND_STR(s_net_items, l_net_name_str, l_net_item_finded); - if (!l_net_item_finded) - HASH_FIND(hh2, s_net_ids, &l_net_id, sizeof(l_net_id), l_net_item_finded); - if (l_net_item_finded) { - log_it(L_ERROR,"Can't create net %s ID %"DAP_UINT64_FORMAT_U", existed net %s ID %"DAP_UINT64_FORMAT_U" has the same name or ID.\n"\ - "Please, fix your configs and restart node", - l_net_name_str, l_net_id.uint64, l_net_item_finded->name, - l_net_item_finded->net_id.uint64); - dap_config_close(l_cfg); - return -2; - } - - dap_chain_net_t *l_net = s_net_new( - &l_net_id, - dap_config_get_item_str(l_cfg , "general" , "name" ), - dap_config_get_item_str(l_cfg , "general" , "native_ticker"), - dap_config_get_item_str(l_cfg , "general" , "node-role" ) - ); - if(!l_net) { - log_it(L_ERROR,"Can't create l_net"); - dap_config_close(l_cfg); - return -1; - } + dap_chain_net_t *l_net = s_net_new(a_net_name, l_cfg); + if ( !l_net ) + return log_it(L_ERROR,"Can't create net \"%s\"", a_net_name), dap_config_close(l_cfg), -1; - l_net->pub.gdb_groups_prefix = dap_strdup( - dap_config_get_item_str_default(l_cfg, "general", "gdb_groups_prefix", - dap_config_get_item_str(l_cfg, "general", "name"))); dap_chain_net_pvt_t *l_net_pvt = PVT(l_net); l_net_pvt->load_mode = true; l_net_pvt->acl_idx = a_acl_idx; - // Bridged netwoks allowed to send transactions to + // Transaction can be sent to bridged networks uint16_t l_net_ids_count = 0; const char **l_bridged_net_ids = dap_config_get_array_str(l_cfg, "general", "bridged_network_ids", &l_net_ids_count); - for (uint16_t i = 0; i < l_net_ids_count; i++) { - dap_chain_net_id_t l_id; - if (dap_chain_net_id_parse(l_bridged_net_ids[i], &l_id) != 0) - continue; - l_net->pub.bridged_networks = dap_list_append(l_net->pub.bridged_networks, DAP_DUP(&l_id)); - } - - // Add network to the list - dap_chain_net_item_t *l_net_item = DAP_NEW_Z(dap_chain_net_item_t); - if (!l_net_item) { - log_it(L_CRITICAL, "%s", c_error_memory_alloc); - dap_chain_net_delete(l_net); - dap_config_close(l_cfg); - return -4; + if (l_net_ids_count) { + l_net->pub.bridged_networks = DAP_NEW_Z_COUNT(dap_chain_net_id_t, l_net_ids_count); + unsigned i, j; + for (i = 0, j = 0; i < l_net_ids_count; ++i) { + if (dap_chain_net_id_parse(l_bridged_net_ids[i], &l_net->pub.bridged_networks[j]) != 0) { + log_it(L_ERROR, "Can't add invalid net id \"%s\" to bridged net list of \"%s\"", + l_bridged_net_ids[i], a_net_name); + continue; + } + ++j; + } + l_net->pub.bridged_networks = j && j < i + ? DAP_REALLOC_COUNT(l_net->pub.bridged_networks, j) + : ( DAP_DELETE(l_net->pub.bridged_networks), NULL ); + l_net->pub.bridged_networks_count = j; } - dap_strncpy(l_net_item->name, dap_config_get_item_str(l_cfg, "general", "name"), DAP_CHAIN_NET_NAME_MAX); - l_net_item->chain_net = l_net; - l_net_item->net_id.uint64 = l_net->pub.id.uint64; - - HASH_ADD_STR(s_net_items, name, l_net_item); - HASH_ADD(hh2, s_net_ids, net_id, sizeof(l_net_item->net_id), l_net_item); const char **l_permanent_nodes_addrs = dap_config_get_array_str(l_cfg, "general", "permanent_nodes_addrs", &l_net_pvt->permanent_links_count); if (l_net_pvt->permanent_links_count) { @@ -1842,27 +1823,25 @@ int s_net_init(const char *a_net_name, uint16_t a_acl_idx) uint16_t l_permalink_hosts_count = 0, i, e; const char **l_permanent_links_hosts = dap_config_get_array_str(l_cfg, "general", "permanent_nodes_hosts", &l_permalink_hosts_count); for (i = 0, e = 0; i < dap_min(l_permalink_hosts_count, l_net_pvt->permanent_links_count); ++i) { - char l_host[DAP_HOSTADDR_STRLEN + 1] = { '\0' }; uint16_t l_port = 0; - struct sockaddr_storage l_saddr; - if ( dap_net_parse_config_address(l_permanent_links_hosts[i], l_host, &l_port, NULL, NULL) < 0 - || dap_net_resolve_host(l_host, dap_itoa(l_port), false, &l_saddr, NULL) < 0 ) - { + struct request_link_info *l_tmp = s_net_resolve_host( l_permanent_links_hosts[i] ); + if ( !l_tmp ) { log_it(L_ERROR, "Incorrect address \"%s\", fix \"%s\" network config" "or check internet connection and restart node", a_net_name, l_permanent_links_hosts[i]); ++e; continue; } - l_net_pvt->permanent_links[i]->uplink_port = l_port; - dap_strncpy(l_net_pvt->permanent_links[i]->uplink_addr, l_host, DAP_HOSTADDR_STRLEN); + l_net_pvt->permanent_links[i]->uplink_port = l_tmp->port; + dap_strncpy(l_net_pvt->permanent_links[i]->uplink_addr, l_tmp->addr, DAP_HOSTADDR_STRLEN); + DAP_DELETE(l_tmp); } if ( i && (e == i) ) { log_it(L_ERROR, "%d / %d permanent links are invalid or can't be accessed, fix \"%s\"" "network config or check internet connection and restart node", e, i, a_net_name); - dap_chain_net_delete(l_net); - dap_config_close(l_cfg); - return -16; + //dap_chain_net_delete(l_net); + //dap_config_close(l_cfg); + //return -16; } const char **l_authorized_nodes_addrs = dap_config_get_array_str(l_cfg, "general", "authorized_nodes_addrs", &l_net_pvt->authorized_nodes_count); @@ -1885,41 +1864,28 @@ int s_net_init(const char *a_net_name, uint16_t a_acl_idx) l_seed_nodes_hosts = dap_config_get_array_str(l_cfg, "general", "bootstrap_hosts", &l_net_pvt->seed_nodes_count); if (!l_net_pvt->seed_nodes_count) log_it(L_WARNING, "Can't read seed nodes addresses, work with local balancer only"); - else if (!(l_net_pvt->seed_nodes_info = DAP_NEW_Z_COUNT(struct request_link_info *, l_net_pvt->seed_nodes_count))) { + else if (!( l_net_pvt->seed_nodes_info = DAP_NEW_Z_COUNT(struct request_link_info*, l_net_pvt->seed_nodes_count) )) { log_it(L_CRITICAL, "%s", c_error_memory_alloc); dap_chain_net_delete(l_net); dap_config_close(l_cfg); return -4; } for (i = 0, e = 0; i < l_net_pvt->seed_nodes_count; ++i) { - char l_host[DAP_HOSTADDR_STRLEN + 1] = { '\0' }; uint16_t l_port = 0; - struct sockaddr_storage l_saddr; - if ( dap_net_parse_config_address(l_seed_nodes_hosts[i], l_host, &l_port, NULL, NULL) < 0 - || dap_net_resolve_host(l_host, dap_itoa(l_port), false, &l_saddr, NULL) < 0) - { + if (!( l_net_pvt->seed_nodes_info[i] = s_net_resolve_host(l_seed_nodes_hosts[i]) )) { log_it(L_ERROR, "Incorrect address \"%s\", fix \"%s\" network config" "or check internet connection and restart node", a_net_name, l_seed_nodes_hosts[i]); ++e; continue; } - l_net_pvt->seed_nodes_info[i] = DAP_NEW_Z(struct request_link_info); - if (!l_net_pvt->seed_nodes_info[i]) { - log_it(L_CRITICAL, "%s", c_error_memory_alloc); - dap_chain_net_delete(l_net); - dap_config_close(l_cfg); - return -4; - } - l_net_pvt->seed_nodes_info[i]->port = l_port; - dap_strncpy(l_net_pvt->seed_nodes_info[i]->addr, l_host, DAP_HOSTADDR_STRLEN); } if ( i && (e == i) ) { log_it(L_ERROR, "%d / %d seed links are invalid or can't be accessed, fix \"%s\"" "network config or check internet connection and restart node", e, i, a_net_name); - dap_chain_net_delete(l_net); - dap_config_close(l_cfg); - return -16; + //dap_chain_net_delete(l_net); + //dap_config_close(l_cfg); + //return -16; } /* *** Chains init by configs *** */ @@ -2045,7 +2011,6 @@ int s_net_init(const char *a_net_name, uint16_t a_acl_idx) l_net->pub.ledger = dap_ledger_create(l_net, l_ledger_flags); // Decrees initializing dap_chain_net_decree_init(l_net); - l_net->pub.config = l_cfg; return 0; } @@ -2217,7 +2182,7 @@ bool s_net_load(void *a_arg) DAP_CLUSTER_TYPE_EMBEDDED); DAP_DELETE(l_gdb_groups_mask); // Nodes and its aliases cluster - l_net->pub.gdb_nodes = dap_strdup_printf("%s.nodes.list",l_net->pub.gdb_groups_prefix); + snprintf(l_net->pub.gdb_nodes, sizeof(l_net->pub.gdb_nodes), "%s.%s", l_net->pub.gdb_groups_prefix, s_gdb_nodes_postfix); l_net_pvt->nodes_cluster = dap_global_db_cluster_add(dap_global_db_instance_get_default(), l_net->pub.name, dap_guuid_compose(l_net->pub.id.uint64, 0), l_net->pub.gdb_nodes, 0, true, @@ -2373,22 +2338,15 @@ bool dap_chain_net_remove_validator_from_clusters(dap_chain_t *a_chain, dap_stre } size_t dap_chain_net_count() { - return HASH_COUNT(s_net_items); + return HASH_COUNT(s_nets_by_name); } dap_chain_net_t *dap_chain_net_iter_start() { - dap_return_val_if_pass(!s_net_items, NULL); - return s_net_items->chain_net; + return s_nets_by_name; } dap_chain_net_t *dap_chain_net_iter_next(dap_chain_net_t *a_it) { - if (!a_it) - return NULL; - dap_chain_net_item_t *l_net_sought = NULL; - HASH_FIND_STR(s_net_items, a_it->pub.name, l_net_sought); - return l_net_sought && l_net_sought->hh.next - ? ((dap_chain_net_item_t*)l_net_sought->hh.next)->chain_net - : NULL; + return a_it ? a_it->hh.next : NULL; } /** @@ -2398,10 +2356,10 @@ dap_chain_net_t *dap_chain_net_iter_next(dap_chain_net_t *a_it) { */ dap_chain_net_t *dap_chain_net_by_name(const char *a_name) { - dap_chain_net_item_t *l_net_item = NULL; + dap_chain_net_t *l_net = NULL; if (a_name) - HASH_FIND(hh, s_net_items, a_name, strlen(a_name), l_net_item); - return l_net_item ? l_net_item->chain_net : NULL; + HASH_FIND_STR(s_nets_by_name, a_name, l_net); + return l_net; } /** @@ -2422,9 +2380,9 @@ dap_ledger_t * dap_ledger_by_net_name( const char * a_net_name) */ dap_chain_net_t *dap_chain_net_by_id(dap_chain_net_id_t a_id) { - dap_chain_net_item_t *l_net_item = NULL; - HASH_FIND(hh2, s_net_ids, &a_id, sizeof(a_id), l_net_item); - return l_net_item ? l_net_item->chain_net : NULL; + dap_chain_net_t *l_net = NULL; + HASH_FIND(hh2, s_nets_by_id, &a_id, sizeof(a_id), l_net); + return l_net; } /** @@ -2715,14 +2673,13 @@ static bool s_net_check_acl(dap_chain_net_t *a_net, dap_chain_hash_fast_t *a_pke */ static uint8_t *s_net_set_acl(dap_chain_hash_fast_t *a_pkey_hash) { - if (!HASH_COUNT(s_net_items)) + uint16_t l_cnt = HASH_COUNT(s_nets_by_name); + if ( !l_cnt ) return NULL; - uint8_t *l_ret = DAP_NEW_Z_SIZE(uint8_t, HASH_COUNT(s_net_items)); + uint8_t *l_ret = DAP_NEW_Z_COUNT(uint8_t, l_cnt); unsigned i = 0; - dap_chain_net_item_t *l_net_cur = NULL, *l_net_tmp = NULL; - HASH_ITER(hh, s_net_items, l_net_cur, l_net_tmp) { - l_ret[i++] = s_net_check_acl(l_net_cur->chain_net, a_pkey_hash); - } + for (dap_chain_net_t *l_net = s_nets_by_name; l_net; l_net = l_net->hh.next) + l_ret[i++] = s_net_check_acl(l_net, a_pkey_hash); return l_ret; } @@ -2955,8 +2912,8 @@ uint256_t dap_chain_net_get_reward(dap_chain_net_t *a_net, uint64_t a_block_num) void dap_chain_net_announce_addr_all() { - for (dap_chain_net_item_t *it = s_net_items; it; it = it->hh.next) - dap_chain_net_announce_addr(it->chain_net); + for (dap_chain_net_t *net = s_nets_by_name; net; net = net->hh.next) + dap_chain_net_announce_addr(net); } void dap_chain_net_announce_addr(dap_chain_net_t *a_net) @@ -3019,19 +2976,15 @@ static int s_net_try_online(dap_chain_net_t *a_net) void dap_chain_net_try_online_all() { int32_t l_ret = 0; - if(!HASH_COUNT(s_net_items)){ - log_it(L_ERROR, "Can't find any nets"); - return; - } - if (!dap_config_get_item_bool_default(g_config ,"general", "auto_online", false)) { - log_it(L_DEBUG, "Auto online is off in config"); - return; - } - dap_chain_net_item_t *l_net_items_current = NULL, *l_net_items_tmp = NULL; - HASH_ITER(hh, s_net_items, l_net_items_current, l_net_items_tmp) { - if( (l_ret = s_net_try_online(l_net_items_current->chain_net)) ) { - log_it(L_ERROR, "Can't try online state for net %s. Finished with (%d) error code.", l_net_items_current->name, l_ret); - } + if( !HASH_COUNT(s_nets_by_name) ) + return log_it(L_ERROR, "Can't find any nets"); + + if ( !dap_config_get_item_bool_default(g_config ,"general", "auto_online", false) ) + return log_it(L_DEBUG, "Auto online is off in config"); + + for (dap_chain_net_t *net = s_nets_by_name; net; net = net->hh.next) { + if (( l_ret = s_net_try_online(net) )) + log_it(L_ERROR, "Can't try online state for net %s. Finished with (%d) error code.", net, l_ret); } } @@ -3386,6 +3339,20 @@ int dap_chain_net_state_go_to(dap_chain_net_t *a_net, dap_chain_net_state_t a_ne dap_link_manager_set_net_condition(a_net->pub.id.uint64, true); for (uint16_t i = 0; i < PVT(a_net)->permanent_links_count; ++i) { dap_link_info_t *l_permalink_info = PVT(a_net)->permanent_links[i]; + if ( !*l_permalink_info->uplink_addr ) { + // Unresolved before? Let's try again + const char **l_permanent_nodes_addrs = dap_config_get_array_str(a_net->pub.config, "general", "permanent_nodes_addrs", NULL); + struct request_link_info *l_tmp = s_net_resolve_host(l_permanent_nodes_addrs[i]); + if (l_tmp) { + l_permalink_info->uplink_port = l_tmp->port; + dap_strncpy(l_permalink_info->uplink_addr, l_tmp->addr, DAP_HOSTADDR_STRLEN); + DAP_DELETE(l_tmp); + } else { + log_it(L_ERROR, "Can't resolve permanent link address %s for net %s, possibly an internet connection issue", + l_permanent_nodes_addrs[i], a_net->pub.name); + continue; + } + } if (dap_chain_net_link_add(a_net, &l_permalink_info->node_addr, l_permalink_info->uplink_addr, l_permalink_info->uplink_port)) { log_it(L_ERROR, "Can't create permanent link to addr " NODE_ADDR_FP_STR, NODE_ADDR_FP_ARGS_S(l_permalink_info->node_addr)); continue; diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c index 7fb5ce1126eaa297f36faef4a2dcd40b3fce679e..a13985e9dd79cbfa96f566a7ffcbcc5f8c386149 100644 --- a/modules/net/dap_chain_node_cli_cmd.c +++ b/modules/net/dap_chain_node_cli_cmd.c @@ -7061,8 +7061,9 @@ int com_tx_create(int a_argc, char **a_argv, void **reply) if (l_addr_to->net_id.uint64 != l_net->pub.id.uint64 && !dap_chain_addr_is_blank(l_addr_to)) { bool l_found = false; - for (dap_list_t *it = l_net->pub.bridged_networks; it; it = it->next) { - if (((dap_chain_net_id_t *)it->data)->uint64 == l_addr_to->net_id.uint64) { + int i; + for (i = 0; i < l_net->pub.bridged_networks_count; ++i) { + if (l_net->pub.bridged_networks[i].uint64 == l_addr_to->net_id.uint64) { l_found = true; break; } @@ -7070,8 +7071,8 @@ int com_tx_create(int a_argc, char **a_argv, void **reply) if (!l_found) { dap_string_t *l_allowed_list = dap_string_new(""); dap_string_append_printf(l_allowed_list, "0x%016"DAP_UINT64_FORMAT_X, l_net->pub.id.uint64); - for (dap_list_t *it = l_net->pub.bridged_networks; it; it = it->next) - dap_string_append_printf(l_allowed_list, ", 0x%016"DAP_UINT64_FORMAT_X, ((dap_chain_net_id_t *)it->data)->uint64); + for (i = 0; i < l_net->pub.bridged_networks_count; ++i) + dap_string_append_printf(l_allowed_list, ", 0x%016"DAP_UINT64_FORMAT_X, l_net->pub.bridged_networks[i].uint64); dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_DESTINATION_NETWORK_IS_UNREACHEBLE, "Destination network ID=0x%"DAP_UINT64_FORMAT_x " is unreachable. List of available network IDs:\n%s" diff --git a/modules/net/include/dap_chain_net.h b/modules/net/include/dap_chain_net.h index 904ea35a28d734a9b545c4aa082e4f6dd1292c26..ca991e0d43c20462f6612cb9fa81b5448055e3d1 100644 --- a/modules/net/include/dap_chain_net.h +++ b/modules/net/include/dap_chain_net.h @@ -54,26 +54,24 @@ typedef enum dap_chain_net_state { NET_STATE_ONLINE } dap_chain_net_state_t; +static const char s_gdb_nodes_postfix[] = ".nodes.list"; + typedef struct dap_chain_net { struct { dap_chain_net_id_t id; - char * name; - char * gdb_groups_prefix; - char * gdb_nodes; - + char name[DAP_CHAIN_NET_NAME_MAX + 1], gdb_nodes[DAP_CHAIN_NET_NAME_MAX + sizeof(s_gdb_nodes_postfix) + 1]; + const char *gdb_groups_prefix, *native_ticker; dap_list_t *keys; // List of PoA certs for net - - bool mempool_autoproc; - - dap_chain_t *chains; // double-linked list of chains - const char *native_ticker; + dap_chain_t *chains; // double-linked list of chains dap_ledger_t *ledger; - // Net fee - uint256_t fee_value; + uint256_t fee_value; // Net fee dap_chain_addr_t fee_addr; - dap_list_t *bridged_networks; // List of bridged network ID's allowed to cross-network TX + dap_chain_net_id_t *bridged_networks; // List of bridged network ID's allowed to cross-network TX + uint16_t bridged_networks_count; dap_config_t *config; + bool mempool_autoproc; } pub; + UT_hash_handle hh, hh2; uint8_t pvt[]; } dap_chain_net_t;