diff --git a/modules/common/dap_chain_datum_token.c b/modules/common/dap_chain_datum_token.c index 8ec5775a36427002c70546ae00496239a9140e65..3d11dfe3eb242d4d596c963b2d73fba75e9172d5 100644 --- a/modules/common/dap_chain_datum_token.c +++ b/modules/common/dap_chain_datum_token.c @@ -218,7 +218,7 @@ void dap_chain_datum_token_certs_dump(dap_string_t * a_str_out, byte_t * a_data_ l_offset += dap_sign_get_size(l_sign); if (l_sign->header.sign_size == 0) { dap_string_append_printf(a_str_out, "<CORRUPTED - 0 size signature>\n"); - continue; + break; } if (l_sign->header.sign_size > a_certs_size) @@ -441,9 +441,9 @@ dap_chain_datum_token_emission_t *dap_chain_datum_emission_add_sign(dap_enc_key_ if (!l_new_sign) return NULL; size_t l_emission_size = dap_chain_datum_emission_get_size((uint8_t *)a_emission); - dap_chain_datum_token_emission_t *l_ret = DAP_REALLOC(a_emission, l_emission_size + l_old_signs_size + dap_sign_get_size(l_new_sign)); size_t l_sign_size = dap_sign_get_size(l_new_sign); - memcpy(l_ret->tsd_n_signs + (size_t)l_ret->data.type_auth.tsd_total_size, l_new_sign, l_sign_size); + dap_chain_datum_token_emission_t *l_ret = DAP_REALLOC(a_emission, l_emission_size + l_old_signs_size + l_sign_size); + memcpy(l_ret->tsd_n_signs + l_old_signs_size, l_new_sign, l_sign_size); DAP_DELETE(l_new_sign); l_old_signs_size += l_sign_size; l_signs_count++; diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c index 1452fd26f9bb822bedf4ef72821c88baa173f297..b8a3f5c46fe5c483d7cff12af42ee1aef1fa72df 100644 --- a/modules/net/dap_chain_net.c +++ b/modules/net/dap_chain_net.c @@ -262,7 +262,9 @@ struct json_object *s_net_states_json_collect(dap_chain_net_t * l_net); static void s_net_states_notify(dap_chain_net_t * l_net); //static void s_net_proc_kill( dap_chain_net_t * a_net ); -int s_net_load(const char * a_net_name, uint16_t a_acl_idx); +int s_net_init(const char * a_net_name, uint16_t a_acl_idx); + +int s_net_load(dap_chain_net_t *a_net); // Notify callback for GlobalDB changes static void s_gbd_history_callback_notify(dap_global_db_context_t *a_context, dap_store_obj_t *a_obj, void *a_arg); @@ -311,6 +313,45 @@ int dap_chain_net_init() s_seed_mode = dap_config_get_item_bool_default(g_config,"general","seed_mode",false); s_debug_more = dap_config_get_item_bool_default(g_config,"chain_net","debug_more",false); + char * l_net_dir_str = dap_strdup_printf("%s/network", dap_config_path()); + DIR * l_net_dir = opendir( l_net_dir_str); + if ( l_net_dir ){ + struct dirent * l_dir_entry; + uint16_t l_acl_idx = 0; + while ( (l_dir_entry = readdir(l_net_dir) )!= NULL ){ + if (l_dir_entry->d_name[0]=='\0' || l_dir_entry->d_name[0]=='.') + continue; + // don't search in directories + char * l_full_path = dap_strdup_printf("%s/%s", l_net_dir_str, l_dir_entry->d_name); + if(dap_dir_test(l_full_path)) { + DAP_DELETE(l_full_path); + continue; + } + DAP_DELETE(l_full_path); + // search only ".cfg" files + if(strlen(l_dir_entry->d_name) > 4) { // It has non zero name excluding file extension + if(strncmp(l_dir_entry->d_name + strlen(l_dir_entry->d_name) - 4, ".cfg", 4) != 0) { + // its not .cfg file + continue; + } + } + log_it(L_DEBUG,"Network config %s try to load", l_dir_entry->d_name); + //char* l_dot_pos = rindex(l_dir_entry->d_name,'.'); + char* l_dot_pos = strchr(l_dir_entry->d_name,'.'); + if ( l_dot_pos ) + *l_dot_pos = '\0'; + s_net_init(l_dir_entry->d_name, l_acl_idx++); + } + closedir(l_net_dir); + }else{ + int l_errno = errno; + char l_errbuf[128]; + l_errbuf[0] = 0; + strerror_r(l_errno,l_errbuf,sizeof (l_errbuf)); + log_it(L_WARNING,"Can't open entries on path %s: \"%s\" (code %d)", l_net_dir_str, l_errbuf, l_errno); + } + DAP_DELETE (l_net_dir_str); + dap_enc_http_set_acl_callback(s_net_set_acl); log_it(L_NOTICE,"Chain networks initialized"); return 0; @@ -1442,44 +1483,21 @@ void dap_chain_net_delete( dap_chain_net_t * a_net ) */ void dap_chain_net_load_all() { - char * l_net_dir_str = dap_strdup_printf("%s/network", dap_config_path()); - DIR * l_net_dir = opendir( l_net_dir_str); - if ( l_net_dir ){ - struct dirent * l_dir_entry; - uint16_t l_acl_idx = 0; - while ( (l_dir_entry = readdir(l_net_dir) )!= NULL ){ - if (l_dir_entry->d_name[0]=='\0' || l_dir_entry->d_name[0]=='.') - continue; - // don't search in directories - char * l_full_path = dap_strdup_printf("%s/%s", l_net_dir_str, l_dir_entry->d_name); - if(dap_dir_test(l_full_path)) { - DAP_DELETE(l_full_path); - continue; - } - DAP_DELETE(l_full_path); - // search only ".cfg" files - if(strlen(l_dir_entry->d_name) > 4) { // It has non zero name excluding file extension - if(strncmp(l_dir_entry->d_name + strlen(l_dir_entry->d_name) - 4, ".cfg", 4) != 0) { - // its not .cfg file - continue; - } - } - log_it(L_DEBUG,"Network config %s try to load", l_dir_entry->d_name); - //char* l_dot_pos = rindex(l_dir_entry->d_name,'.'); - char* l_dot_pos = strchr(l_dir_entry->d_name,'.'); - if ( l_dot_pos ) - *l_dot_pos = '\0'; - s_net_load(l_dir_entry->d_name, l_acl_idx++); + dap_chain_net_t **l_net_list = NULL; + uint16_t l_net_count = 0; + int32_t l_ret = 0; + + l_net_list = dap_chain_net_list(&l_net_count); + if(!l_net_list|| !l_net_count){ + log_it(L_ERROR, "Can't find any nets"); + return; + } + + for(uint16_t i = 0; i < l_net_count; i++){ + if((l_ret = s_net_load(l_net_list[i])) != 0){ + log_it(L_ERROR, "Loading chains of net %s finished with (%d) error code.", l_net_list[i]->pub.name, l_ret); } - closedir(l_net_dir); - }else{ - int l_errno = errno; - char l_errbuf[128]; - l_errbuf[0] = 0; - strerror_r(l_errno,l_errbuf,sizeof (l_errbuf)); - log_it(L_WARNING,"Can't open entries on path %s: \"%s\" (code %d)", l_net_dir_str, l_errbuf, l_errno); } - DAP_DELETE (l_net_dir_str); } dap_string_t* dap_cli_list_net() @@ -1574,7 +1592,7 @@ static void s_chain_net_ledger_cache_reload(dap_chain_net_t *l_net) /** * @brief update ledger cache at once * if you node build need ledger cache one time reload, uncomment this function - * iat the end of s_net_load + * iat the end of s_net_init * @param l_net network object * @return true * @return false @@ -2135,7 +2153,7 @@ void s_main_timer_callback(void *a_arg) * @param a_acl_idx currently 0 * @return int */ -int s_net_load(const char * a_net_name, uint16_t a_acl_idx) +int s_net_init(const char * a_net_name, uint16_t a_acl_idx) { dap_config_t *l_cfg=NULL; dap_string_t *l_cfg_path = dap_string_new("network/"); @@ -2505,200 +2523,224 @@ int s_net_load(const char * a_net_name, uint16_t a_acl_idx) } } - char * l_chains_path = dap_strdup_printf("%s/network/%s", dap_config_path(), l_net->pub.name); - DIR * l_chains_dir = opendir(l_chains_path); - DAP_DEL_Z(l_chains_path); - if ( l_chains_dir ){ - // for sequential loading chains - dap_list_t *l_prior_list = NULL; - struct dirent * l_dir_entry; - while ( (l_dir_entry = readdir(l_chains_dir) )!= NULL ){ - if (l_dir_entry->d_name[0]=='\0') - continue; - char * l_entry_name = strdup(l_dir_entry->d_name); - if (strlen (l_entry_name) > 4 ){ // It has non zero name excluding file extension - if ( strncmp (l_entry_name+ strlen(l_entry_name)-4,".cfg",4) == 0 ) { // its .cfg file - l_entry_name [strlen(l_entry_name)-4] = 0; - log_it(L_DEBUG,"Open chain config \"%s\"...",l_entry_name); - l_chains_path = dap_strdup_printf("network/%s/%s",l_net->pub.name,l_entry_name); - dap_config_t * l_cfg = dap_config_open(l_chains_path); - if(l_cfg) { - list_priority *l_chain_prior = DAP_NEW_Z(list_priority); - l_chain_prior->prior = dap_config_get_item_uint16_default(l_cfg, "chain", "load_priority", 100); - l_chain_prior->chains_path = l_chains_path; - // add chain to load list; - l_prior_list = dap_list_append(l_prior_list, l_chain_prior); - dap_config_close(l_cfg); - } + + + DAP_DELETE(l_node_addr_str); + dap_config_close(l_cfg); + } + return 0; +} + +int s_net_load(dap_chain_net_t *a_net) +{ + dap_chain_net_t *l_net = a_net; + + dap_config_t *l_cfg=NULL; + dap_string_t *l_cfg_path = dap_string_new("network/"); + dap_string_append(l_cfg_path,a_net->pub.name); + + if( ( l_cfg = dap_config_open ( l_cfg_path->str ) ) == NULL ) { + log_it(L_ERROR,"Can't open default network config"); + dap_string_free(l_cfg_path,true); + return -1; + } + + dap_chain_net_pvt_t * l_net_pvt = PVT(l_net); + char * l_chains_path = dap_strdup_printf("%s/network/%s", dap_config_path(), l_net->pub.name); + DIR * l_chains_dir = opendir(l_chains_path); + DAP_DEL_Z(l_chains_path); + if ( l_chains_dir ){ + // for sequential loading chains + dap_list_t *l_prior_list = NULL; + + struct dirent * l_dir_entry; + while ( (l_dir_entry = readdir(l_chains_dir) )!= NULL ){ + if (l_dir_entry->d_name[0]=='\0') + continue; + char * l_entry_name = strdup(l_dir_entry->d_name); + if (strlen (l_entry_name) > 4 ){ // It has non zero name excluding file extension + if ( strncmp (l_entry_name+ strlen(l_entry_name)-4,".cfg",4) == 0 ) { // its .cfg file + l_entry_name [strlen(l_entry_name)-4] = 0; + log_it(L_DEBUG,"Open chain config \"%s\"...",l_entry_name); + l_chains_path = dap_strdup_printf("network/%s/%s",l_net->pub.name,l_entry_name); + dap_config_t * l_cfg = dap_config_open(l_chains_path); + if(l_cfg) { + list_priority *l_chain_prior = DAP_NEW_Z(list_priority); + l_chain_prior->prior = dap_config_get_item_uint16_default(l_cfg, "chain", "load_priority", 100); + l_chain_prior->chains_path = l_chains_path; + // add chain to load list; + l_prior_list = dap_list_append(l_prior_list, l_chain_prior); + dap_config_close(l_cfg); } } - DAP_DELETE (l_entry_name); - } - closedir(l_chains_dir); - - dap_chain_net_srv_stake_load_cache(l_net); - // reload ledger cache at once - if (s_chain_net_reload_ledger_cache_once(l_net)) { - log_it(L_WARNING,"Start one time ledger cache reloading"); - dap_chain_ledger_purge(l_net->pub.ledger, false); - dap_chain_net_srv_stake_cache_purge(l_net); } + DAP_DELETE (l_entry_name); + } + closedir(l_chains_dir); + + dap_chain_net_srv_stake_load_cache(l_net); + // reload ledger cache at once + if (s_chain_net_reload_ledger_cache_once(l_net)) { + log_it(L_WARNING,"Start one time ledger cache reloading"); + dap_chain_ledger_purge(l_net->pub.ledger, false); + dap_chain_net_srv_stake_cache_purge(l_net); + } - // sort list with chains names by priority - l_prior_list = dap_list_sort(l_prior_list, callback_compare_prioritity_list); + // sort list with chains names by priority + l_prior_list = dap_list_sort(l_prior_list, callback_compare_prioritity_list); - // create and load chains params by priority - dap_chain_t *l_chain; - dap_list_t *l_list = l_prior_list; - while(l_list){ - list_priority *l_chain_prior = l_list->data; - // Create chain object - l_chain = dap_chain_load_from_cfg(l_net->pub.ledger, l_net->pub.name, - l_net->pub.id, l_chain_prior->chains_path); + // create and load chains params by priority + dap_chain_t *l_chain; + dap_list_t *l_list = l_prior_list; + while(l_list){ + list_priority *l_chain_prior = l_list->data; + // Create chain object + l_chain = dap_chain_load_from_cfg(l_net->pub.ledger, l_net->pub.name, + l_net->pub.id, l_chain_prior->chains_path); - if(l_chain) { - DL_APPEND(l_net->pub.chains, l_chain); + if(l_chain) { + DL_APPEND(l_net->pub.chains, l_chain); - // add a callback to monitor changes in the chain - dap_chain_add_callback_notify(l_chain, s_chain_callback_notify, l_net); - } - DAP_DELETE (l_chain_prior->chains_path); - l_list = dap_list_next(l_list); + // add a callback to monitor changes in the chain + dap_chain_add_callback_notify(l_chain, s_chain_callback_notify, l_net); + } + DAP_DELETE (l_chain_prior->chains_path); + l_list = dap_list_next(l_list); + } + dap_list_free_full(l_prior_list, NULL); + + //load decree + dap_chain_net_decree_init(l_net); + // load chains + l_chain = l_net->pub.chains; + while(l_chain){ + dap_chain_ledger_set_fee(l_net->pub.ledger, uint256_0, c_dap_chain_addr_blank); + if (dap_chain_load_all(l_chain) == 0) + log_it (L_NOTICE, "Loaded chain files"); + else { + dap_chain_save_all( l_chain ); + log_it (L_NOTICE, "Initialized chain files"); } - dap_list_free_full(l_prior_list, NULL); - - //load decree - dap_chain_net_decree_init(l_net); - // load chains - l_chain = l_net->pub.chains; - while(l_chain){ - dap_chain_ledger_set_fee(l_net->pub.ledger, uint256_0, c_dap_chain_addr_blank); - if (dap_chain_load_all(l_chain) == 0) - log_it (L_NOTICE, "Loaded chain files"); - else { - dap_chain_save_all( l_chain ); - log_it (L_NOTICE, "Initialized chain files"); - } - if(l_chain->callback_created) - l_chain->callback_created(l_chain, l_cfg); + if(l_chain->callback_created) + l_chain->callback_created(l_chain, l_cfg); - l_chain = l_chain->next; - } + l_chain = l_chain->next; + } - dap_chain_t *l_chain02; - DL_FOREACH(l_net->pub.chains, l_chain){ - DL_FOREACH(l_net->pub.chains, l_chain02){ - 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%"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%"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; - } - remove_duplicates_in_chain_by_priority(l_chain, l_chain02); + dap_chain_t *l_chain02; + DL_FOREACH(l_net->pub.chains, l_chain){ + DL_FOREACH(l_net->pub.chains, l_chain02){ + 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%"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%"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; } + remove_duplicates_in_chain_by_priority(l_chain, l_chain02); } } + } - bool l_processed; - do { - l_processed = false; - DL_FOREACH(l_net->pub.chains, l_chain) { - if (l_chain->callback_atom_add_from_treshold) { - while (l_chain->callback_atom_add_from_treshold(l_chain, NULL)) { - log_it(L_DEBUG, "Added atom from treshold"); - l_processed = true; - } + bool l_processed; + do { + l_processed = false; + DL_FOREACH(l_net->pub.chains, l_chain) { + if (l_chain->callback_atom_add_from_treshold) { + while (l_chain->callback_atom_add_from_treshold(l_chain, NULL)) { + log_it(L_DEBUG, "Added atom from treshold"); + l_processed = true; } } - } while (l_processed); - } else { - log_it(L_ERROR, "Can't find any chains for network %s", l_net->pub.name); - l_net_pvt->load_mode = false; - return -2; - } - // Do specific role actions post-chain created - l_net_pvt->state_target = NET_STATE_OFFLINE; - dap_chain_net_state_t l_target_state = NET_STATE_OFFLINE; - l_net_pvt->only_static_links = false; - switch ( l_net_pvt->node_role.enums ) { - case NODE_ROLE_ROOT_MASTER:{ - // Set to process everything in datum pool - 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"); - } // Master root includes root - case NODE_ROLE_ROOT:{ - // Set to process only zerochain + } + } while (l_processed); + } else { + log_it(L_ERROR, "Can't find any chains for network %s", l_net->pub.name); + l_net_pvt->load_mode = false; + return -2; + } + + // Do specific role actions post-chain created + l_net_pvt->state_target = NET_STATE_OFFLINE; + dap_chain_net_state_t l_target_state = NET_STATE_OFFLINE; + l_net_pvt->only_static_links = false; + switch ( l_net_pvt->node_role.enums ) { + case NODE_ROLE_ROOT_MASTER:{ + // Set to process everything in datum pool + 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"); + } // 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); + if (l_chain ) + l_chain->is_datum_pool_proc = true; + l_net_pvt->only_static_links = true; + l_target_state = NET_STATE_ONLINE; + log_it(L_INFO,"Root node role established"); + } break; + case NODE_ROLE_CELL_MASTER: + case NODE_ROLE_MASTER:{ + + uint16_t l_proc_chains_count=0; + char ** l_proc_chains = dap_config_get_array_str(l_cfg,"role-master" , "proc_chains", &l_proc_chains_count ); + for ( size_t i = 0; i< l_proc_chains_count ; i++){ 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); - if (l_chain ) - l_chain->is_datum_pool_proc = true; - l_net_pvt->only_static_links = true; - l_target_state = NET_STATE_ONLINE; - log_it(L_INFO,"Root node role established"); - } break; - case NODE_ROLE_CELL_MASTER: - case NODE_ROLE_MASTER:{ - - uint16_t l_proc_chains_count=0; - char ** l_proc_chains = dap_config_get_array_str(l_cfg,"role-master" , "proc_chains", &l_proc_chains_count ); - for ( size_t i = 0; i< l_proc_chains_count ; i++){ - dap_chain_id_t l_chain_id = {{0}}; - if (sscanf( l_proc_chains[i], "0x%16"DAP_UINT64_FORMAT_X, &l_chain_id.uint64) ==1 || - sscanf(l_proc_chains[i], "0x%16"DAP_UINT64_FORMAT_x, &l_chain_id.uint64) == 1) { - dap_chain_t * l_chain = dap_chain_find_by_id(l_net->pub.id, l_chain_id ); - if ( l_chain ){ - l_chain->is_datum_pool_proc = true; - }else{ - log_it( L_WARNING, "Can't find chain id " ); - } + if (sscanf( l_proc_chains[i], "0x%16"DAP_UINT64_FORMAT_X, &l_chain_id.uint64) ==1 || + sscanf(l_proc_chains[i], "0x%16"DAP_UINT64_FORMAT_x, &l_chain_id.uint64) == 1) { + dap_chain_t * l_chain = dap_chain_find_by_id(l_net->pub.id, l_chain_id ); + if ( l_chain ){ + l_chain->is_datum_pool_proc = true; + }else{ + log_it( L_WARNING, "Can't find chain id " ); } } - l_net_pvt->only_static_links = true; - l_target_state = NET_STATE_ONLINE; - log_it(L_INFO,"Master node role established"); - } break; - case NODE_ROLE_FULL:{ - log_it(L_INFO,"Full node role established"); - l_target_state = NET_STATE_ONLINE; - } break; - case NODE_ROLE_LIGHT: - default: - log_it(L_INFO,"Light node role established"); + } + l_net_pvt->only_static_links = true; + l_target_state = NET_STATE_ONLINE; + log_it(L_INFO,"Master node role established"); + } break; + case NODE_ROLE_FULL:{ + log_it(L_INFO,"Full node role established"); + l_target_state = NET_STATE_ONLINE; + } break; + case NODE_ROLE_LIGHT: + default: + log_it(L_INFO,"Light node role established"); - } - if (!l_net_pvt->only_static_links) - l_net_pvt->only_static_links = dap_config_get_item_bool_default(l_cfg, "general", "links_static_only", false); - if (s_seed_mode || !dap_config_get_item_bool_default(g_config ,"general", "auto_online",false ) ) { // If we seed we do everything manual. First think - prefil list of node_addrs and its aliases - l_target_state = NET_STATE_OFFLINE; - } - l_net_pvt->load_mode = false; - dap_chain_ledger_load_end(l_net->pub.ledger); + } + if (!l_net_pvt->only_static_links) + l_net_pvt->only_static_links = dap_config_get_item_bool_default(l_cfg, "general", "links_static_only", false); + if (s_seed_mode || !dap_config_get_item_bool_default(g_config ,"general", "auto_online",false ) ) { // If we seed we do everything manual. First think - prefil list of node_addrs and its aliases + l_target_state = NET_STATE_OFFLINE; + } + l_net_pvt->load_mode = false; + dap_chain_ledger_load_end(l_net->pub.ledger); - l_net_pvt->balancer_http = !dap_config_get_item_bool_default(l_cfg, "general", "use_dns_links", false); + l_net_pvt->balancer_http = !dap_config_get_item_bool_default(l_cfg, "general", "use_dns_links", false); - dap_chain_net_add_gdb_notify_callback(l_net, dap_chain_net_sync_gdb_broadcast, l_net); - if (l_target_state != l_net_pvt->state_target) - dap_chain_net_state_go_to(l_net, l_target_state); + dap_chain_net_add_gdb_notify_callback(l_net, dap_chain_net_sync_gdb_broadcast, l_net); + if (l_target_state != l_net_pvt->state_target) + dap_chain_net_state_go_to(l_net, l_target_state); - uint32_t l_timeout = dap_config_get_item_uint32_default(g_config, "node_client", "timer_update_states", 600); - PVT(l_net)->main_timer = dap_interval_timer_create(l_timeout * 1000, s_main_timer_callback, l_net); - log_it(L_INFO, "Chain network \"%s\" initialized",l_net_item->name); + uint32_t l_timeout = dap_config_get_item_uint32_default(g_config, "node_client", "timer_update_states", 600); + PVT(l_net)->main_timer = dap_interval_timer_create(l_timeout * 1000, s_main_timer_callback, l_net); + log_it(L_INFO, "Chain network \"%s\" initialized",l_net->pub.name); + + dap_config_close(l_cfg); - DAP_DELETE(l_node_addr_str); - dap_config_close(l_cfg); - } return 0; } diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c index 531606226a58ecc53c3fc162c4490a252a288d15..b278fab3614b66fc0f90bdd1590d0b4adaf41e5e 100644 --- a/modules/net/dap_chain_node_cli_cmd_tx.c +++ b/modules/net/dap_chain_node_cli_cmd_tx.c @@ -673,7 +673,24 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) if(l_is_all) { // without filters //l_str_out = dap_db_history_filter(l_chain_cur, l_ledger, NULL, NULL, l_hash_out_type, -1, 0, NULL, l_list_tx_hash_processd); - dap_string_append_printf(l_str_ret, "all history:\n%s\n", l_str_out ? l_str_out : " empty"); + //Print tx from ledger + size_t l_tx_count = dap_chain_ledger_count(l_ledger); + if (!l_tx_count) { + dap_string_append_printf(l_str_ret, "Network ledger %s contains no transactions.\n", l_ledger->net_name); + } else { + dap_string_append_printf(l_str_ret, "There are %zu transactions in the network ledger %s:\n", + l_tx_count, l_ledger->net_name); + dap_list_t *l_txs_list = dap_chain_ledger_get_txs(l_ledger, l_tx_count, 1, true); + for (dap_list_t *iter = l_txs_list; iter; iter = dap_list_next(iter)) { + dap_chain_datum_tx_t *l_tx = iter->data; + size_t l_tx_size = dap_chain_datum_tx_get_size(l_tx); + dap_hash_fast_t l_tx_hash = {0}; + dap_hash_fast(l_tx, l_tx_size, &l_tx_hash); + const char *l_tx_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, &l_tx_hash); + dap_chain_datum_dump_tx(l_tx, l_tx_ticker, l_str_ret, l_hash_out_type, &l_tx_hash); + } + dap_list_free1(l_txs_list); + } } else {/* l_str_out = l_tx_hash_str ? diff --git a/modules/service/stake_pos_delegate/dap_chain_net_srv_stake_pos_delegate.c b/modules/service/stake_pos_delegate/dap_chain_net_srv_stake_pos_delegate.c index 9a01c4bb34bc3d4038015ff812de82a74b70c542..53892153dc6eb70c4264b9794123fc59602e54bb 100644 --- a/modules/service/stake_pos_delegate/dap_chain_net_srv_stake_pos_delegate.c +++ b/modules/service/stake_pos_delegate/dap_chain_net_srv_stake_pos_delegate.c @@ -75,8 +75,10 @@ int dap_chain_net_srv_stake_pos_delegate_init() "\tDelegate public key in specified certificate with specified net name. Pay with specified value of m-tokens of native net token.\n" "srv_stake approve -net <net_name> -tx <transaction_hash> -poa_cert <priv_cert_name>\n" "\tApprove stake transaction by root node certificate within specified net name\n" - "srv_stake keylist -net <net_name> [-cert <delegated_cert>]\n" + "srv_stake list keys -net <net_name> [-cert <delegated_cert>]\n" "\tShow the list of active stake keys (optional delegated with specified cert).\n" + "srv_stake list tx -net <net_name> \n" + "\tShow the list of key delegation transactions.\n" "srv_stake invalidate -net <net_name> {-tx <transaction_hash> | -cert <delegated_cert> | -cert_pkey_hash <pkey_hash>}" " {-wallet <wallet_name> -fee <value> | -poa_cert <cert_name>}\n" "\tInvalidate requested delegated stake transaction by hash or cert name or cert pkey hash within net name and" @@ -160,7 +162,10 @@ void dap_chain_net_srv_stake_key_delegate(dap_chain_net_t *a_net, dap_chain_addr l_stake->value = a_value; l_stake->tx_hash = *a_stake_tx_hash; if (!l_found) + { HASH_ADD(hh, s_srv_stake->itemlist, signing_addr, sizeof(dap_chain_addr_t), l_stake); + HASH_ADD(ht, s_srv_stake->h_itemlist, tx_hash, sizeof(dap_chain_hash_fast_t), l_stake); + } } @@ -1055,10 +1060,60 @@ static void s_srv_stake_print(dap_chain_net_srv_stake_item_t *a_stake, dap_strin DAP_DELETE(l_pkey_hash_str); } +/** + * @brief The get_tx_cond_pos_del_from_tx struct + */ +struct get_tx_cond_pos_del_from_tx +{ + dap_list_t * ret; + +}; + +/** + * @brief s_get_tx_filter_callback + * @param a_net + * @param a_tx + * @param a_arg + */ +static void s_get_tx_filter_callback(dap_chain_net_t* a_net, dap_chain_datum_tx_t *a_tx, void *a_arg) +{ + struct get_tx_cond_pos_del_from_tx * l_args = (struct get_tx_cond_pos_del_from_tx* ) a_arg; + int l_out_idx_tmp = 0; + dap_chain_tx_out_cond_t *l_tx_out_cond = NULL; + dap_hash_fast_t l_datum_hash; + + if (NULL != (l_tx_out_cond = dap_chain_datum_tx_out_cond_get(a_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE, + &l_out_idx_tmp))) + { + dap_hash_fast(a_tx, dap_chain_datum_tx_get_size(a_tx), &l_datum_hash); + if(dap_chain_ledger_tx_hash_is_used_out_item(a_net->pub.ledger,&l_datum_hash,l_out_idx_tmp)==NULL) + { + dap_chain_net_srv_stake_item_t *l_stake = NULL; + HASH_FIND(ht, s_srv_stake->h_itemlist, &l_datum_hash, sizeof(dap_hash_fast_t), l_stake); + if(!l_stake){ + l_args->ret = dap_list_append(l_args->ret,a_tx); + } + } + } + return; +} + +static int callback_compare_tx_list(const void * a_datum1, const void * a_datum2, void *a_unused) +{ + UNUSED(a_unused); + dap_chain_datum_tx_t *l_datum1 = (dap_chain_datum_tx_t*) a_datum1; + dap_chain_datum_tx_t *l_datum2 = (dap_chain_datum_tx_t*) a_datum2; + if(!l_datum1 || !l_datum2 || l_datum1->header.ts_created == l_datum2->header.ts_created) + return 0; + if(l_datum1->header.ts_created > l_datum2->header.ts_created) + return 1; + return -1; +} + static int s_cli_srv_stake(int a_argc, char **a_argv, char **a_str_reply) { enum { - CMD_NONE, CMD_ORDER, CMD_DELEGATE, CMD_APPROVE, CMD_KEY_LIST, CMD_INVALIDATE, CMD_MIN_VALUE + CMD_NONE, CMD_ORDER, CMD_DELEGATE, CMD_APPROVE, CMD_LIST, CMD_INVALIDATE, CMD_MIN_VALUE }; int l_arg_index = 1; @@ -1083,8 +1138,8 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, char **a_str_reply) l_cmd_num = CMD_APPROVE; } // Show the tx list with frozen staker funds - else if (dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, min(a_argc, l_arg_index + 1), "keylist", NULL)) { - l_cmd_num = CMD_KEY_LIST; + else if (dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, min(a_argc, l_arg_index + 1), "list", NULL)) { + l_cmd_num = CMD_LIST; } // Return staker's funds else if (dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, min(a_argc, l_arg_index + 1), "invalidate", NULL)) { @@ -1094,6 +1149,9 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, char **a_str_reply) else if (dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, min(a_argc, l_arg_index + 1), "min_value", NULL)) { l_cmd_num = CMD_MIN_VALUE; } + else if(dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, min(a_argc, l_arg_index + 1), "test_com", NULL)) { + //l_cmd_num = CMD_test; + } switch (l_cmd_num) { case CMD_ORDER: @@ -1248,53 +1306,118 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, char **a_str_reply) l_decree_hash_str); DAP_DELETE(l_decree_hash_str); } break; - case CMD_KEY_LIST: { - const char *l_net_str = NULL, - *l_cert_str = NULL; + case CMD_LIST: { + const char * sub_com = NULL; l_arg_index++; - dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str); - if (!l_net_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'keylist' requires parameter -net"); - return -3; - } - dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_str); - if (!l_net) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Network %s not found", l_net_str); - return -4; - } - dap_chain_net_srv_stake_item_t *l_stake = NULL, *l_tmp; - dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-cert", &l_cert_str); - if (l_cert_str) { - dap_cert_t *l_cert = dap_cert_find_by_name(l_cert_str); - if (!l_cert) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate not found"); - return -18; - } - dap_chain_addr_t l_signing_addr; - if (dap_chain_addr_fill_from_key(&l_signing_addr, l_cert->enc_key, l_net->pub.id)) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate is wrong"); - return -20; + if(dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "keys", &sub_com)){ + const char *l_net_str = NULL, + *l_cert_str = NULL; + l_arg_index++; + dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str); + if (!l_net_str) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'keylist' requires parameter -net"); + return -3; } - HASH_FIND(hh, s_srv_stake->itemlist, &l_signing_addr, sizeof(dap_chain_addr_t), l_stake); - if (!l_stake) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate isn't delegated or it's delegating isn't approved"); - return -21; + dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_str); + if (!l_net) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Network %s not found", l_net_str); + return -4; } - } - dap_string_t *l_reply_str = dap_string_new(""); - if (l_stake) - s_srv_stake_print(l_stake, l_reply_str); - else - HASH_ITER(hh, s_srv_stake->itemlist, l_stake, l_tmp) { - if (l_stake->net->pub.id.uint64 != l_net->pub.id.uint64) { - continue; + dap_chain_net_srv_stake_item_t *l_stake = NULL, *l_tmp; + dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-cert", &l_cert_str); + if (l_cert_str) { + dap_cert_t *l_cert = dap_cert_find_by_name(l_cert_str); + if (!l_cert) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate not found"); + return -18; + } + dap_chain_addr_t l_signing_addr; + if (dap_chain_addr_fill_from_key(&l_signing_addr, l_cert->enc_key, l_net->pub.id)) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate is wrong"); + return -20; } + HASH_FIND(hh, s_srv_stake->itemlist, &l_signing_addr, sizeof(dap_chain_addr_t), l_stake); + if (!l_stake) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate isn't delegated or it's delegating isn't approved"); + return -21; + } + } + dap_string_t *l_reply_str = dap_string_new(""); + if (l_stake) s_srv_stake_print(l_stake, l_reply_str); + else + HASH_ITER(hh, s_srv_stake->itemlist, l_stake, l_tmp) { + if (l_stake->net->pub.id.uint64 != l_net->pub.id.uint64) { + continue; + } + s_srv_stake_print(l_stake, l_reply_str); + } + if (!HASH_CNT(hh, s_srv_stake->itemlist)) { + dap_string_append(l_reply_str, "No keys found"); } - if (!HASH_CNT(hh, s_srv_stake->itemlist)) { - dap_string_append(l_reply_str, "No keys found"); + *a_str_reply = dap_string_free(l_reply_str, false); + }else if(dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "tx", &sub_com)) + { + const char *l_net_str = NULL; + l_arg_index++; + dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str); + if (!l_net_str) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'approve' requires parameter -net"); + return -3; + } + dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_str); + if (!l_net) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Network %s not found", l_net_str); + return -4; + } + struct get_tx_cond_pos_del_from_tx * l_args = DAP_NEW_Z(struct get_tx_cond_pos_del_from_tx); + dap_string_t * l_str_tmp = dap_string_new(NULL); + dap_hash_fast_t l_datum_hash; + dap_chain_datum_tx_t *l_datum_tx = NULL; + dap_chain_tx_out_cond_t *l_tx_out_cond = NULL; + int l_out_idx_tmp = 0; + char *l_hash_str = NULL; + char *spaces = {"--------------------------------------------------------------------------------------------------------------------"}; + char *l_signing_addr_str = NULL; + char *l_balance = NULL; + char* l_node_address_text_block = NULL; + dap_chain_net_get_tx_all(l_net,TX_SEARCH_TYPE_NET,s_get_tx_filter_callback, l_args); + l_args->ret = dap_list_sort(l_args->ret, callback_compare_tx_list); + for(dap_list_t *tx = l_args->ret; tx; tx = tx->next) + { + l_datum_tx = (dap_chain_datum_tx_t*)tx->data; + dap_time_t l_ts_create = (dap_time_t)l_datum_tx->header.ts_created; + char buf[50] = {[0]='\0'}; + dap_hash_fast(l_datum_tx, dap_chain_datum_tx_get_size(l_datum_tx), &l_datum_hash); + l_tx_out_cond = dap_chain_datum_tx_out_cond_get(l_datum_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE, + &l_out_idx_tmp); + l_hash_str = dap_chain_hash_fast_to_str_new(&l_datum_hash); + dap_string_append_printf(l_str_tmp,"%s \n",spaces); + dap_string_append_printf(l_str_tmp,"%s \n",dap_ctime_r(&l_ts_create, buf)); + dap_string_append_printf(l_str_tmp,"tx_hash:\t%s \n",l_hash_str); + + l_signing_addr_str = dap_chain_addr_to_str(&l_tx_out_cond->subtype.srv_stake_pos_delegate.signing_addr); + char *l_pkey_hash_str = dap_chain_hash_fast_to_str_new(&l_tx_out_cond->subtype.srv_stake_pos_delegate.signing_addr.data.hash_fast); + l_balance = dap_chain_balance_to_coins(l_tx_out_cond->header.value); + + dap_string_append_printf(l_str_tmp,"signing_addr:\t%s \n",l_signing_addr_str); + dap_string_append_printf(l_str_tmp,"signing_hash:\t%s \n",l_pkey_hash_str); + l_node_address_text_block = dap_strdup_printf("node_address:\t" NODE_ADDR_FP_STR,NODE_ADDR_FP_ARGS_S(l_tx_out_cond->subtype.srv_stake_pos_delegate.signer_node_addr)); + dap_string_append_printf(l_str_tmp,"%s \n",l_node_address_text_block); + dap_string_append_printf(l_str_tmp,"value:\t\t%s \n",l_balance); + + DAP_DELETE(l_node_address_text_block); + DAP_DELETE(l_signing_addr_str); + DAP_DELETE(l_pkey_hash_str); + DAP_DELETE(l_balance); + DAP_DELETE(l_hash_str); + } + + dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_str_tmp->str); + dap_string_free(l_str_tmp, true); + DAP_DELETE(l_args); } - *a_str_reply = dap_string_free(l_reply_str, false); + } break; case CMD_INVALIDATE: { const char *l_net_str = NULL, @@ -1494,7 +1617,7 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, char **a_str_reply) DAP_DELETE(l_decree); return -21; } - } break; + } break; default: { dap_cli_server_cmd_set_reply_text(a_str_reply, "Command %s not recognized", a_argv[l_arg_index]); return -1; diff --git a/modules/service/stake_pos_delegate/include/dap_chain_net_srv_stake_pos_delegate.h b/modules/service/stake_pos_delegate/include/dap_chain_net_srv_stake_pos_delegate.h index e54785d97c881dd05b5c34dd5b704da8c909ec49..df399d9e6b144dc0907ced263b1888815156f27d 100644 --- a/modules/service/stake_pos_delegate/include/dap_chain_net_srv_stake_pos_delegate.h +++ b/modules/service/stake_pos_delegate/include/dap_chain_net_srv_stake_pos_delegate.h @@ -37,7 +37,7 @@ typedef struct dap_chain_net_srv_stake_item { dap_chain_addr_t signing_addr; dap_chain_hash_fast_t tx_hash; dap_chain_node_addr_t node_addr; - UT_hash_handle hh; + UT_hash_handle hh,ht; } dap_chain_net_srv_stake_item_t; @@ -54,7 +54,7 @@ typedef struct dap_chain_net_srv_stake_cache_item { typedef struct dap_chain_net_srv_stake { uint256_t delegate_allowed_min; - dap_chain_net_srv_stake_item_t *itemlist; + dap_chain_net_srv_stake_item_t *itemlist, *h_itemlist; dap_chain_net_srv_stake_cache_item_t *cache; } dap_chain_net_srv_stake_t; diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c index bff5afaabb818d49090ec2cb2797bb6ea9d81323..5dc48804e1e1d86840c49c8b1b72d9c47a201f8f 100644 --- a/modules/type/blocks/dap_chain_cs_blocks.c +++ b/modules/type/blocks/dap_chain_cs_blocks.c @@ -170,7 +170,7 @@ int dap_chain_cs_blocks_init() "\t\tDump block info\n\n" "block -net <net_name> -chain <chain_name> list [-from_hash <block_hash>] [-to_hash <block_hash>]" - "[-from_dt <datetime>] [-to_dt <datetime>]\n" + "[-from_dt <datetime>] [-to_dt <datetime>] [-cert <priv_cert_name> -unspent]\n" "\t\t List blocks\n\n" "Commission collect:\n" "block -net <net_name> -chain <chain_name> fee collect\n"