diff --git a/dap_chain_net.c b/dap_chain_net.c index abbf467f04bae2a8ecc56d38ade781ed961470e1..17adfdd2363534a07e1a0aaee211b75c80c61580 100644 --- a/dap_chain_net.c +++ b/dap_chain_net.c @@ -309,7 +309,6 @@ lb_proc_state: if(!PVT(l_net)->links_addrs_count){ PVT(l_net)->links_addrs = DAP_NEW_Z_SIZE(dap_chain_node_addr_t, min(1, PVT(l_net)->seed_aliases_count) * sizeof(dap_chain_node_addr_t)); - for(uint16_t i = 0; i < min(1, PVT(l_net)->seed_aliases_count); i++) { dap_chain_node_addr_t * l_node_addr = dap_chain_node_alias_find(l_net, PVT(l_net)->seed_aliases[i]); if(l_node_addr) { @@ -756,7 +755,10 @@ static dap_chain_net_t *s_net_new(const char * a_id, const char * a_name , */ void dap_chain_net_delete( dap_chain_net_t * a_net ) { - if (PVT(a_net)->seed_aliases) + if(PVT(a_net)->seed_aliases) { + DAP_DELETE(PVT(a_net)->seed_aliases); + PVT(a_net)->seed_aliases = NULL; + } DAP_DELETE( PVT(a_net) ); } @@ -809,6 +811,7 @@ void dap_chain_net_load_all() *l_dot_pos = '\0'; s_net_load(l_dir_entry->d_name ); } + closedir(l_net_dir); } DAP_DELETE (l_net_dir_str); } @@ -1064,10 +1067,15 @@ int s_net_load(const char * a_net_name) } // init LEDGER model l_net->pub.ledger = dap_chain_ledger_create(l_ledger_flags); - // Check if seed nodes are present in local db alias - PVT(l_net)->seed_aliases = dap_config_get_array_str( l_cfg , "general" ,"seed_nodes_aliases" + char **l_seed_aliases = dap_config_get_array_str( l_cfg , "general" ,"seed_nodes_aliases" ,&PVT(l_net)->seed_aliases_count); + PVT(l_net)->seed_aliases = PVT(l_net)->seed_aliases_count>0 ? + (char **)DAP_NEW_SIZE(char**, sizeof(char*)*PVT(l_net)->seed_aliases_count) : NULL; + for(size_t i = 0; i < PVT(l_net)->seed_aliases_count; i++) { + PVT(l_net)->seed_aliases[i] = dap_strdup(l_seed_aliases[i]); + } + uint16_t l_seed_nodes_addrs_len =0; char ** l_seed_nodes_addrs = dap_config_get_array_str( l_cfg , "general" ,"seed_nodes_addrs" ,&l_seed_nodes_addrs_len); @@ -1079,7 +1087,6 @@ int s_net_load(const char * a_net_name) const char * l_node_ipv4_str = dap_config_get_item_str(l_cfg , "general" ,"node-ipv4"); const char * l_node_addr_str = dap_config_get_item_str(l_cfg , "general" ,"node-addr"); const char * l_node_alias_str = dap_config_get_item_str(l_cfg , "general" , "node-alias"); - log_it (L_DEBUG, "Read %u aliases, %u address and %u ipv4 addresses, check them", PVT(l_net)->seed_aliases_count,l_seed_nodes_addrs_len, l_seed_nodes_ipv4_len ); for ( size_t i = 0; i < PVT(l_net)->seed_aliases_count && @@ -1118,13 +1125,14 @@ int s_net_load(const char * a_net_name) }else log_it(L_WARNING,"No address for seed node, can't populate global_db with it"); DAP_DELETE( l_node_info); - }else + }else{ log_it(L_DEBUG,"Seed alias %s is present",PVT(l_net)->seed_aliases[i]); + DAP_DELETE( l_seed_node_addr); + } } - DAP_DELETE( l_seed_nodes_ipv4); - DAP_DELETE(l_seed_nodes_addrs); - + //DAP_DELETE( l_seed_nodes_ipv4); + //DAP_DELETE(l_seed_nodes_addrs); if ( l_node_addr_str || l_node_alias_str ){ dap_chain_node_addr_t * l_node_addr; if ( l_node_addr_str == NULL) @@ -1167,11 +1175,11 @@ int s_net_load(const char * a_net_name) } - // Init chains - size_t l_chains_path_size =strlen(dap_config_path())+1+strlen(l_net->pub.name)+1+strlen("network")+1; - char * l_chains_path = DAP_NEW_Z_SIZE (char,l_chains_path_size); - dap_snprintf(l_chains_path,l_chains_path_size,"%s/network/%s",dap_config_path(),l_net->pub.name); + //size_t l_chains_path_size =strlen(dap_config_path())+1+strlen(l_net->pub.name)+1+strlen("network")+1; + //char * l_chains_path = DAP_NEW_Z_SIZE (char,l_chains_path_size); + //dap_snprintf(l_chains_path,l_chains_path_size,"%s/network/%s",dap_config_path(),l_net->pub.name); + 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_DELETE (l_chains_path); if ( l_chains_dir ){ @@ -1180,35 +1188,31 @@ int s_net_load(const char * a_net_name) if (l_dir_entry->d_name[0]=='\0') continue; char * l_entry_name = strdup(l_dir_entry->d_name); - l_chains_path_size = strlen(l_net->pub.name)+1+strlen("network")+1+strlen (l_entry_name)-3; - l_chains_path = DAP_NEW_Z_SIZE(char, l_chains_path_size); - 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); - dap_snprintf(l_chains_path,l_chains_path_size,"network/%s/%s",l_net->pub.name,l_entry_name); - //dap_config_open(l_chains_path); - + l_chains_path = dap_strdup_printf("network/%s/%s",l_net->pub.name,l_entry_name); // Create chain object - dap_chain_t * l_chain = dap_chain_load_from_cfg(l_net->pub.ledger, l_net->pub.name, l_net->pub.id, l_chains_path); - if(l_chain){ - DL_APPEND( l_net->pub.chains, l_chain); + dap_chain_t * l_chain = dap_chain_load_from_cfg(l_net->pub.ledger, l_net->pub.name, + l_net->pub.id, l_chains_path); + if(l_chain) { + DL_APPEND(l_net->pub.chains, l_chain); if(l_chain->callback_created) - l_chain->callback_created(l_chain,l_cfg); + l_chain->callback_created(l_chain, l_cfg); } + DAP_DELETE (l_chains_path); } } - DAP_DELETE (l_chains_path); DAP_DELETE (l_entry_name); } + closedir(l_chains_dir); } else { log_it(L_ERROR,"Can't any chains for network %s",l_net->pub.name); PVT(l_net)->load_mode = false; return -2; } - // Do specific role actions post-chain created switch ( PVT( l_net )->node_role.enums ) { case NODE_ROLE_ROOT_MASTER:{ @@ -1254,8 +1258,9 @@ int s_net_load(const char * a_net_name) // Start the proc thread s_net_proc_thread_start(l_net); log_it(L_NOTICE, "Сhain network \"%s\" initialized",l_net_item->name); - return 0; + dap_config_close(l_cfg); } + return 0; } /** @@ -1341,6 +1346,47 @@ dap_chain_t * dap_chain_net_get_chain_by_name( dap_chain_net_t * l_net, const ch return NULL; } +/** + * @brief dap_chain_net_get_chain_by_chain_type + * @param a_datum_type + * @return + */ +dap_chain_t * dap_chain_net_get_chain_by_chain_type(dap_chain_net_t * l_net, dap_chain_type_t a_datum_type) +{ + dap_chain_t * l_chain; + if(!l_net) + return NULL; + DL_FOREACH(l_net->pub.chains, l_chain) + { + for(uint16_t i = 0; i < l_chain->datum_types_count; i++) { + if(l_chain->datum_types[i] == a_datum_type) + return l_chain; + } + } + return NULL; +} + +/** + * @brief dap_chain_net_get_gdb_group_mempool_by_chain_type + * @param a_datum_type + * @return + */ +char * dap_chain_net_get_gdb_group_mempool_by_chain_type(dap_chain_net_t * l_net, dap_chain_type_t a_datum_type) +{ + dap_chain_t * l_chain; + if(!l_net) + return NULL; + DL_FOREACH(l_net->pub.chains, l_chain) + { + for(uint16_t i = 0; i < l_chain->datum_types_count; i++) { + if(l_chain->datum_types[i] == a_datum_type) + return dap_chain_net_get_gdb_group_mempool(l_chain); + } + } + return NULL; +} + + /** * @brief dap_chain_net_get_cur_addr * @param l_net diff --git a/dap_chain_net.h b/dap_chain_net.h index 27384fbc1e7be732f780da90313f967651fa7401..c757b610c412d6af7b6b4891d1a42e1cc4e15dc2 100644 --- a/dap_chain_net.h +++ b/dap_chain_net.h @@ -49,7 +49,6 @@ typedef enum dap_chain_net_state{ NET_STATE_SYNC_CHAINS, } dap_chain_net_state_t; - typedef struct dap_chain_net{ struct { dap_chain_net_id_t id; @@ -103,10 +102,13 @@ void dap_chain_net_links_connect(dap_chain_net_t * a_net); */ DAP_STATIC_INLINE char * dap_chain_net_get_gdb_group_mempool(dap_chain_t * l_chain) { - dap_chain_net_t * l_net = dap_chain_net_by_id(l_chain->net_id); + dap_chain_net_t * l_net = l_chain ? dap_chain_net_by_id(l_chain->net_id) : NULL; if ( l_net ) { const char c_mempool_group_str[]="mempool"; return dap_strdup_printf("%s.chain-%s.%s",l_net->pub.gdb_groups_prefix,l_chain->name,c_mempool_group_str); } return NULL; } + +dap_chain_t * dap_chain_net_get_chain_by_chain_type(dap_chain_net_t * l_net, dap_chain_type_t a_datum_type); +char * dap_chain_net_get_gdb_group_mempool_by_chain_type(dap_chain_net_t * l_net, dap_chain_type_t a_datum_type); diff --git a/dap_chain_node_cli.c b/dap_chain_node_cli.c index ef36699b1d9df66e6036ff847631090ca6fe3278..d131c8c990f8c47f541c5aa1ccfe80124ef8388d 100644 --- a/dap_chain_node_cli.c +++ b/dap_chain_node_cli.c @@ -306,8 +306,10 @@ static void* thread_one_client_func(void *args) char *str_reply = NULL; if(l_cmd){ while(list) { + char *str_cmd_prev = str_cmd; str_cmd = dap_strdup_printf("%s;%s", str_cmd, list->data); list = dap_list_next(list); + DAP_DELETE(str_cmd_prev); } log_it(L_INFO, "execute command=%s", str_cmd); // exec command @@ -774,10 +776,10 @@ int dap_chain_node_cli_init(dap_config_t * g_config) return 0; } -/* dap_chain_node_cli_cmd_item_create("global_db", com_global_db, "Work with global database", - "global_db cells add -cell <cell id> \n\n" - "global_db wallet_info set -addr <wallet address> -cell <cell id> \n\n" - );*/ + dap_chain_node_cli_cmd_item_create("global_db", com_global_db, "Work with global database", + "global_db cells add -cell <cell id> \n\n" +// "global_db wallet_info set -addr <wallet address> -cell <cell id> \n\n" + ); dap_chain_node_cli_cmd_item_create("node", com_node, "Work with node", "node add -net <net name> -addr {<node address> | -alias <node alias>} -cell <cell id> {-ipv4 <ipv4 external address> | -ipv6 <ipv6 external address>}\n\n" diff --git a/dap_chain_node_cli_cmd.c b/dap_chain_node_cli_cmd.c index 37d703fa4e0777fa5df8f166a374fe14f73a76fa..c1e9ca101223ee102cb1b4e5833514881aad36b9 100644 --- a/dap_chain_node_cli_cmd.c +++ b/dap_chain_node_cli_cmd.c @@ -72,6 +72,7 @@ #include "dap_chain_node_cli_cmd.h" #include "dap_chain_node_cli_cmd_tx.h" #include "dap_chain_net_srv.h" +#include "dap_chain_cell.h" #include "dap_chain_datum.h" #include "dap_chain_datum_tx_items.h" @@ -631,40 +632,137 @@ static int node_info_dump_with_reply(dap_chain_net_t * a_net, dap_chain_node_add * * return 0 OK, -1 Err */ -/* + int com_global_db(int a_argc, char ** a_argv, char **a_str_reply) { enum { - CMD_NONE, CMD_ADD, CMD_DEL, CMD_LINK }; + CMD_NONE, CMD_NAME_CELL, CMD_ADD }; + int arg_index = 1; + int cmd_name = CMD_NONE; + // find 'cells' as first parameter only + arg_index = dap_chain_node_cli_find_option_val(a_argv, arg_index, min(a_argc, arg_index + 1), "cells", NULL); + if(arg_index) + cmd_name = CMD_NAME_CELL; + if(!arg_index || a_argc < 3) { + dap_chain_node_cli_set_reply_text(a_str_reply, "parameters are not valid"); + return -1; + } + dap_chain_t * l_chain = NULL; + dap_chain_net_t * l_net = NULL; + + if(dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, a_argc, a_argv, a_str_reply, &l_chain, &l_net) < 0) + return -11; + + const char *l_cell_str = NULL, *l_chain_str = NULL; + // find cell and chain + dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-cell", &l_cell_str); + dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-chain", &l_chain_str); + + // Check for chain + if(!l_chain_str) { + dap_chain_node_cli_set_reply_text(a_str_reply, "%s requires parameter 'chain' to be valid"); + return -12; + } + + int arg_index_n = ++arg_index; + // find command (add, delete, etc) as second parameter only + int cmd_num = CMD_NONE; + switch (cmd_name) { + case CMD_NAME_CELL: + if((arg_index_n = dap_chain_node_cli_find_option_val(a_argv, arg_index, min(a_argc, arg_index + 1), "add", NULL)) + != 0) { + cmd_num = CMD_ADD; + } + dap_chain_cell_id_t l_cell_id = { 0 }; + if(l_cell_str) { + dap_digit_from_string(l_cell_str, (uint8_t*) &l_cell_id.raw, sizeof(l_cell_id.raw)); //DAP_CHAIN_CELL_ID_SIZE); + } + + switch (cmd_num) + { + // add new node to global_db + case CMD_ADD: + if(!arg_index || a_argc < 7) { + dap_chain_node_cli_set_reply_text(a_str_reply, "invalid parameters"); + return -1; + } + dap_chain_cell_t *l_cell = dap_chain_cell_create(); + l_cell->chain = l_chain; + l_cell->id.uint64 = l_cell_id.uint64; + l_cell->file_storage_path = dap_strdup_printf("%0llx.dchaincell",l_cell->id.uint64); + int l_ret = dap_chain_cell_file_update(l_cell); + if(!l_ret) + dap_chain_node_cli_set_reply_text(a_str_reply, "cell added successfully"); + else + dap_chain_node_cli_set_reply_text(a_str_reply, "can't create file for cell 0x%016X ( %s )", + l_cell->id.uint64,l_cell->file_storage_path); + dap_chain_cell_delete(l_cell); + return l_ret; + + //case CMD_NONE: + default: + dap_chain_node_cli_set_reply_text(a_str_reply, "command %s not recognized", a_argv[1]); + return -1; + } + + } +} + +/* +int com_global_db_prev(int a_argc, char ** a_argv, char **a_str_reply) +{ + enum { + CMD_NONE, CMD_NAME_NODE, CMD_NAME_CELL, CMD_ADD, CMD_DEL, CMD_LINK }; //printf("com_global_db\n"); int arg_index = 1; + int cmd_name = CMD_NONE; // find 'node' as first parameter only arg_index = dap_chain_node_cli_find_option_val(a_argv, arg_index, min(a_argc, arg_index + 1), "node", NULL); + if(arg_index) + cmd_name = CMD_NAME_NODE; + // find 'cells' as first parameter only + if(!arg_index) { + arg_index = 1; + arg_index = dap_chain_node_cli_find_option_val(a_argv, arg_index, min(a_argc, arg_index + 1), "cells", NULL); + if(arg_index) + cmd_name = CMD_NAME_CELL; + } if(!arg_index || a_argc < 3) { dap_chain_node_cli_set_reply_text(a_str_reply, "parameters are not valid"); return -1; } + dap_chain_t * l_chain = NULL; dap_chain_net_t * l_net = NULL; - if(dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, a_argc, a_argv, a_str_reply, NULL, &l_net) < 0) + if(dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, a_argc, a_argv, a_str_reply, &l_chain, &l_net) < 0) return -11; int arg_index_n = ++arg_index; // find command (add, delete, etc) as second parameter only int cmd_num = CMD_NONE; - if((arg_index_n = dap_chain_node_cli_find_option_val(a_argv, arg_index, min(a_argc, arg_index + 1), "add", NULL)) - != 0) { - cmd_num = CMD_ADD; - } - else if((arg_index_n = dap_chain_node_cli_find_option_val(a_argv, arg_index, min(a_argc, arg_index + 1), "del", - NULL)) - != 0) { - cmd_num = CMD_DEL; - } - else if((arg_index_n = dap_chain_node_cli_find_option_val(a_argv, arg_index, min(a_argc, arg_index + 1), "link", - NULL)) - != 0) { - cmd_num = CMD_LINK; + switch(cmd_name){ + case CMD_NAME_NODE: + if((arg_index_n = dap_chain_node_cli_find_option_val(a_argv, arg_index, min(a_argc, arg_index + 1), "add", NULL)) + != 0) { + cmd_num = CMD_ADD; + } + else if((arg_index_n = dap_chain_node_cli_find_option_val(a_argv, arg_index, min(a_argc, arg_index + 1), "del", + NULL)) + != 0) { + cmd_num = CMD_DEL; + } + else if((arg_index_n = dap_chain_node_cli_find_option_val(a_argv, arg_index, min(a_argc, arg_index + 1), "link", + NULL)) + != 0) { + cmd_num = CMD_LINK; + } + break; + + case CMD_NAME_CELL: + if((arg_index_n = dap_chain_node_cli_find_option_val(a_argv, arg_index, min(a_argc, arg_index + 1), "add", NULL)) + != 0) { + cmd_num = CMD_ADD; + } } if(cmd_num == CMD_NONE) { @@ -674,13 +772,14 @@ int com_global_db(int a_argc, char ** a_argv, char **a_str_reply) //arg_index = arg_index_n; // no need, they are already equal must be assert(arg_index == arg_index_n); arg_index++; - const char *l_addr_str = NULL, *alias_str = NULL, *l_cell_str = NULL, *l_link_str = NULL; + const char *l_addr_str = NULL, *alias_str = NULL, *l_cell_str = NULL, *l_chain_str = NULL, *l_link_str = NULL; const char *a_ipv4_str = NULL, *a_ipv6_str = NULL; // find addr, alias dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-addr", &l_addr_str); dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-alias", &alias_str); dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-cell", &l_cell_str); + dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-chain", &l_chain_str); dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-ipv4", &a_ipv4_str); dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-ipv6", &a_ipv6_str); dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-link", &l_link_str); @@ -705,13 +804,29 @@ int com_global_db(int a_argc, char ** a_argv, char **a_str_reply) { // add new node to global_db case CMD_ADD: - if(!arg_index || a_argc < 8) { - dap_chain_node_cli_set_reply_text(a_str_reply, "invalid parameters"); - return -1; + if(cmd_name == CMD_NAME_NODE) { + if(!arg_index || a_argc < 8) { + dap_chain_node_cli_set_reply_text(a_str_reply, "invalid parameters"); + return -1; + } + // handler of command 'global_db node add' + return node_info_add_with_reply(l_net, l_node_info, alias_str, l_cell_str, a_ipv4_str, a_ipv6_str, + a_str_reply); } - // handler of command 'global_db node add' - return node_info_add_with_reply(l_net,l_node_info, alias_str, l_cell_str, a_ipv4_str, a_ipv6_str, a_str_reply); - //break; + else if(cmd_name == CMD_NAME_CELL) { + if(!arg_index || a_argc < 7) { + dap_chain_node_cli_set_reply_text(a_str_reply, "invalid parameters"); + return -1; + } + dap_chain_cell_t *l_cell = dap_chain_cell_create(); + l_cell->chain = l_chain; + l_cell->id.uint64 = l_node_info->hdr.cell_id.uint64; + l_cell->file_storage_path = "234"; + dap_chain_cell_file_update(l_cell); + DAP_DELETE(l_cell); + + } + break; case CMD_DEL: // handler of command 'global_db node del' @@ -734,7 +849,8 @@ int com_global_db(int a_argc, char ** a_argv, char **a_str_reply) dap_chain_node_cli_set_reply_text(a_str_reply, "command %s not recognized", a_argv[1]); return -1; } -}*/ +} + */ /** * Node command @@ -1519,11 +1635,16 @@ int dap_chain_node_cli_cmd_values_parse_net_chain(int *a_arg_index, int argc, ch if(l_chain_str) { if((*a_chain = dap_chain_net_get_chain_by_name(*a_net, l_chain_str)) == NULL) { // Can't find such chain dap_chain_node_cli_set_reply_text(a_str_reply, - "%s requires parameter 'chain' to be valid chain name in chain net %s", + "%s requires parameter '-chain' to be valid chain name in chain net %s", argv[0], l_net_str); return -103; } } + else { + dap_chain_node_cli_set_reply_text(a_str_reply, + "%s requires parameter '-chain'", argv[0]); + return -104; + } } return 0; @@ -1552,8 +1673,15 @@ int com_token_decl_sign(int argc, char ** argv, char ** a_str_reply) dap_chain_net_t * l_net = NULL; - if(dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, argc, argv, a_str_reply, &l_chain, &l_net) < 0) + dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, argc, argv, a_str_reply, &l_chain, &l_net); + if(!l_net) return -1; + else { + if(*a_str_reply) { + DAP_DELETE(*a_str_reply); + *a_str_reply = NULL; + } + } // Load certs lists dap_chain_cert_parse_str_list(l_certs_str, &l_certs, &l_certs_size); @@ -1564,7 +1692,13 @@ int com_token_decl_sign(int argc, char ** argv, char ** a_str_reply) } size_t l_certs_count = l_certs_size / sizeof(dap_chain_cert_t *); - char * l_gdb_group_mempool = dap_chain_net_get_gdb_group_mempool(l_chain); + char * l_gdb_group_mempool;// = dap_chain_net_get_gdb_group_mempool(l_chain); + if(l_gdb_group_mempool) { + l_gdb_group_mempool = dap_chain_net_get_gdb_group_mempool(l_chain); + } + else { + l_gdb_group_mempool = dap_chain_net_get_gdb_group_mempool_by_chain_type(l_net, CHAIN_TYPE_TOKEN); + } log_it(L_DEBUG, "Requested to sign token declaration %s in gdb://%s with certs %s", l_gdb_group_mempool, l_datum_hash_str, l_certs_str); @@ -1715,30 +1849,54 @@ int com_mempool_list(int argc, char ** argv, char ** a_str_reply) dap_chain_t * l_chain = NULL; dap_chain_net_t * l_net = NULL; - if(dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, argc, argv, a_str_reply, &l_chain, &l_net) != 0) { + dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, argc, argv, a_str_reply, &l_chain, &l_net); + if(!l_net) return -1; + else { + if(*a_str_reply) { + DAP_DELETE(*a_str_reply); + *a_str_reply = NULL; + } } - if(l_chain && l_net) { - char * l_gdb_group_mempool = dap_chain_net_get_gdb_group_mempool(l_chain); + if(l_net) { + char * l_gdb_group_mempool = NULL, * l_gdb_group_mempool_tmp; + if(l_chain){ + l_gdb_group_mempool = dap_chain_net_get_gdb_group_mempool(l_chain); + l_gdb_group_mempool_tmp = l_gdb_group_mempool; + } dap_string_t * l_str_tmp = dap_string_new(NULL); - size_t l_objs_size = 0; - - dap_global_db_obj_t * l_objs = dap_chain_global_db_gr_load(l_gdb_group_mempool, &l_objs_size); - dap_string_append_printf(l_str_tmp, "%s.%s: Found %u records :\n", l_net->pub.name, l_chain->name, l_objs_size); - for(size_t i = 0; i < l_objs_size; i++) { - dap_chain_datum_t * l_datum = (dap_chain_datum_t*) l_objs[i].value; - char buf[50]; - time_t l_ts_create = (time_t) l_datum->header.ts_create; - dap_string_append_printf(l_str_tmp, "%s: type_id=%s data_size=%u ts_create=%s", - l_objs[i].key, c_datum_type_str[l_datum->header.type_id], - l_datum->header.data_size, ctime_r(&l_ts_create, buf)); + for(dap_chain_type_t i = CHAIN_TYPE_FIRST+1; i < CHAIN_TYPE_LAST; i++) { + if(!l_gdb_group_mempool){ + l_chain = dap_chain_net_get_chain_by_chain_type(l_net, i); + if(!l_chain) + continue; + l_gdb_group_mempool_tmp = dap_chain_net_get_gdb_group_mempool(l_chain); + } + size_t l_objs_size = 0; + dap_global_db_obj_t * l_objs = dap_chain_global_db_gr_load(l_gdb_group_mempool_tmp, &l_objs_size); + if(l_objs_size>0) + dap_string_append_printf(l_str_tmp, "%s.%s: Found %u records :\n", l_net->pub.name, l_chain->name, + l_objs_size); + else + dap_string_append_printf(l_str_tmp, "%s.%s: Not found records\n", l_net->pub.name, l_chain->name); + for(size_t i = 0; i < l_objs_size; i++) { + dap_chain_datum_t * l_datum = (dap_chain_datum_t*) l_objs[i].value; + char buf[50]; + time_t l_ts_create = (time_t) l_datum->header.ts_create; + dap_string_append_printf(l_str_tmp, "%s: type_id=%s data_size=%u ts_create=%s", + l_objs[i].key, c_datum_type_str[l_datum->header.type_id], + l_datum->header.data_size, ctime_r(&l_ts_create, buf)); + } + // Clean up + dap_chain_global_db_objs_delete(l_objs, l_objs_size); + DAP_DELETE(l_gdb_group_mempool_tmp); + // only one time if group defined + if(l_gdb_group_mempool) + break; } - - // Clean up dap_chain_node_cli_set_reply_text(a_str_reply, l_str_tmp->str); - dap_chain_global_db_objs_delete(l_objs, l_objs_size); dap_string_free(l_str_tmp, false); return 0; @@ -1801,55 +1959,79 @@ int com_mempool_delete(int argc, char ** argv, char ** a_str_reply) int com_mempool_proc(int argc, char ** argv, char ** a_str_reply) { int arg_index = 1; - dap_chain_t * l_chain; + dap_chain_t * l_chain = NULL; dap_chain_net_t * l_net = NULL; - if(dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, argc, argv, a_str_reply, &l_chain, &l_net) < 0) + dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, argc, argv, a_str_reply, &l_chain, &l_net); + if(!l_net) return -1; - char * l_gdb_group_mempool = dap_chain_net_get_gdb_group_mempool(l_chain); - size_t l_objs_size = 0; - dap_global_db_obj_t * l_objs = dap_chain_global_db_gr_load(l_gdb_group_mempool, &l_objs_size); + else { + if(*a_str_reply) { + DAP_DELETE(*a_str_reply); + *a_str_reply = NULL; + } + } + char * l_gdb_group_mempool = NULL, *l_gdb_group_mempool_tmp; + if(l_chain){ + l_gdb_group_mempool = dap_chain_net_get_gdb_group_mempool(l_chain); + l_gdb_group_mempool_tmp = l_gdb_group_mempool; + } + dap_string_t * l_str_tmp = dap_string_new(NULL); - if(l_objs_size) { - dap_string_append_printf(l_str_tmp, "%s.%s: Found %u records :\n", l_net->pub.name, l_chain->name); - - size_t l_datums_size = l_objs_size; - dap_chain_datum_t ** l_datums = DAP_NEW_Z_SIZE(dap_chain_datum_t*, sizeof(dap_chain_datum_t*) * l_datums_size); - size_t l_objs_size_tmp = (l_objs_size > 15) ? min(l_objs_size, 10) : l_objs_size; - for(size_t i = 0; i < l_objs_size; i++) { - dap_chain_datum_t * l_datum = (dap_chain_datum_t*) l_objs[i].value; - l_datums[i] = l_datum; - if(i < l_objs_size_tmp) { - char buf[50]; - time_t l_ts_create = (time_t) l_datum->header.ts_create; - dap_string_append_printf(l_str_tmp, "0x%s: type_id=%s ts_create=%s data_size=%u\n", - l_objs[i].key, c_datum_type_str[l_datum->header.type_id], - ctime_r(&l_ts_create, buf), l_datum->header.data_size); - } + for(dap_chain_type_t i = CHAIN_TYPE_FIRST + 1; i < CHAIN_TYPE_LAST; i++) { + + if(!l_gdb_group_mempool) { + l_chain = dap_chain_net_get_chain_by_chain_type(l_net, i); + l_gdb_group_mempool_tmp = dap_chain_net_get_gdb_group_mempool(l_chain); } - if(l_objs_size > 15) { - dap_string_append_printf(l_str_tmp, "...\n"); - } - size_t l_objs_processed = l_chain->callback_datums_pool_proc(l_chain, l_datums, l_datums_size); - // Delete processed objects - size_t l_objs_processed_tmp = (l_objs_processed > 15) ? min(l_objs_processed, 10) : l_objs_processed; - for(size_t i = 0; i < l_objs_processed; i++) { - dap_chain_global_db_gr_del(l_objs[i].key, l_gdb_group_mempool); - if(i < l_objs_processed_tmp) { - dap_string_append_printf(l_str_tmp, "New event created, removed datum 0x%s from mempool \n", - l_objs[i].key); + size_t l_objs_size = 0; + dap_global_db_obj_t * l_objs = dap_chain_global_db_gr_load(l_gdb_group_mempool_tmp, &l_objs_size); + if(l_objs_size) { + dap_string_append_printf(l_str_tmp, "%s.%s: Found %u records :\n", l_net->pub.name, l_chain->name, + l_objs_size); + size_t l_datums_size = l_objs_size; + dap_chain_datum_t ** l_datums = DAP_NEW_Z_SIZE(dap_chain_datum_t*, + sizeof(dap_chain_datum_t*) * l_datums_size); + size_t l_objs_size_tmp = (l_objs_size > 15) ? min(l_objs_size, 10) : l_objs_size; + for(size_t i = 0; i < l_objs_size; i++) { + dap_chain_datum_t * l_datum = (dap_chain_datum_t*) l_objs[i].value; + l_datums[i] = l_datum; + if(i < l_objs_size_tmp) { + char buf[50]; + time_t l_ts_create = (time_t) l_datum->header.ts_create; + dap_string_append_printf(l_str_tmp, "0x%s: type_id=%s ts_create=%s data_size=%u\n", + l_objs[i].key, c_datum_type_str[l_datum->header.type_id], + ctime_r(&l_ts_create, buf), l_datum->header.data_size); + } + } + if(l_objs_size > 15) { + dap_string_append_printf(l_str_tmp, "...\n"); } + size_t l_objs_processed = l_chain->callback_datums_pool_proc(l_chain, l_datums, l_datums_size); + // Delete processed objects + size_t l_objs_processed_tmp = (l_objs_processed > 15) ? min(l_objs_processed, 10) : l_objs_processed; + for(size_t i = 0; i < l_objs_processed; i++) { + dap_chain_global_db_gr_del(l_objs[i].key, l_gdb_group_mempool); + if(i < l_objs_processed_tmp) { + dap_string_append_printf(l_str_tmp, "New event created, removed datum 0x%s from mempool \n", + l_objs[i].key); + } + } + if(l_objs_processed > 15) { + dap_string_append_printf(l_str_tmp, "...\n"); + } + dap_chain_global_db_objs_delete(l_objs, l_objs_size); } - if(l_objs_processed > 15) { - dap_string_append_printf(l_str_tmp, "...\n"); + else { + dap_string_append_printf(l_str_tmp, "%s.%s: No records in mempool\n", l_net->pub.name, l_chain->name); } - dap_chain_global_db_objs_delete(l_objs, l_objs_size); - - dap_chain_node_cli_set_reply_text(a_str_reply, l_str_tmp->str); - dap_string_free(l_str_tmp, false); - } else { - dap_chain_node_cli_set_reply_text(a_str_reply, "%s.^s: No records in mempool", l_net->pub.name, l_chain->name); + DAP_DELETE(l_gdb_group_mempool); + // only one time if group defined + if(l_gdb_group_mempool) + break; } + dap_chain_node_cli_set_reply_text(a_str_reply, l_str_tmp->str); + dap_string_free(l_str_tmp, true); return 0; } @@ -1860,10 +2042,9 @@ int com_mempool_proc(int argc, char ** argv, char ** a_str_reply) * @param str_reply * @return */ -int com_token_decl(int argc, char ** argv, char ** str_reply) +int com_token_decl(int argc, char ** argv, char ** a_str_reply) { int arg_index = 1; - char *str_reply_tmp = NULL; const char * l_ticker = NULL; const char * l_total_supply_str = NULL; @@ -1880,11 +2061,18 @@ int com_token_decl(int argc, char ** argv, char ** str_reply) dap_chain_cert_t ** l_certs = NULL; size_t l_certs_size = 0; - dap_chain_t * l_chain; + dap_chain_t * l_chain = NULL; dap_chain_net_t * l_net = NULL; - if(dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, argc, argv, str_reply, &l_chain, &l_net) < 0) + dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, argc, argv, a_str_reply, &l_chain, &l_net); + if(!l_net) return -1; + else { + if(*a_str_reply) { + DAP_DELETE(*a_str_reply); + *a_str_reply = NULL; + } + } // Total supply value dap_chain_node_cli_find_option_val(argv, arg_index, argc, "total_supply", &l_total_supply_str); @@ -1902,12 +2090,12 @@ int com_token_decl(int argc, char ** argv, char ** str_reply) dap_chain_node_cli_find_option_val(argv, arg_index, argc, "signs_emission", &l_signs_emission_str); if(!l_total_supply_str) { - dap_chain_node_cli_set_reply_text(str_reply, "token_create requires parameter 'total_supply'"); + dap_chain_node_cli_set_reply_text(a_str_reply, "token_create requires parameter 'total_supply'"); return -11; } else { char * l_tmp = NULL; if((l_total_supply = strtoull(l_total_supply_str, &l_tmp, 10)) == 0) { - dap_chain_node_cli_set_reply_text(str_reply, + dap_chain_node_cli_set_reply_text(a_str_reply, "token_create requires parameter 'total_supply' to be unsigned integer value that fits in 8 bytes"); return -2; } @@ -1915,12 +2103,12 @@ int com_token_decl(int argc, char ** argv, char ** str_reply) // Signs emission if(!l_signs_emission_str) { - dap_chain_node_cli_set_reply_text(str_reply, "token_create requires parameter 'signs_emission'"); + dap_chain_node_cli_set_reply_text(a_str_reply, "token_create requires parameter 'signs_emission'"); return -3; } else { char * l_tmp = NULL; if((l_signs_emission = (uint16_t) strtol(l_signs_emission_str, &l_tmp, 10)) == 0) { - dap_chain_node_cli_set_reply_text(str_reply, + dap_chain_node_cli_set_reply_text(a_str_reply, "token_create requires parameter 'signs_emission' to be unsigned integer value that fits in 2 bytes"); return -4; } @@ -1928,12 +2116,12 @@ int com_token_decl(int argc, char ** argv, char ** str_reply) // Signs total if(!l_signs_total_str) { - dap_chain_node_cli_set_reply_text(str_reply, "token_create requires parameter 'signs_total'"); + dap_chain_node_cli_set_reply_text(a_str_reply, "token_create requires parameter 'signs_total'"); return -31; } else { char * l_tmp = NULL; if((l_signs_total = (uint16_t) strtol(l_signs_total_str, &l_tmp, 10)) == 0) { - dap_chain_node_cli_set_reply_text(str_reply, + dap_chain_node_cli_set_reply_text(a_str_reply, "token_create requires parameter 'signs_total' to be unsigned integer value that fits in 2 bytes"); return -41; } @@ -1941,20 +2129,20 @@ int com_token_decl(int argc, char ** argv, char ** str_reply) // Check for ticker if(!l_ticker) { - dap_chain_node_cli_set_reply_text(str_reply, "token_emit requires parameter 'token'"); + dap_chain_node_cli_set_reply_text(a_str_reply, "token_emit requires parameter 'token'"); return -5; } // Check certs list if(!l_certs_str) { - dap_chain_node_cli_set_reply_text(str_reply, "token_emit requires parameter 'certs'"); + dap_chain_node_cli_set_reply_text(a_str_reply, "token_emit requires parameter 'certs'"); return -6; } // Load certs lists dap_chain_cert_parse_str_list(l_certs_str, &l_certs, &l_certs_size); if(!l_certs_size) { - dap_chain_node_cli_set_reply_text(str_reply, + dap_chain_node_cli_set_reply_text(a_str_reply, "token_create command requres at least one valid certificate to sign the basic transaction of emission"); return -7; } @@ -1995,18 +2183,23 @@ int com_token_decl(int argc, char ** argv, char ** str_reply) char * l_key_str = dap_chain_hash_fast_to_str_new(&l_key_hash); // Add datum to mempool with datum_token hash as a key - char * l_gdb_group_mempool = dap_chain_net_get_gdb_group_mempool(l_chain); + char * l_gdb_group_mempool; + if(l_chain) { + l_gdb_group_mempool = dap_chain_net_get_gdb_group_mempool(l_chain); + } + else { + l_gdb_group_mempool = dap_chain_net_get_gdb_group_mempool_by_chain_type(l_net, CHAIN_TYPE_TOKEN); + + } if(dap_chain_global_db_gr_set(l_key_str, (uint8_t *) l_datum, l_datum_size, l_gdb_group_mempool)) { - dap_chain_node_cli_set_reply_text(str_reply, "%s\ndatum %s with token %s is placed in datum pool ", - str_reply_tmp, l_key_str, l_ticker); + dap_chain_node_cli_set_reply_text(a_str_reply, "datum %s with token %s is placed in datum pool ", l_key_str, l_ticker); DAP_DELETE(l_datum); DAP_DELETE(l_datum_token); DAP_DELETE(l_gdb_group_mempool); return 0; } else { - dap_chain_node_cli_set_reply_text(str_reply, "%s\ndatum tx %s is not placed in datum pool ", str_reply_tmp, - l_key_str); + dap_chain_node_cli_set_reply_text(a_str_reply, "datum tx %s is not placed in datum pool ", l_key_str); DAP_DELETE(l_datum); DAP_DELETE(l_datum_token); DAP_DELETE(l_gdb_group_mempool); @@ -2103,11 +2296,13 @@ int com_token_emit(int argc, char ** argv, char ** str_reply) // Select chain network if(!l_net_str) { dap_chain_node_cli_set_reply_text(str_reply, "token_create requires parameter 'net'"); + DAP_DELETE(l_addr); return -42; } else { if((l_net = dap_chain_net_by_name(l_net_str)) == NULL) { // Can't find such network dap_chain_node_cli_set_reply_text(str_reply, "token_create requires parameter '-net' to be valid chain network name"); + DAP_DELETE(l_addr); return -43; } } @@ -2116,34 +2311,51 @@ int com_token_emit(int argc, char ** argv, char ** str_reply) dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-chain_base_tx", &l_chain_base_tx_str); // Select chain emission - if(!l_chain_emission_str) { + /*if(!l_chain_emission_str) { dap_chain_node_cli_set_reply_text(str_reply, "token_create requires parameter '-chain_emission'"); return -44; - } else { + } */ + if(l_chain_emission_str) { if((l_chain_emission = dap_chain_net_get_chain_by_name(l_net, l_chain_emission_str)) == NULL) { // Can't find such chain dap_chain_node_cli_set_reply_text(str_reply, "token_create requires parameter 'chain_emission' to be valid chain name in chain net %s", l_net_str); + DAP_DELETE(l_addr); return -45; } } // Select chain emission - if(!l_chain_base_tx_str) { + /*if(!l_chain_base_tx_str) { dap_chain_node_cli_set_reply_text(str_reply, "token_create requires parameter 'chain_base_tx'"); return -46; - } else { + }*/ + if(l_chain_base_tx_str) { if((l_chain_base_tx = dap_chain_net_get_chain_by_name(l_net, l_chain_base_tx_str)) == NULL) { // Can't find such chain dap_chain_node_cli_set_reply_text(str_reply, "token_create requires parameter 'chain_emission' to be valid chain name in chain net %s", l_net_str); + DAP_DELETE(l_addr); return -47; } } - // Get mempool group for this chain - char * l_gdb_group_mempool_emission = dap_chain_net_get_gdb_group_mempool(l_chain_emission); - char * l_gdb_group_mempool_base_tx = dap_chain_net_get_gdb_group_mempool(l_chain_base_tx); + // Get groups for the chains + char * l_gdb_group_mempool_emission, * l_gdb_group_mempool_base_tx; + if(l_chain_emission) { + l_gdb_group_mempool_emission = dap_chain_net_get_gdb_group_mempool(l_chain_emission); + } + else { + l_gdb_group_mempool_emission = dap_chain_net_get_gdb_group_mempool_by_chain_type(l_net, CHAIN_TYPE_EMISSION); + } + if(l_chain_base_tx) { + l_gdb_group_mempool_base_tx = dap_chain_net_get_gdb_group_mempool(l_chain_base_tx); + } + else { + l_gdb_group_mempool_base_tx = dap_chain_net_get_gdb_group_mempool_by_chain_type(l_net, CHAIN_TYPE_TX); + } + //char * l_gdb_group_mempool_emission = dap_chain_net_get_gdb_group_mempool(l_chain_emission); + //char * l_gdb_group_mempool_base_tx = dap_chain_net_get_gdb_group_mempool(l_chain_base_tx); // Create emission datum // then create datum in memory @@ -2192,6 +2404,7 @@ int com_token_emit(int argc, char ** argv, char ** str_reply) return -1; } DAP_DELETE(l_key_str); + DAP_DELETE(l_datum_emission); // create first transaction (with tx_token) dap_chain_datum_tx_t *l_tx = DAP_NEW_Z_SIZE(dap_chain_datum_tx_t, sizeof(dap_chain_datum_tx_t)); @@ -2211,6 +2424,7 @@ int com_token_emit(int argc, char ** argv, char ** str_reply) if(dap_chain_datum_tx_add_sign_item(&l_tx, l_certs[i]->enc_key) < 0) { dap_chain_node_cli_set_reply_text(str_reply, "No private key for certificate=%s", l_certs[i]->name); + DAP_DELETE(l_addr); return -3; } } @@ -2247,7 +2461,8 @@ int com_token_emit(int argc, char ** argv, char ** str_reply) } DAP_DELETE(str_reply_tmp); DAP_DELETE(l_key_str); - + DAP_DELETE(l_datum_tx); + DAP_DELETE(l_addr); return 0; } @@ -2367,13 +2582,16 @@ int com_tx_create(int argc, char ** argv, char **str_reply) return -1; } - if(!l_chain_name) { +/* if(!l_chain_name) { dap_chain_node_cli_set_reply_text(str_reply, "tx_create requires parameter '-chain'"); return -1; - } + }*/ dap_chain_t * l_chain = dap_chain_net_get_chain_by_name(l_net, l_chain_name); if ( !l_chain ){ - dap_chain_node_cli_set_reply_text(str_reply, "not found chain name '%s'", l_chain_name); + l_chain = dap_chain_net_get_chain_by_chain_type(l_net, CHAIN_TYPE_TX); + } + if ( !l_chain ){ + dap_chain_node_cli_set_reply_text(str_reply, "not found chain name '%s', try use parameter '-chain'", l_chain_name); return -1; } diff --git a/dap_chain_node_cli_cmd_tx.c b/dap_chain_node_cli_cmd_tx.c index dc4c118103dec591e2017e6affeda3ccd5f7f7ba..dee80f84b21cc52350cbc3da3fd1bbdbafe2e193 100644 --- a/dap_chain_node_cli_cmd_tx.c +++ b/dap_chain_node_cli_cmd_tx.c @@ -51,7 +51,7 @@ typedef struct dap_tx_data { UT_hash_handle hh; } dap_tx_data_t; -static char* dap_db_new_history_timestamp() +/*static char* dap_db_new_history_timestamp() { static pthread_mutex_t s_mutex = PTHREAD_MUTEX_INITIALIZER; // get unique key @@ -68,7 +68,7 @@ static char* dap_db_new_history_timestamp() char *l_str = dap_strdup_printf("%lld_%lld", (uint64_t) l_cur_time, s_suffix); pthread_mutex_unlock(&s_mutex); return l_str; -} +}*/ // for dap_db_history_tx & dap_db_history_addr() static dap_chain_datum_t* get_prev_tx(dap_tx_data_t *a_tx_data) @@ -134,7 +134,6 @@ char* dap_db_history_tx(dap_chain_hash_fast_t* a_tx_hash, dap_chain_t * a_chain) // save token name if(l_list_tx_token) { dap_chain_tx_token_t *tk = l_list_tx_token->data; - int d = sizeof(l_tx_data->token_ticker); memcpy(l_tx_data->token_ticker, tk->header.ticker, sizeof(l_tx_data->token_ticker)); } // take token from prev out item @@ -187,14 +186,11 @@ char* dap_db_history_tx(dap_chain_hash_fast_t* a_tx_hash, dap_chain_t * a_chain) // found a_tx_hash now // transaction time - char *l_time_str = NULL; if(l_tx->header.ts_created > 0) { time_t rawtime = (time_t) l_tx->header.ts_created; - struct tm * timeinfo; - timeinfo = localtime(&rawtime); - if(timeinfo) { - dap_string_append_printf(l_str_out, " %s", asctime(timeinfo)); - } + struct tm l_timeinfo = {0}; + localtime_r(&rawtime, &l_timeinfo); + dap_string_append_printf(l_str_out, " %s", asctime(&l_timeinfo)); } // find all OUT items in transaction @@ -301,7 +297,6 @@ char* dap_db_history_addr(dap_chain_addr_t * a_addr, dap_chain_t * a_chain) { dap_string_t *l_str_out = dap_string_new(NULL); - bool l_tx_hash_found = false; dap_tx_data_t *l_tx_data_hash = NULL; // load transactions dap_chain_atom_iter_t *l_atom_iter = a_chain->callback_atom_iter_create(a_chain); @@ -309,15 +304,15 @@ char* dap_db_history_addr(dap_chain_addr_t * a_addr, dap_chain_t * a_chain) size_t l_atom_size = a_chain->callback_atom_get_size(l_atom); while(l_atom && l_atom_size) { - dap_chain_datum_t *l_datum = (dap_chain_datum_t*) l_atom; - if(!l_datum && l_datum->header.type_id != DAP_CHAIN_DATUM_TX) { + dap_chain_datum_t *l_datum = a_chain->callback_atom_get_datum ? a_chain->callback_atom_get_datum(l_atom) : (dap_chain_datum_t*)l_atom; + if(!l_datum || l_datum->header.type_id != DAP_CHAIN_DATUM_TX) { // go to next transaction l_atom = a_chain->callback_atom_iter_get_next(l_atom_iter); l_atom_size = a_chain->callback_atom_get_size(l_atom); continue; } - dap_tx_data_t *l_tx_data = NULL; + dap_tx_data_t *l_tx_data = NULL; // transaction dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*) l_datum->data; dap_list_t *l_records_out = NULL; @@ -360,7 +355,6 @@ char* dap_db_history_addr(dap_chain_addr_t * a_addr, dap_chain_t * a_chain) // save token name if(l_tx_data && l_list_tx_token) { dap_chain_tx_token_t *tk = l_list_tx_token->data; - int d = sizeof(l_tx_data->token_ticker); memcpy(l_tx_data->token_ticker, tk->header.ticker, sizeof(l_tx_data->token_ticker)); } HASH_ADD(hh, l_tx_data_hash, tx_hash, sizeof(dap_chain_hash_fast_t), l_tx_data);