diff --git a/modules/net/dap_chain_node_cli.c b/modules/net/dap_chain_node_cli.c index 7cddc19615b750b4c12ddbcf55a1dcbeff259bf9..d03b7df259f7060721ef3f7a5e7536640ba9ed11 100644 --- a/modules/net/dap_chain_node_cli.c +++ b/modules/net/dap_chain_node_cli.c @@ -269,7 +269,9 @@ int dap_chain_node_cli_init(dap_config_t * g_config) "mempool dump -net <net_name> -chain <chain_name> -datum <datum_hash>\n" "\tOutput information about datum in mempool\n" "mempool add_ca -net <net_name> [-chain <chain_name>] -ca_name <priv_cert_name>\n" - "\tAdd pubic certificate into the mempool to prepare its way to chains\n"); + "\tAdd pubic certificate into the mempool to prepare its way to chains\n" + "mempool count -net <net_name> [-chain <chain_name>]\n" + "\tDisplays the number of elements in the mempool of a given network."); dap_cli_cmd_t *l_cmd_mempool = dap_cli_server_cmd_find("mempool"); dap_cli_server_alias_add("mempool_list", "list", l_cmd_mempool); dap_cli_server_alias_add("mempool_check", "check", l_cmd_mempool); diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c index 6367e274c69f990b2e948d0cc94630c47a73d995..c410055d022a660aba2719718ea12ee53f93a873 100644 --- a/modules/net/dap_chain_node_cli_cmd.c +++ b/modules/net/dap_chain_node_cli_cmd.c @@ -2744,6 +2744,13 @@ void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a dap_string_append_printf(a_str_tmp, "Cannot convert string '%s' to binary address.\n", a_add); return; } + if (l_wallet_addr && a_fast) { + dap_string_append_printf(a_str_tmp, "In fast mode, it is impossible to count the number of " + "transactions and emissions for a specific address. The -fast and -addr " + "options are mutually exclusive.\n"); + DAP_DELETE(l_wallet_addr); + return; + } dap_chain_mempool_filter(a_chain, &l_removed); dap_string_append_printf(a_str_tmp, "Removed %i records from the %s chain mempool in %s network. \n\n", l_removed, a_chain->name, a_net->pub.name); @@ -2767,96 +2774,131 @@ void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a char buff_time[50]; dap_time_to_str_rfc822(buff_time, 50, l_datum->header.ts_create); dap_string_append_printf(a_str_tmp, "%s hash %s %s\n", l_datum_type, l_objs[i].key, buff_time); - bool datum_is_accepted_addr = false; - switch (l_datum->header.type_id) { - case DAP_CHAIN_DATUM_TX: { - dap_chain_addr_t l_addr_from; - dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *) l_datum->data; - const char *l_main_token = s_tx_get_main_ticker(l_tx, a_net, NULL); - dap_list_t *l_list_sig_item = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_SIG, NULL); - if (!l_list_sig_item) { - dap_string_append_printf(a_str_tmp, - "\tAn item with a type TX_ITEM_TYPE_SIG for the transaction " - "was not found, the transaction may be corrupted.\n"); - break; - } - dap_chain_tx_sig_t *l_sig = l_list_sig_item->data; - dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig(l_sig); - dap_chain_addr_fill_from_sign(&l_addr_from, l_sign, a_net->pub.id); - if (l_wallet_addr && dap_chain_addr_compare(l_wallet_addr, &l_addr_from)) { - datum_is_accepted_addr = true; - } - dap_list_free(l_list_sig_item); - char *l_addr_from_str = dap_chain_addr_to_str(&l_addr_from); - dap_string_append_printf(a_str_tmp, "\tFrom: %s\n", l_addr_from_str); - DAP_DELETE(l_addr_from_str); - dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_ALL, NULL); - for (dap_list_t *it = l_list_out_items; it; it = it->next) { - dap_chain_addr_t *l_dist_addr = NULL; - uint256_t l_value = uint256_0; - const char *l_dist_token = NULL; - uint8_t l_type = *(uint8_t *) it->data; - switch (l_type) { - case TX_ITEM_TYPE_OUT: { - l_value = ((dap_chain_tx_out_t *) it->data)->header.value; - l_dist_token = l_main_token; - l_dist_addr = &((dap_chain_tx_out_t *) it->data)->addr; - } - break; - case TX_ITEM_TYPE_OUT_EXT: { - l_value = ((dap_chain_tx_out_ext_t *) it->data)->header.value; - l_dist_token = ((dap_chain_tx_out_ext_t *) it->data)->token; - l_dist_addr = &((dap_chain_tx_out_ext_t *) it->data)->addr; - } - break; - case TX_ITEM_TYPE_OUT_COND: { - l_value = ((dap_chain_tx_out_cond_t *) it->data)->header.value; - if (((dap_chain_tx_out_cond_t *) it->data)->header.subtype == - DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE) { - l_dist_token = a_net->pub.native_ticker; + if (!a_fast) { + bool datum_is_accepted_addr = false; + switch (l_datum->header.type_id) { + case DAP_CHAIN_DATUM_TX: { + dap_chain_addr_t l_addr_from; + dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *) l_datum->data; + const char *l_main_token = s_tx_get_main_ticker(l_tx, a_net, NULL); + dap_list_t *l_list_sig_item = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_SIG, NULL); + if (!l_list_sig_item) { + dap_string_append_printf(a_str_tmp, + "\tAn item with a type TX_ITEM_TYPE_SIG for the transaction " + "was not found, the transaction may be corrupted.\n"); + break; + } + dap_chain_tx_sig_t *l_sig = l_list_sig_item->data; + dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig(l_sig); + dap_chain_addr_fill_from_sign(&l_addr_from, l_sign, a_net->pub.id); + if (l_wallet_addr && dap_chain_addr_compare(l_wallet_addr, &l_addr_from)) { + datum_is_accepted_addr = true; + } + dap_list_free(l_list_sig_item); + char *l_addr_from_str = dap_chain_addr_to_str(&l_addr_from); + dap_list_t *l_list_in_reward = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_IN_REWARD, NULL); + if (l_list_in_reward) { + dap_chain_tx_in_reward_t *l_in_reward = (dap_chain_tx_in_reward_t*)l_list_in_reward->data; + char *l_block_hash = dap_chain_hash_fast_to_str_new(&l_in_reward->block_hash); + dap_string_append_printf(a_str_tmp, "\tForm block reward: %s\n", l_block_hash); + DAP_DELETE(l_block_hash); + } else { + dap_string_append_printf(a_str_tmp, "\tFrom: %s\n", l_addr_from_str); + } + dap_list_free(l_list_in_reward); + DAP_DELETE(l_addr_from_str); + dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_ALL, NULL); + for (dap_list_t *it = l_list_out_items; it; it = it->next) { + dap_chain_addr_t *l_dist_addr = NULL; + uint256_t l_value = uint256_0; + const char *l_dist_token = NULL; + uint8_t l_type = *(uint8_t *) it->data; + const char *l_type_out_str = "To"; + switch (l_type) { + case TX_ITEM_TYPE_OUT: { + l_value = ((dap_chain_tx_out_t *) it->data)->header.value; + l_dist_token = l_main_token; + l_dist_addr = &((dap_chain_tx_out_t *) it->data)->addr; + } + break; + case TX_ITEM_TYPE_OUT_EXT: { + l_value = ((dap_chain_tx_out_ext_t *) it->data)->header.value; + l_dist_token = ((dap_chain_tx_out_ext_t *) it->data)->token; + l_dist_addr = &((dap_chain_tx_out_ext_t *) it->data)->addr; + } + break; + case TX_ITEM_TYPE_OUT_COND: { + dap_chain_tx_out_cond_t *l_out_cond = (dap_chain_tx_out_cond_t*)it->data; + l_value = ((dap_chain_tx_out_cond_t *) it->data)->header.value; + switch (l_out_cond->header.subtype) { + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE: { + l_dist_token = a_net->pub.native_ticker; + l_type_out_str = "Fee"; + } break; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK: { + l_dist_token = l_main_token; + l_dist_addr = NULL; + l_type_out_str = "Stake lock"; + } break; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE: { + l_dist_token = l_main_token; + l_type_out_str = "xchange"; + } break; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE: { + l_dist_token = l_main_token; + l_type_out_str = "Stake pos delegate"; + } break; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY: { + l_dist_token = l_main_token; + l_type_out_str = "Pay"; + } break; + default: + break; + } } + break; + default: + break; } - break; - default: - break; - } - char *l_value_str = dap_chain_balance_print(l_value); - char *l_value_coins_str = dap_chain_balance_to_coins(l_value); - char *l_addr_str = dap_chain_addr_to_str(l_dist_addr); - if (l_dist_addr) { - if (!datum_is_accepted_addr && l_wallet_addr) { - datum_is_accepted_addr = dap_chain_addr_compare(l_wallet_addr, l_dist_addr); + char *l_value_str = dap_chain_balance_print(l_value); + char *l_value_coins_str = dap_chain_balance_to_coins(l_value); + if (!l_dist_addr) { + dap_string_append_printf(a_str_tmp, "\t%s: %s (%s) %s\n", l_type_out_str, + l_value_coins_str, l_value_str, l_dist_token); + } else { + char *l_addr_str = dap_chain_addr_to_str(l_dist_addr); + if (!datum_is_accepted_addr && l_wallet_addr) { + datum_is_accepted_addr = dap_chain_addr_compare(l_wallet_addr, l_dist_addr); + } + dap_chain_addr_compare(&l_addr_from, l_dist_addr) ? + dap_string_append_printf(a_str_tmp, "\tСhange: %s (%s) %s\n", + l_value_coins_str, l_value_str, l_dist_token) : + dap_string_append_printf(a_str_tmp, "\tTo: %s (%s) %s %s\n", + l_value_coins_str, l_value_str, l_dist_token, l_addr_str); + DAP_DELETE(l_addr_str); } - dap_chain_addr_compare(&l_addr_from, l_dist_addr) ? - dap_string_append_printf(a_str_tmp, "\tСhange: %s (%s) %s\n", - l_value_coins_str, l_value_str, l_dist_token) : - dap_string_append_printf(a_str_tmp, "\tTo: %s (%s) %s %s\n", - l_value_coins_str, l_value_str, l_dist_token, l_addr_str); - } else { - dap_string_append_printf(a_str_tmp, "\tFee: %s (%s) %s\n", l_value_coins_str, l_value_str, - l_dist_token); + DAP_DELETE(l_value_str); + DAP_DELETE(l_value_coins_str); } - DAP_DELETE(l_value_str); - DAP_DELETE(l_value_coins_str); - DAP_DELETE(l_addr_str); + dap_list_free(l_list_out_items); + } + break; + case DAP_CHAIN_DATUM_TOKEN_EMISSION: { + size_t l_emi_size = 0; + dap_chain_datum_token_emission_t *l_emi = dap_chain_datum_emission_read(l_datum->data, + &l_emi_size); + if (l_wallet_addr && l_emi && dap_chain_addr_compare(l_wallet_addr, &l_emi->hdr.address)) + datum_is_accepted_addr = true; + DAP_DELETE(l_emi); + dap_chain_datum_dump(a_str_tmp, l_datum, a_hash_out_type, a_net->pub.id); } - dap_list_free(l_list_out_items); + break; + default: + dap_chain_datum_dump(a_str_tmp, l_datum, a_hash_out_type, a_net->pub.id); } - break; - case DAP_CHAIN_DATUM_TOKEN_EMISSION: { - size_t l_emi_size = 0; - dap_chain_datum_token_emission_t *l_emi = dap_chain_datum_emission_read(l_datum->data, &l_emi_size); - if (l_wallet_addr && l_emi && dap_chain_addr_compare(l_wallet_addr, &l_emi->hdr.address)) - datum_is_accepted_addr = true; - DAP_DELETE(l_emi); - dap_chain_datum_dump(a_str_tmp, l_datum, a_hash_out_type, a_net->pub.id); + if (datum_is_accepted_addr) { + l_objs_addr++; } - break; - default: - dap_chain_datum_dump(a_str_tmp, l_datum, a_hash_out_type, a_net->pub.id); - } - if (datum_is_accepted_addr) { - l_objs_addr++; } } if (l_wallet_addr) { @@ -4500,7 +4542,7 @@ int com_mempool(int a_argc, char **a_argv, char **a_str_reply){ dap_chain_net_t *l_net = NULL; dap_chain_t *l_chain = NULL; const char *l_addr_b58 = NULL; - enum _subcmd {SUBCMD_LIST, SUBCMD_PROC, SUBCMD_PROC_ALL, SUBCMD_DELETE, SUBCMD_ADD_CA, SUBCMD_CHECK, SUBCMD_DUMP}; + enum _subcmd {SUBCMD_LIST, SUBCMD_PROC, SUBCMD_PROC_ALL, SUBCMD_DELETE, SUBCMD_ADD_CA, SUBCMD_CHECK, SUBCMD_DUMP, SUBCMD_COUNT}; enum _subcmd l_cmd = 0; if (a_argv[1]) { char *lts = a_argv[1]; @@ -4518,6 +4560,8 @@ int com_mempool(int a_argc, char **a_argv, char **a_str_reply){ l_cmd = SUBCMD_DUMP; } else if (!dap_strcmp(lts, "check")) { l_cmd = SUBCMD_CHECK; + } else if (!dap_strcmp(lts, "count")) { + l_cmd = SUBCMD_COUNT; } else { dap_cli_server_cmd_set_reply_text(a_str_reply, "Invalid sub command specified. Ыub command %s " "is not supported.", lts); @@ -4525,6 +4569,9 @@ int com_mempool(int a_argc, char **a_argv, char **a_str_reply){ } } dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, a_argc, a_argv, a_str_reply, &l_chain, &l_net); + if (!l_net) { + return -2; + } const char *l_hash_out_type = "hex"; dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-H", &l_hash_out_type); const char *l_datum_hash_in = NULL; @@ -4600,6 +4647,31 @@ int com_mempool(int a_argc, char **a_argv, char **a_str_reply){ dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_str_ret->str); dap_string_free(l_str_ret, true); } break; + case SUBCMD_COUNT: { + char *l_mempool_group; + dap_string_t *l_str_ret = dap_string_new(NULL); + if (!l_chain) { + DL_FOREACH(l_net->pub.chains, l_chain) { + l_mempool_group = dap_chain_net_get_gdb_group_mempool_new(l_chain); + size_t l_objs_count = 0; + dap_global_db_obj_t *l_objs = dap_global_db_get_all_sync(l_mempool_group, &l_objs_count); + dap_global_db_objs_delete(l_objs, l_objs_count); + DAP_DELETE(l_mempool_group); + dap_string_append_printf(l_str_ret, "%zu records found in mempool %s.%s\n", l_objs_count, + l_net->pub.name, l_chain->name); + } + } else { + l_mempool_group = dap_chain_net_get_gdb_group_mempool_new(l_chain); + size_t l_objs_count = 0; + dap_global_db_obj_t *l_objs = dap_global_db_get_all_sync(l_mempool_group, &l_objs_count); + dap_global_db_objs_delete(l_objs, l_objs_count); + DAP_DELETE(l_mempool_group); + dap_string_append_printf(l_str_ret, "%zu records found in mempool %s.%s\n", l_objs_count, + l_net->pub.name, l_chain->name); + } + dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_str_ret->str); + dap_string_free(l_str_ret, true); + } break; } DAP_DEL_Z(l_datum_hash); return ret; diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c index fa3a133ba45b4c16b2b9143cc9d139cebe9a92bc..8730a1e141945223d210b60e72172f0ea7000cb3 100644 --- a/modules/type/blocks/dap_chain_cs_blocks.c +++ b/modules/type/blocks/dap_chain_cs_blocks.c @@ -181,6 +181,9 @@ int dap_chain_cs_blocks_init() " [{-cert <signing_cert_name> | -pkey_hash <signing_cert_pkey_hash>} [-unspent]]\n" "\t\t List blocks\n\n" + "block -net <net_name> -chain <chain_name> count\n" + "\t\t Show count block\n\n" + "Commission collect:\n" "block -net <net_name> -chain <chain_name> fee collect" " -cert <priv_cert_name> -addr <addr> -hashes <hashes_list> -fee <value>\n" @@ -516,6 +519,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply) SUBCMD_DROP, SUBCMD_REWARD, SUBCMD_AUTOCOLLECT, + SUBCMD_COUNT, } l_subcmd={0}; const char* l_subcmd_strs[]={ @@ -530,6 +534,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply) [SUBCMD_DROP]="drop", [SUBCMD_REWARD] = "reward", [SUBCMD_AUTOCOLLECT] = "autocollect", + [SUBCMD_COUNT] = "count", [SUBCMD_UNDEFINED]=NULL }; const size_t l_subcmd_str_count=sizeof(l_subcmd_strs)/sizeof(*l_subcmd_strs); @@ -898,6 +903,11 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply) dap_string_free(l_str_tmp, true); } break; + case SUBCMD_COUNT: { + dap_cli_server_cmd_set_reply_text(a_str_reply, "%zu blocks in %s.%s", PVT(l_blocks)->blocks_count, + l_net->pub.name, l_chain->name); + } break; + case SUBCMD_FEE: case SUBCMD_REWARD: { const char * l_fee_value_str = NULL; diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c index 11382d550ddca313c8b40b6c70edccf349701a91..3a71be2a2d1e53cc11450aead8951a5a540d06f2 100644 --- a/modules/type/dag/dap_chain_cs_dag.c +++ b/modules/type/dag/dap_chain_cs_dag.c @@ -166,6 +166,8 @@ int dap_chain_cs_dag_init() "\tDump event info\n\n" "dag event list -net <net_name> -chain <chain_name> -from {events | events_lasts | threshold | round.new | round.<Round id in hex>}\n\n" "\tShow event list \n\n" + "dag event count -net <net_name> -chain <chain_name>\n" + "\tShow count event \n\n" "dag round complete -net <net_name> -chain <chain_name> \n" "\tComplete the current new round, verify it and if everything is ok - publish new events in chain\n" "dag round find -net <net_name> -chain <chain_name> -datum <datum_hash> \n" @@ -1442,6 +1444,7 @@ static int s_cli_dag(int argc, char ** argv, char **a_str_reply) SUBCMD_EVENT_LIST, SUBCMD_EVENT_DUMP, SUBCMD_EVENT_SIGN, + SUBCMD_EVENT_COUNT, SUBCMD_UNDEFINED } l_event_subcmd={0}; @@ -1645,6 +1648,8 @@ static int s_cli_dag(int argc, char ** argv, char **a_str_reply) dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-event", &l_event_hash_str); dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-cert", &l_cert_str); l_event_subcmd = SUBCMD_EVENT_SIGN; + } else if (strcmp(l_event_cmd_str, "count") == 0) { + l_event_subcmd = SUBCMD_EVENT_COUNT; } else { l_event_subcmd = SUBCMD_UNDEFINED; } @@ -1973,6 +1978,23 @@ static int s_cli_dag(int argc, char ** argv, char **a_str_reply) } } break; + + case SUBCMD_EVENT_COUNT: { + dap_string_t *l_ret_str = dap_string_new(NULL); + dap_string_append_printf(l_ret_str, "%s.%s:\n", l_net->pub.name, l_chain->name); + const char * l_gdb_group_events = DAP_CHAIN_CS_DAG(l_chain)->gdb_group_events_round_new; + if (l_gdb_group_events) { + size_t l_objs_count = 0; + dap_global_db_obj_t *l_objs = dap_global_db_get_all_sync(l_gdb_group_events,&l_objs_count); + dap_string_append_printf(l_ret_str,"%zu in round.new\n", l_objs_count); + } + size_t l_event_count = HASH_COUNT(PVT(l_dag)->events); + size_t l_event_treshold_count = HASH_COUNT(PVT(l_dag)->events_treshold); + dap_string_append_printf(l_ret_str, "%zu atoms(s) in events\n%zu atom(s) in threshold", l_event_count, l_event_treshold_count); + dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_ret_str->str); + dap_string_free(l_ret_str, true); + } break; + case SUBCMD_EVENT_SIGN: { // Sign event command char * l_gdb_group_events = l_dag->gdb_group_events_round_new; size_t l_round_item_size = 0;