diff --git a/dap-sdk b/dap-sdk index 85437a317bb69fd091c08cb65349312f0e5d6eba..ac68909d903e1a95e3b5d2cf939ac212969aecce 160000 --- a/dap-sdk +++ b/dap-sdk @@ -1 +1 @@ -Subproject commit 85437a317bb69fd091c08cb65349312f0e5d6eba +Subproject commit ac68909d903e1a95e3b5d2cf939ac212969aecce diff --git a/modules/net/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c index 67b87f9b7c1efdd3f444fd2754ccadf197b7decb..c401211107ed5c95fad06dfc22fd8086f8a11602 100644 --- a/modules/net/dap_chain_ledger.c +++ b/modules/net/dap_chain_ledger.c @@ -1795,14 +1795,31 @@ int dap_ledger_token_load(dap_ledger_t *a_ledger, byte_t *a_token, size_t a_toke return dap_ledger_token_add(a_ledger, l_token, a_token_size); } -json_object *dap_ledger_threshold_info(dap_ledger_t *a_ledger) +json_object *dap_ledger_threshold_info(dap_ledger_t *a_ledger, size_t a_limit, size_t a_offset) { dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); dap_ledger_tx_item_t *l_tx_item, *l_tx_tmp; json_object* json_arr_out = json_object_new_array(); uint32_t l_counter = 0; pthread_rwlock_rdlock(&l_ledger_pvt->threshold_txs_rwlock); + size_t l_arr_start = 0; + if (a_offset > 1) { + l_arr_start = a_limit * a_offset; + } + size_t l_arr_end = HASH_COUNT(l_ledger_pvt->threshold_txs); + if (a_limit) { + l_arr_end = l_arr_start + a_limit; + if (l_arr_end > HASH_COUNT(l_ledger_pvt->threshold_txs)) { + l_arr_end = HASH_COUNT(l_ledger_pvt->threshold_txs); + } + } + size_t i_tmp = 0; HASH_ITER(hh, l_ledger_pvt->threshold_txs, l_tx_item, l_tx_tmp){ + if (i_tmp < l_arr_start || i_tmp > l_arr_end) { + i_tmp++; + continue; + } + i_tmp++; json_object* json_obj_tx = json_object_new_object(); if (!json_obj_tx) { return NULL; @@ -1848,7 +1865,7 @@ json_object *dap_ledger_threshold_info(dap_ledger_t *a_ledger) return json_arr_out; } -json_object *dap_ledger_threshold_hash_info(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *l_threshold_hash) +json_object *dap_ledger_threshold_hash_info(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *l_threshold_hash, size_t a_limit, size_t a_offset) { dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); dap_ledger_tx_item_t *l_tx_item, *l_tx_tmp; @@ -1857,9 +1874,26 @@ json_object *dap_ledger_threshold_hash_info(dap_ledger_t *a_ledger, dap_chain_ha if (!json_obj_tx) { return NULL; } + size_t l_arr_start = 0; + if (a_offset > 1) { + l_arr_start = a_limit * a_offset; + } + size_t l_arr_end = HASH_COUNT(l_ledger_pvt->threshold_txs); + if (a_limit) { + l_arr_end = l_arr_start + a_limit; + if (l_arr_end > HASH_COUNT(l_ledger_pvt->threshold_txs)) { + l_arr_end = HASH_COUNT(l_ledger_pvt->threshold_txs); + } + } + size_t i_tmp = 0; pthread_rwlock_rdlock(&l_ledger_pvt->threshold_txs_rwlock); HASH_ITER(hh, l_ledger_pvt->threshold_txs, l_tx_item, l_tx_tmp){ if (!memcmp(l_threshold_hash, &l_tx_item->tx_hash_fast, sizeof(dap_chain_hash_fast_t))){ + if (i_tmp < l_arr_start || i_tmp > l_arr_end) { + i_tmp++; + continue; + } + i_tmp++; char l_tx_hash_str[70]={0}; dap_chain_hash_fast_to_str(l_threshold_hash,l_tx_hash_str,sizeof(l_tx_hash_str)); json_object_object_add(json_obj_tx, "Hash was found in ledger tx threshold", json_object_new_string(l_tx_hash_str)); @@ -1874,6 +1908,11 @@ json_object *dap_ledger_threshold_hash_info(dap_ledger_t *a_ledger, dap_chain_ha dap_ledger_token_emission_item_t *l_emission_item, *l_emission_tmp; HASH_ITER(hh, l_ledger_pvt->threshold_emissions, l_emission_item, l_emission_tmp){ if (!memcmp(&l_emission_item->datum_token_emission_hash,l_threshold_hash, sizeof(dap_chain_hash_fast_t))){ + if (i_tmp < l_arr_start || i_tmp > l_arr_end) { + i_tmp++; + continue; + } + i_tmp++; char l_emission_hash_str[70]={0}; dap_chain_hash_fast_to_str(l_threshold_hash,l_emission_hash_str,sizeof(l_emission_hash_str)); json_object_object_add(json_obj_tx, "Hash was found in ledger emission threshold", json_object_new_string(l_emission_hash_str)); @@ -1888,14 +1927,31 @@ json_object *dap_ledger_threshold_hash_info(dap_ledger_t *a_ledger, dap_chain_ha return json_arr_out; } -json_object *dap_ledger_balance_info(dap_ledger_t *a_ledger) +json_object *dap_ledger_balance_info(dap_ledger_t *a_ledger, size_t a_limit, size_t a_offset) { dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); json_object * json_arr_out = json_object_new_array(); pthread_rwlock_rdlock(&l_ledger_pvt->balance_accounts_rwlock); uint32_t l_counter = 0; dap_ledger_wallet_balance_t *l_balance_item, *l_balance_tmp; + size_t l_arr_start = 0; + if (a_offset > 1) { + l_arr_start = a_limit * a_offset; + } + size_t l_arr_end = HASH_COUNT(l_ledger_pvt->balance_accounts); + if (a_limit) { + l_arr_end = l_arr_start + a_limit; + if (l_arr_end > HASH_COUNT(l_ledger_pvt->balance_accounts)) { + l_arr_end = HASH_COUNT(l_ledger_pvt->balance_accounts); + } + } + size_t i_tmp = 0; HASH_ITER(hh, l_ledger_pvt->balance_accounts, l_balance_item, l_balance_tmp) { + if (i_tmp < l_arr_start || i_tmp > l_arr_end) { + i_tmp++; + continue; + } + i_tmp++; json_object* json_obj_tx = json_object_new_object(); //log_it(L_DEBUG,"Ledger balance key %s, token_ticker: %s, balance: %s", l_balance_key, l_balance_item->token_ticker, // dap_chain_balance_print(l_balance_item->balance)); @@ -1985,13 +2041,30 @@ dap_list_t * dap_ledger_token_auth_pkeys_hashes(dap_ledger_t *a_ledger, const ch * @param a_ledger * @return */ -json_object *dap_ledger_token_info(dap_ledger_t *a_ledger) +json_object *dap_ledger_token_info(dap_ledger_t *a_ledger, size_t a_limit, size_t a_offset) { json_object * json_obj_datum; json_object * json_arr_out = json_object_new_array(); dap_ledger_token_item_t *l_token_item, *l_tmp_item; pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock); + size_t l_arr_start = 0; + if (a_offset > 1) { + l_arr_start = a_limit * a_offset; + } + size_t l_arr_end = HASH_COUNT(PVT(a_ledger)->tokens); + if (a_limit) { + l_arr_end = l_arr_start + a_limit; + if (l_arr_end > HASH_COUNT(PVT(a_ledger)->tokens)) { + l_arr_end = HASH_COUNT(PVT(a_ledger)->tokens); + } + } + size_t i_tmp = 0; HASH_ITER(hh, PVT(a_ledger)->tokens, l_token_item, l_tmp_item) { + if (i_tmp < l_arr_start || i_tmp > l_arr_end) { + i_tmp++; + continue; + } + i_tmp++; json_obj_datum = json_object_new_object(); const char *l_type_str; const char *l_flags_str = s_flag_str_from_code(l_token_item->datum_token->header_private_decl.flags); diff --git a/modules/net/dap_chain_node_cli.c b/modules/net/dap_chain_node_cli.c index 68f28e5447fba4bd6239ee62ab050257bc89c8e2..44f9ac413114db5a6a0c7d7531d76424f92932d7 100644 --- a/modules/net/dap_chain_node_cli.c +++ b/modules/net/dap_chain_node_cli.c @@ -256,7 +256,7 @@ int dap_chain_node_cli_init(dap_config_t * g_config) "-addr <addr> [-chain_emission <chain_name>] -net <net_name> -certs <cert list>\n"); dap_cli_server_cmd_add("mempool", com_mempool, "Command for working with mempool", - "mempool list -net <net_name> [-chain <chain_name>] [-addr <addr>] [-brief]\n" + "mempool list -net <net_name> [-chain <chain_name>] [-addr <addr>] [-brief] [-limit] [-offset]\n" "\tList mempool (entries or transaction) for (selected chain network or wallet)\n" "mempool check -net <net_name> [-chain <chain_name>] -datum <datum_hash>\n" "\tCheck mempool entrie for presence in selected chain network\n" @@ -302,14 +302,14 @@ int dap_chain_node_cli_init(dap_config_t * g_config) // Transaction history dap_cli_server_cmd_add("tx_history", com_tx_history, "Transaction history (for address or by hash)", - "tx_history {-addr <addr> | -w <wallet_name> | -tx <tx_hash>} [-net <net_name>] [-chain <chain_name>]\n" - "tx_history -all -net <net_name> [-chain <chain_name>]\n"); + "tx_history {-addr <addr> | -w <wallet_name> | -tx <tx_hash>} [-net <net_name>] [-chain <chain_name>] [-limit] [-offset]\n" + "tx_history -all -net <net_name> [-chain <chain_name>] [-limit] [-offset]\n"); // Ledger info dap_cli_server_cmd_add("ledger", com_ledger, "Ledger information", - "ledger list coins -net <net_name>\n" - "ledger list threshold [-hash <tx_treshold_hash>] -net <net_name>\n" - "ledger list balance -net <net_name>\n" + "ledger list coins -net <net_name> [-limit] [-offset]\n" + "ledger list threshold [-hash <tx_treshold_hash>] -net <net_name> [-limit] [-offset]\n" + "ledger list balance -net <net_name> [-limit] [-offset]\n" "ledger info -hash <tx_hash> -net <net_name> [-unspent]\n" "ledger tx -all -net <net_name> [-unspent]\n" "ledger tx {-addr <addr> | -w <wallet_name> | -tx <tx_hash>} -net <net_name>\n"); diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c index b7c8acd6c168edb8ceddef854bc1dc708089d5ca..bad1dc485109e2e7d2748ecf70bb4318110bd124 100644 --- a/modules/net/dap_chain_node_cli_cmd.c +++ b/modules/net/dap_chain_node_cli_cmd.c @@ -2609,7 +2609,8 @@ int com_token_decl_sign(int a_argc, char **a_argv, void **a_str_reply) * @param a_str_tmp * @param a_hash_out_type */ -void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a_chain, const char * a_add, json_object *a_json_obj, const char *a_hash_out_type, bool a_fast) { +void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a_chain, const char * a_add, + json_object *a_json_obj, const char *a_hash_out_type, bool a_fast, size_t a_limit, size_t a_offset) { dap_chain_addr_t *l_wallet_addr = dap_chain_addr_from_str(a_add); if (a_add && !l_wallet_addr) { dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_CMD_VALUE_PARSE_CONVERT_BASE58_TO_ADDR_WALLET, "Cannot convert " @@ -2650,7 +2651,8 @@ void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a size_t l_objs_addr = 0; dap_global_db_obj_t * l_objs = dap_global_db_get_all_sync(l_gdb_group_mempool, &l_objs_count); json_object *l_jobj_datums; - if (l_objs_count == 0) { + size_t l_offset = a_limit * a_offset; + if (l_objs_count == 0 || l_objs_count < l_offset) { l_jobj_datums = json_object_new_null(); } else { l_jobj_datums = json_object_new_array(); @@ -2659,138 +2661,123 @@ void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a dap_json_rpc_allocation_error; return; } - } - for(size_t i = 0; i < l_objs_count; i++) { - dap_chain_datum_t *l_datum = (dap_chain_datum_t *)l_objs[i].value; - if (!l_datum->header.data_size || (l_datum->header.data_size > l_objs[i].value_len)) { - log_it(L_ERROR, "Trash datum in GDB %s.%s, key: %s data_size:%u, value_len:%zu", - a_net->pub.name, a_chain->name, l_objs[i].key, l_datum->header.data_size, l_objs[i].value_len); - dap_global_db_del_sync(l_gdb_group_mempool, l_objs[i].key); - continue; - } - dap_time_t l_ts_create = (dap_time_t) l_datum->header.ts_create; - const char *l_datum_type = dap_chain_datum_type_id_to_str(l_datum->header.type_id); - dap_hash_fast_t l_datum_real_hash = {0}; - dap_hash_fast_t l_datum_hash_from_key = {0}; - dap_hash_fast(l_datum->data, l_datum->header.data_size, &l_datum_real_hash); - dap_chain_hash_fast_from_str(l_objs[i].key, &l_datum_hash_from_key); - char buff_time[50]; - dap_time_to_str_rfc822(buff_time, 50, l_datum->header.ts_create); - json_object *l_jobj_type = json_object_new_string(l_datum_type); - json_object *l_jobj_hash = json_object_new_string(l_objs[i].key); - json_object *l_jobj_ts_created = json_object_new_object(); - json_object *l_jobj_ts_created_time_stamp = json_object_new_uint64(l_ts_create); - json_object *l_jobj_ts_created_str = json_object_new_string(buff_time); - if (!l_jobj_type || !l_jobj_hash || !l_jobj_ts_created || !l_jobj_ts_created_str || !l_jobj_ts_created_time_stamp) { - json_object_put(l_jobj_type); - json_object_put(l_jobj_hash); - json_object_put(l_jobj_ts_created); - json_object_put(l_jobj_ts_created_time_stamp); - json_object_put(l_jobj_ts_created_str); - json_object_put(l_jobj_datums); - json_object_put(l_obj_chain); - dap_global_db_objs_delete(l_objs, l_objs_count); - dap_json_rpc_allocation_error; - return; - } - json_object_object_add(l_jobj_ts_created, "time_stamp", l_jobj_ts_created_time_stamp); - json_object_object_add(l_jobj_ts_created, "str", l_jobj_ts_created_str); - json_object *l_jobj_datum = json_object_new_object(); - if (!l_jobj_datum) { - json_object_put(l_jobj_type); - json_object_put(l_jobj_hash); - json_object_put(l_jobj_ts_created); - json_object_put(l_jobj_ts_created_time_stamp); - json_object_put(l_jobj_ts_created_str); - json_object_put(l_jobj_datums); - json_object_put(l_obj_chain); - dap_global_db_objs_delete(l_objs, l_objs_count); - dap_json_rpc_allocation_error; - return; - } - if (!dap_hash_fast_compare(&l_datum_real_hash, &l_datum_hash_from_key)){ - char *l_drh_str = dap_hash_fast_to_str_new(&l_datum_real_hash); - char *l_wgn = dap_strdup_printf("Key field in DB %s does not match datum's hash %s\n", - l_objs[i].key, l_drh_str); - DAP_DELETE(l_drh_str); - if (!l_wgn) { - dap_global_db_objs_delete(l_objs, l_objs_count); - json_object_put(l_jobj_datum); - json_object_put(l_obj_chain); + + size_t l_arr_start = 0; + if (l_offset) { + l_arr_start = l_offset; + json_object *l_jobj_offset = json_object_new_uint64(l_offset); + json_object_object_add(l_obj_chain, "offset", l_jobj_offset); + } + size_t l_arr_end = 0; + if (a_limit) { + l_arr_end = l_offset + a_limit; + if (l_arr_end > l_objs_count) + l_arr_end = l_objs_count; + json_object *l_jobj_limit = json_object_new_uint64(l_arr_end); + json_object_object_add(l_obj_chain, "limit", l_jobj_limit); + } + for (size_t i = l_arr_start; i < l_arr_end; i++) { + dap_chain_datum_t *l_datum = (dap_chain_datum_t *) l_objs[i].value; + if (!l_datum->header.data_size || (l_datum->header.data_size > l_objs[i].value_len)) { + log_it(L_ERROR, "Trash datum in GDB %s.%s, key: %s data_size:%u, value_len:%zu", + a_net->pub.name, a_chain->name, l_objs[i].key, l_datum->header.data_size, l_objs[i].value_len); + dap_global_db_del_sync(l_gdb_group_mempool, l_objs[i].key); + continue; + } + dap_time_t l_ts_create = (dap_time_t) l_datum->header.ts_create; + const char *l_datum_type = dap_chain_datum_type_id_to_str(l_datum->header.type_id); + dap_hash_fast_t l_datum_real_hash = {0}; + dap_hash_fast_t l_datum_hash_from_key = {0}; + dap_hash_fast(l_datum->data, l_datum->header.data_size, &l_datum_real_hash); + dap_chain_hash_fast_from_str(l_objs[i].key, &l_datum_hash_from_key); + char buff_time[50]; + dap_time_to_str_rfc822(buff_time, 50, l_datum->header.ts_create); + json_object *l_jobj_type = json_object_new_string(l_datum_type); + json_object *l_jobj_hash = json_object_new_string(l_objs[i].key); + json_object *l_jobj_ts_created = json_object_new_object(); + json_object *l_jobj_ts_created_time_stamp = json_object_new_uint64(l_ts_create); + json_object *l_jobj_ts_created_str = json_object_new_string(buff_time); + if (!l_jobj_type || !l_jobj_hash || !l_jobj_ts_created || !l_jobj_ts_created_str || + !l_jobj_ts_created_time_stamp) { json_object_put(l_jobj_type); json_object_put(l_jobj_hash); json_object_put(l_jobj_ts_created); + json_object_put(l_jobj_ts_created_time_stamp); + json_object_put(l_jobj_ts_created_str); json_object_put(l_jobj_datums); + json_object_put(l_obj_chain); + dap_global_db_objs_delete(l_objs, l_objs_count); dap_json_rpc_allocation_error; return; } - json_object *l_jobj_warning = json_object_new_string(l_wgn); - DAP_DELETE(l_wgn); - if (!l_jobj_warning) { - dap_global_db_objs_delete(l_objs, l_objs_count); - json_object_put(l_jobj_datum); - json_object_put(l_obj_chain); + json_object_object_add(l_jobj_ts_created, "time_stamp", l_jobj_ts_created_time_stamp); + json_object_object_add(l_jobj_ts_created, "str", l_jobj_ts_created_str); + json_object *l_jobj_datum = json_object_new_object(); + if (!l_jobj_datum) { json_object_put(l_jobj_type); json_object_put(l_jobj_hash); json_object_put(l_jobj_ts_created); + json_object_put(l_jobj_ts_created_time_stamp); + json_object_put(l_jobj_ts_created_str); json_object_put(l_jobj_datums); + json_object_put(l_obj_chain); + dap_global_db_objs_delete(l_objs, l_objs_count); dap_json_rpc_allocation_error; return; } - json_object_object_add(l_jobj_datum, "warning", l_jobj_warning); - json_object_array_add(l_jobj_datums, l_jobj_datum); - continue; - } - json_object_object_add(l_jobj_datum, "hash", l_jobj_hash); - json_object_object_add(l_jobj_datum, "type", l_jobj_type); - json_object_object_add(l_jobj_datum, "created", l_jobj_ts_created); - bool datum_is_accepted_addr = false; - if (!a_fast) { - 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; - - int l_ledger_rc = DAP_LEDGER_TX_CHECK_NULL_TX; - const char *l_main_ticker = dap_ledger_tx_get_main_ticker(a_net->pub.ledger, l_tx, &l_ledger_rc); - char * l_ledger_rc_str = dap_ledger_tx_check_err_str(l_ledger_rc); - - json_object *l_jobj_main_ticker = json_object_new_string(l_main_ticker ? l_main_ticker : "UNKNOWN"); - json_object *l_jobj_ledger_rc = json_object_new_string(l_ledger_rc_str); - - if (!l_jobj_main_ticker || !l_jobj_ledger_rc) { - json_object_put(l_jobj_datum); - json_object_put(l_jobj_datums); - json_object_put(l_obj_chain); - dap_global_db_objs_delete(l_objs, l_objs_count); - dap_json_rpc_allocation_error; - return; - } - - json_object_object_add(l_jobj_datum, "main_ticker", l_jobj_main_ticker); - json_object_object_add(l_jobj_datum, "ledger_rc", l_jobj_ledger_rc); - - dap_list_t *l_list_sig_item = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_SIG, NULL); - dap_list_t *l_list_in_ems = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_IN_EMS, NULL); - if (!l_list_sig_item) { - json_object *l_jobj_wgn = json_object_new_string("An item with a type TX_ITEM_TYPE_SIG for the " - "transaction was not found, the transaction may " - "be corrupted."); - json_object_object_add(l_jobj_datum, "warning", l_jobj_wgn); - 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); - 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) { - json_object *l_obj_in_reward_arary = json_object_new_array(); - if (!l_obj_in_reward_arary) { - dap_list_free(l_list_in_reward); + if (!dap_hash_fast_compare(&l_datum_real_hash, &l_datum_hash_from_key)) { + char *l_drh_str = dap_hash_fast_to_str_new(&l_datum_real_hash); + char *l_wgn = dap_strdup_printf("Key field in DB %s does not match datum's hash %s\n", + l_objs[i].key, l_drh_str); + DAP_DELETE(l_drh_str); + if (!l_wgn) { + dap_global_db_objs_delete(l_objs, l_objs_count); + json_object_put(l_jobj_datum); + json_object_put(l_obj_chain); + json_object_put(l_jobj_type); + json_object_put(l_jobj_hash); + json_object_put(l_jobj_ts_created); + json_object_put(l_jobj_datums); + dap_json_rpc_allocation_error; + return; + } + json_object *l_jobj_warning = json_object_new_string(l_wgn); + DAP_DELETE(l_wgn); + if (!l_jobj_warning) { + dap_global_db_objs_delete(l_objs, l_objs_count); + json_object_put(l_jobj_datum); + json_object_put(l_obj_chain); + json_object_put(l_jobj_type); + json_object_put(l_jobj_hash); + json_object_put(l_jobj_ts_created); + json_object_put(l_jobj_datums); + dap_json_rpc_allocation_error; + return; + } + json_object_object_add(l_jobj_datum, "warning", l_jobj_warning); + json_object_array_add(l_jobj_datums, l_jobj_datum); + continue; + } + json_object_object_add(l_jobj_datum, "hash", l_jobj_hash); + json_object_object_add(l_jobj_datum, "type", l_jobj_type); + json_object_object_add(l_jobj_datum, "created", l_jobj_ts_created); + bool datum_is_accepted_addr = false; + if (!a_fast) { + 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; + + int l_ledger_rc = DAP_LEDGER_TX_CHECK_NULL_TX; + const char *l_main_ticker = dap_ledger_tx_get_main_ticker(a_net->pub.ledger, l_tx, + &l_ledger_rc); + char *l_ledger_rc_str = dap_ledger_tx_check_err_str(l_ledger_rc); + + json_object *l_jobj_main_ticker = json_object_new_string( + l_main_ticker ? l_main_ticker : "UNKNOWN"); + json_object *l_jobj_ledger_rc = json_object_new_string(l_ledger_rc_str); + + if (!l_jobj_main_ticker || !l_jobj_ledger_rc) { json_object_put(l_jobj_datum); json_object_put(l_jobj_datums); json_object_put(l_obj_chain); @@ -2798,13 +2785,31 @@ void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a dap_json_rpc_allocation_error; return; } - for (dap_list_t *it = l_list_in_reward; it; it = it->next) { - dap_chain_tx_in_reward_t *l_in_reward = (dap_chain_tx_in_reward_t *) it->data; - char *l_block_hash = dap_chain_hash_fast_to_str_new(&l_in_reward->block_hash); - json_object *l_jobj_block_hash = json_object_new_string(l_block_hash); - if (!l_jobj_block_hash) { - DAP_DELETE(l_block_hash); - json_object_put(l_obj_in_reward_arary); + + json_object_object_add(l_jobj_datum, "main_ticker", l_jobj_main_ticker); + json_object_object_add(l_jobj_datum, "ledger_rc", l_jobj_ledger_rc); + + dap_list_t *l_list_sig_item = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_SIG, NULL); + dap_list_t *l_list_in_ems = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_IN_EMS, NULL); + if (!l_list_sig_item) { + json_object *l_jobj_wgn = json_object_new_string( + "An item with a type TX_ITEM_TYPE_SIG for the " + "transaction was not found, the transaction may " + "be corrupted."); + json_object_object_add(l_jobj_datum, "warning", l_jobj_wgn); + 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); + 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) { + json_object *l_obj_in_reward_arary = json_object_new_array(); + if (!l_obj_in_reward_arary) { dap_list_free(l_list_in_reward); json_object_put(l_jobj_datum); json_object_put(l_jobj_datums); @@ -2813,116 +2818,59 @@ void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a dap_json_rpc_allocation_error; return; } - json_object_array_add(l_obj_in_reward_arary, l_jobj_block_hash); - DAP_DELETE(l_block_hash); - } - } else { - json_object *l_jobj_addr_from = json_object_new_string(dap_chain_addr_to_str(&l_addr_from)); - if (!l_jobj_addr_from) { - json_object_put(l_jobj_datum); - json_object_put(l_jobj_datums); - json_object_put(l_obj_chain); - dap_global_db_objs_delete(l_objs, l_objs_count); - dap_json_rpc_allocation_error; - return; - } - json_object_object_add(l_jobj_datum, "from", l_jobj_addr_from); - } - dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_ALL, NULL); - json_object *l_jobj_to_list = json_object_new_array(); - json_object *l_jobj_change_list = json_object_new_array(); - json_object *l_jobj_to_from_emi = json_object_new_array(); - json_object *l_jobj_fee_list = json_object_new_array(); - json_object *l_jobj_stake_lock_list = json_object_new_array(); - json_object *l_jobj_xchange_list = json_object_new_array(); - json_object *l_jobj_stake_pos_delegate_list = json_object_new_array(); - json_object *l_jobj_pay_list = json_object_new_array(); - json_object *l_jobj_tx_vote = json_object_new_array(); - json_object *l_jobj_tx_voting = json_object_new_array(); - if (!l_jobj_to_list || !l_jobj_change_list || !l_jobj_fee_list || !l_jobj_stake_lock_list || - !l_jobj_xchange_list || !l_jobj_stake_pos_delegate_list || !l_jobj_pay_list) { - json_object_put(l_jobj_to_list); - json_object_put(l_jobj_change_list); - json_object_put(l_jobj_to_from_emi); - json_object_put(l_jobj_fee_list); - json_object_put(l_jobj_stake_lock_list); - json_object_put(l_jobj_xchange_list); - json_object_put(l_jobj_stake_pos_delegate_list); - json_object_put(l_jobj_pay_list); - json_object_put(l_jobj_tx_vote); - json_object_put(l_jobj_tx_voting); - json_object_put(l_jobj_datum); - json_object_put(l_jobj_datums); - json_object_put(l_obj_chain); - dap_global_db_objs_delete(l_objs, l_objs_count); - dap_json_rpc_allocation_error; - return; - } - enum { - OUT_COND_TYPE_UNKNOWN, - OUT_COND_TYPE_PAY, - OUT_COND_TYPE_FEE, - OUT_COND_TYPE_STAKE_LOCK, - OUT_COND_TYPE_XCHANGE, - OUT_COND_TYPE_POS_DELEGATE - }l_out_cond_subtype={0}; - dap_list_t *l_vote_list = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_VOTE, NULL); - dap_list_t *l_voting_list = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_VOTING, 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_ticker; - l_dist_addr = &((dap_chain_tx_out_t *) it->data)->addr; + for (dap_list_t *it = l_list_in_reward; it; it = it->next) { + dap_chain_tx_in_reward_t *l_in_reward = (dap_chain_tx_in_reward_t *) it->data; + char *l_block_hash = dap_chain_hash_fast_to_str_new(&l_in_reward->block_hash); + json_object *l_jobj_block_hash = json_object_new_string(l_block_hash); + if (!l_jobj_block_hash) { + DAP_DELETE(l_block_hash); + json_object_put(l_obj_in_reward_arary); + dap_list_free(l_list_in_reward); + json_object_put(l_jobj_datum); + json_object_put(l_jobj_datums); + json_object_put(l_obj_chain); + dap_global_db_objs_delete(l_objs, l_objs_count); + dap_json_rpc_allocation_error; + return; + } + json_object_array_add(l_obj_in_reward_arary, l_jobj_block_hash); + DAP_DELETE(l_block_hash); } - 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; + } else { + json_object *l_jobj_addr_from = json_object_new_string(dap_chain_addr_to_str(&l_addr_from)); + if (!l_jobj_addr_from) { + json_object_put(l_jobj_datum); + json_object_put(l_jobj_datums); + json_object_put(l_obj_chain); + dap_global_db_objs_delete(l_objs, l_objs_count); + dap_json_rpc_allocation_error; + return; } - 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_out_cond_subtype = OUT_COND_TYPE_FEE; - } break; - case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK: { - l_dist_token = l_main_ticker; - l_out_cond_subtype = OUT_COND_TYPE_STAKE_LOCK; - } break; - case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE: { - l_dist_token = l_main_ticker; - l_out_cond_subtype = OUT_COND_TYPE_XCHANGE; - } break; - case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE: { - l_dist_token = l_main_ticker; - l_out_cond_subtype = OUT_COND_TYPE_POS_DELEGATE; - } break; - case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY: { - l_dist_token = l_main_ticker; - l_out_cond_subtype = OUT_COND_TYPE_PAY; - } break; - default: - break; - } - } break; - default: - break; + json_object_object_add(l_jobj_datum, "from", l_jobj_addr_from); } - json_object *l_jobj_money = json_object_new_object(); - if (!l_jobj_money) { + dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_ALL, NULL); + json_object *l_jobj_to_list = json_object_new_array(); + json_object *l_jobj_change_list = json_object_new_array(); + json_object *l_jobj_to_from_emi = json_object_new_array(); + json_object *l_jobj_fee_list = json_object_new_array(); + json_object *l_jobj_stake_lock_list = json_object_new_array(); + json_object *l_jobj_xchange_list = json_object_new_array(); + json_object *l_jobj_stake_pos_delegate_list = json_object_new_array(); + json_object *l_jobj_pay_list = json_object_new_array(); + json_object *l_jobj_tx_vote = json_object_new_array(); + json_object *l_jobj_tx_voting = json_object_new_array(); + if (!l_jobj_to_list || !l_jobj_change_list || !l_jobj_fee_list || !l_jobj_stake_lock_list || + !l_jobj_xchange_list || !l_jobj_stake_pos_delegate_list || !l_jobj_pay_list) { json_object_put(l_jobj_to_list); json_object_put(l_jobj_change_list); json_object_put(l_jobj_to_from_emi); json_object_put(l_jobj_fee_list); + json_object_put(l_jobj_stake_lock_list); + json_object_put(l_jobj_xchange_list); + json_object_put(l_jobj_stake_pos_delegate_list); + json_object_put(l_jobj_pay_list); + json_object_put(l_jobj_tx_vote); + json_object_put(l_jobj_tx_voting); json_object_put(l_jobj_datum); json_object_put(l_jobj_datums); json_object_put(l_obj_chain); @@ -2930,35 +2878,77 @@ void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a dap_json_rpc_allocation_error; return; } - char *l_value_coins_str, *l_value_str = dap_uint256_to_char(l_value, &l_value_coins_str); - json_object_object_add(l_jobj_money, "value", json_object_new_string(l_value_str)); - json_object_object_add(l_jobj_money, "coins", json_object_new_string(l_value_coins_str)); - if (l_dist_token) { - json_object *l_jobj_token = json_object_new_string(l_dist_token); - if (!l_jobj_token) { - json_object_put(l_jobj_to_list); - json_object_put(l_jobj_change_list); - json_object_put(l_jobj_to_from_emi); - json_object_put(l_jobj_fee_list); - json_object_put(l_jobj_money); - json_object_put(l_jobj_datum); - json_object_put(l_jobj_datums); - json_object_put(l_obj_chain); - dap_global_db_objs_delete(l_objs, l_objs_count); - dap_json_rpc_allocation_error; - return; + enum { + OUT_COND_TYPE_UNKNOWN, + OUT_COND_TYPE_PAY, + OUT_COND_TYPE_FEE, + OUT_COND_TYPE_STAKE_LOCK, + OUT_COND_TYPE_XCHANGE, + OUT_COND_TYPE_POS_DELEGATE + } l_out_cond_subtype = {0}; + dap_list_t *l_vote_list = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_VOTE, NULL); + dap_list_t *l_voting_list = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_VOTING, 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_ticker; + 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_out_cond_subtype = OUT_COND_TYPE_FEE; + } + break; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK: { + l_dist_token = l_main_ticker; + l_out_cond_subtype = OUT_COND_TYPE_STAKE_LOCK; + } + break; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE: { + l_dist_token = l_main_ticker; + l_out_cond_subtype = OUT_COND_TYPE_XCHANGE; + } + break; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE: { + l_dist_token = l_main_ticker; + l_out_cond_subtype = OUT_COND_TYPE_POS_DELEGATE; + } + break; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY: { + l_dist_token = l_main_ticker; + l_out_cond_subtype = OUT_COND_TYPE_PAY; + } + break; + default: + break; + } + } + break; + default: + break; } - json_object_object_add(l_jobj_money, "token", l_jobj_token); - } - - if (l_dist_addr) { - json_object *l_jobj_addr = json_object_new_string(dap_chain_addr_to_str(l_dist_addr)); - if (!l_jobj_addr) { + json_object *l_jobj_money = json_object_new_object(); + if (!l_jobj_money) { json_object_put(l_jobj_to_list); json_object_put(l_jobj_change_list); json_object_put(l_jobj_to_from_emi); json_object_put(l_jobj_fee_list); - json_object_put(l_jobj_money); json_object_put(l_jobj_datum); json_object_put(l_jobj_datums); json_object_put(l_obj_chain); @@ -2966,135 +2956,183 @@ void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a dap_json_rpc_allocation_error; return; } - if (!datum_is_accepted_addr && l_wallet_addr) { - datum_is_accepted_addr = dap_chain_addr_compare(l_wallet_addr, l_dist_addr); - } - json_object *l_jobj_f = json_object_new_object(); - if (!l_jobj_f) { - json_object_put(l_jobj_to_list); - json_object_put(l_jobj_change_list); - json_object_put(l_jobj_to_from_emi); - json_object_put(l_jobj_fee_list); - json_object_put(l_jobj_addr); - json_object_put(l_jobj_money); - json_object_put(l_jobj_datum); - json_object_put(l_jobj_datums); - json_object_put(l_obj_chain); - dap_global_db_objs_delete(l_objs, l_objs_count); - dap_json_rpc_allocation_error; - return; + char *l_value_coins_str, *l_value_str = dap_uint256_to_char(l_value, &l_value_coins_str); + json_object_object_add(l_jobj_money, "value", json_object_new_string(l_value_str)); + json_object_object_add(l_jobj_money, "coins", json_object_new_string(l_value_coins_str)); + if (l_dist_token) { + json_object *l_jobj_token = json_object_new_string(l_dist_token); + if (!l_jobj_token) { + json_object_put(l_jobj_to_list); + json_object_put(l_jobj_change_list); + json_object_put(l_jobj_to_from_emi); + json_object_put(l_jobj_fee_list); + json_object_put(l_jobj_money); + json_object_put(l_jobj_datum); + json_object_put(l_jobj_datums); + json_object_put(l_obj_chain); + dap_global_db_objs_delete(l_objs, l_objs_count); + dap_json_rpc_allocation_error; + return; + } + json_object_object_add(l_jobj_money, "token", l_jobj_token); } - json_object_object_add(l_jobj_f, "money", l_jobj_money); - if (dap_chain_addr_compare(&l_addr_from, l_dist_addr)) { - bool l_in_from_emi = false; - for (dap_list_t *it_ems = l_list_in_ems; it_ems; it_ems = it_ems->next) { - dap_chain_tx_in_ems_t *l_in_ems = (dap_chain_tx_in_ems_t*)it_ems->data; - if (!dap_strcmp(l_in_ems->header.ticker, l_dist_token)) { - l_in_from_emi = true; - dap_hash_fast_t l_ems_hash = l_in_ems->header.token_emission_hash; - char l_ems_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; - dap_hash_fast_to_str(&l_ems_hash, l_ems_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE); - json_object * l_obj_ems_hash = json_object_new_string(l_ems_hash_str); - if (!l_obj_ems_hash) { - json_object_put(l_jobj_to_list); - json_object_put(l_jobj_change_list); - json_object_put(l_jobj_to_from_emi); - json_object_put(l_jobj_fee_list); - json_object_put(l_jobj_addr); - json_object_put(l_jobj_money); - json_object_put(l_jobj_datum); - json_object_put(l_jobj_datums); - json_object_put(l_obj_chain); - json_object_put(l_jobj_f); - dap_global_db_objs_delete(l_objs, l_objs_count); - dap_json_rpc_allocation_error; - return; + + if (l_dist_addr) { + json_object *l_jobj_addr = json_object_new_string(dap_chain_addr_to_str(l_dist_addr)); + if (!l_jobj_addr) { + json_object_put(l_jobj_to_list); + json_object_put(l_jobj_change_list); + json_object_put(l_jobj_to_from_emi); + json_object_put(l_jobj_fee_list); + json_object_put(l_jobj_money); + json_object_put(l_jobj_datum); + json_object_put(l_jobj_datums); + json_object_put(l_obj_chain); + dap_global_db_objs_delete(l_objs, l_objs_count); + dap_json_rpc_allocation_error; + return; + } + if (!datum_is_accepted_addr && l_wallet_addr) { + datum_is_accepted_addr = dap_chain_addr_compare(l_wallet_addr, l_dist_addr); + } + json_object *l_jobj_f = json_object_new_object(); + if (!l_jobj_f) { + json_object_put(l_jobj_to_list); + json_object_put(l_jobj_change_list); + json_object_put(l_jobj_to_from_emi); + json_object_put(l_jobj_fee_list); + json_object_put(l_jobj_addr); + json_object_put(l_jobj_money); + json_object_put(l_jobj_datum); + json_object_put(l_jobj_datums); + json_object_put(l_obj_chain); + dap_global_db_objs_delete(l_objs, l_objs_count); + dap_json_rpc_allocation_error; + return; + } + json_object_object_add(l_jobj_f, "money", l_jobj_money); + if (dap_chain_addr_compare(&l_addr_from, l_dist_addr)) { + bool l_in_from_emi = false; + for (dap_list_t *it_ems = l_list_in_ems; it_ems; it_ems = it_ems->next) { + dap_chain_tx_in_ems_t *l_in_ems = (dap_chain_tx_in_ems_t *) it_ems->data; + if (!dap_strcmp(l_in_ems->header.ticker, l_dist_token)) { + l_in_from_emi = true; + dap_hash_fast_t l_ems_hash = l_in_ems->header.token_emission_hash; + char l_ems_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; + dap_hash_fast_to_str(&l_ems_hash, l_ems_hash_str, + DAP_CHAIN_HASH_FAST_STR_SIZE); + json_object *l_obj_ems_hash = json_object_new_string(l_ems_hash_str); + if (!l_obj_ems_hash) { + json_object_put(l_jobj_to_list); + json_object_put(l_jobj_change_list); + json_object_put(l_jobj_to_from_emi); + json_object_put(l_jobj_fee_list); + json_object_put(l_jobj_addr); + json_object_put(l_jobj_money); + json_object_put(l_jobj_datum); + json_object_put(l_jobj_datums); + json_object_put(l_obj_chain); + json_object_put(l_jobj_f); + dap_global_db_objs_delete(l_objs, l_objs_count); + dap_json_rpc_allocation_error; + return; + } + json_object_object_add(l_jobj_f, "token_emission_hash", l_obj_ems_hash); + break; } - json_object_object_add(l_jobj_f, "token_emission_hash", l_obj_ems_hash); - break; } + if (l_in_from_emi) + json_object_array_add(l_jobj_to_from_emi, l_jobj_f); + else + json_object_array_add(l_jobj_change_list, l_jobj_f); + } else { + json_object_object_add(l_jobj_f, "addr", l_jobj_addr); + json_object_array_add(l_jobj_to_list, l_jobj_f); } - if (l_in_from_emi) - json_object_array_add(l_jobj_to_from_emi, l_jobj_f); - else - json_object_array_add(l_jobj_change_list, l_jobj_f); } else { - json_object_object_add(l_jobj_f, "addr", l_jobj_addr); - json_object_array_add(l_jobj_to_list, l_jobj_f); - } - } else { - switch (l_out_cond_subtype) { - case OUT_COND_TYPE_PAY: - json_object_array_add(l_jobj_pay_list, l_jobj_money); - break; - case OUT_COND_TYPE_FEE: - json_object_array_add(l_jobj_fee_list, l_jobj_money); - break; - case OUT_COND_TYPE_STAKE_LOCK: - json_object_array_add(l_jobj_stake_lock_list, l_jobj_money); - break; - case OUT_COND_TYPE_XCHANGE: - json_object_array_add(l_jobj_xchange_list, l_jobj_money); - break; - case OUT_COND_TYPE_POS_DELEGATE: - json_object_array_add(l_jobj_stake_pos_delegate_list, l_jobj_money); - break; - default: - log_it(L_ERROR, "An unknown subtype output was found in a transaction in the mempool list."); - break; + switch (l_out_cond_subtype) { + case OUT_COND_TYPE_PAY: + json_object_array_add(l_jobj_pay_list, l_jobj_money); + break; + case OUT_COND_TYPE_FEE: + json_object_array_add(l_jobj_fee_list, l_jobj_money); + break; + case OUT_COND_TYPE_STAKE_LOCK: + json_object_array_add(l_jobj_stake_lock_list, l_jobj_money); + break; + case OUT_COND_TYPE_XCHANGE: + json_object_array_add(l_jobj_xchange_list, l_jobj_money); + break; + case OUT_COND_TYPE_POS_DELEGATE: + json_object_array_add(l_jobj_stake_pos_delegate_list, l_jobj_money); + break; + default: + log_it(L_ERROR, + "An unknown subtype output was found in a transaction in the mempool list."); + break; + } } } + for (dap_list_t *it = l_vote_list; it; it = it->next) { + json_object *l_jobj_vote = dap_chain_datum_tx_item_vote_to_json( + (dap_chain_tx_vote_t *) it->data); + json_object_array_add(l_jobj_tx_vote, l_jobj_vote); + } + for (dap_list_t *it = l_voting_list; it; it = it->next) { + json_object *l_jobj_voting = dap_chain_datum_tx_item_voting_tsd_to_json(l_tx); + json_object_array_add(l_jobj_tx_voting, l_jobj_voting); + } + json_object_object_add(l_jobj_datum, "to", l_jobj_to_list); + json_object_object_add(l_jobj_datum, "change", l_jobj_change_list); + json_object_object_add(l_jobj_datum, "fee", l_jobj_fee_list); + json_object_array_length(l_jobj_pay_list) > 0 ? + json_object_object_add(l_jobj_datum, "srv_pay", l_jobj_pay_list) : json_object_put( + l_jobj_pay_list); + json_object_array_length(l_jobj_xchange_list) > 0 ? + json_object_object_add(l_jobj_datum, "srv_xchange", l_jobj_xchange_list) : json_object_put( + l_jobj_xchange_list); + json_object_array_length(l_jobj_stake_lock_list) > 0 ? + json_object_object_add(l_jobj_datum, "srv_stake_lock", l_jobj_stake_lock_list) + : json_object_put(l_jobj_stake_lock_list); + json_object_array_length(l_jobj_stake_pos_delegate_list) > 0 ? + json_object_object_add(l_jobj_datum, "srv_stake_pos_delegate", l_jobj_stake_pos_delegate_list) + : json_object_put( + l_jobj_stake_pos_delegate_list); + json_object_array_length(l_jobj_to_from_emi) > 0 ? + json_object_object_add(l_jobj_datum, "from_emission", l_jobj_to_from_emi) : json_object_put( + l_jobj_to_from_emi); + json_object_array_length(l_jobj_tx_vote) > 0 ? + json_object_object_add(l_jobj_datum, "vote", l_jobj_tx_vote) : json_object_put(l_jobj_tx_vote); + json_object_array_length(l_jobj_tx_voting) > 0 ? + json_object_object_add(l_jobj_datum, "voting", l_jobj_tx_voting) : json_object_put( + l_jobj_tx_voting); + dap_list_free(l_list_out_items); + dap_list_free(l_vote_list); + dap_list_free(l_voting_list); } - for (dap_list_t *it = l_vote_list; it; it = it->next) { - json_object *l_jobj_vote = dap_chain_datum_tx_item_vote_to_json((dap_chain_tx_vote_t*)it->data); - json_object_array_add(l_jobj_tx_vote, l_jobj_vote); - } - for (dap_list_t *it = l_voting_list; it; it = it->next) { - json_object *l_jobj_voting = dap_chain_datum_tx_item_voting_tsd_to_json(l_tx); - json_object_array_add(l_jobj_tx_voting, l_jobj_voting); + break; + case DAP_CHAIN_DATUM_TOKEN_EMISSION: { + size_t l_emi_size = l_datum->header.data_size; + 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); + json_object_object_add(l_jobj_datum, "data", dap_chain_datum_data_to_json(l_datum)); } - json_object_object_add(l_jobj_datum, "to", l_jobj_to_list); - json_object_object_add(l_jobj_datum, "change", l_jobj_change_list); - json_object_object_add(l_jobj_datum, "fee", l_jobj_fee_list); - json_object_array_length(l_jobj_pay_list) > 0 ? - json_object_object_add(l_jobj_datum, "srv_pay", l_jobj_pay_list) : json_object_put(l_jobj_pay_list); - json_object_array_length(l_jobj_xchange_list) > 0 ? - json_object_object_add(l_jobj_datum, "srv_xchange", l_jobj_xchange_list) : json_object_put(l_jobj_xchange_list); - json_object_array_length(l_jobj_stake_lock_list) > 0 ? - json_object_object_add(l_jobj_datum, "srv_stake_lock", l_jobj_stake_lock_list) : json_object_put(l_jobj_stake_lock_list); - json_object_array_length(l_jobj_stake_pos_delegate_list) > 0 ? - json_object_object_add(l_jobj_datum, "srv_stake_pos_delegate", l_jobj_stake_pos_delegate_list) : json_object_put(l_jobj_stake_pos_delegate_list); - json_object_array_length(l_jobj_to_from_emi) > 0 ? - json_object_object_add(l_jobj_datum, "from_emission", l_jobj_to_from_emi) : json_object_put(l_jobj_to_from_emi); - json_object_array_length(l_jobj_tx_vote) > 0 ? - json_object_object_add(l_jobj_datum, "vote", l_jobj_tx_vote) : json_object_put(l_jobj_tx_vote); - json_object_array_length(l_jobj_tx_voting) > 0 ? - json_object_object_add(l_jobj_datum, "voting", l_jobj_tx_voting) : json_object_put(l_jobj_tx_voting); - dap_list_free(l_list_out_items); - dap_list_free(l_vote_list); - dap_list_free(l_voting_list); - } - break; - case DAP_CHAIN_DATUM_TOKEN_EMISSION: { - size_t l_emi_size = l_datum->header.data_size; - 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); - json_object_object_add(l_jobj_datum, "data", dap_chain_datum_data_to_json(l_datum)); + break; + default: + json_object_object_add(l_jobj_datum, "data", dap_chain_datum_data_to_json(l_datum)); } - break; - default: - json_object_object_add(l_jobj_datum, "data", dap_chain_datum_data_to_json(l_datum)); } - } - if (l_wallet_addr) { - if (datum_is_accepted_addr) { - json_object_array_add(l_jobj_datums, l_jobj_datum); + if (l_wallet_addr) { + if (datum_is_accepted_addr) { + json_object_array_add(l_jobj_datums, l_jobj_datum); + } else + json_object_put(l_jobj_datum); } else - json_object_put(l_jobj_datum); - } else - json_object_array_add(l_jobj_datums, l_jobj_datum); + json_object_array_add(l_jobj_datums, l_jobj_datum); + } } json_object_object_add(l_obj_chain, "datums", l_jobj_datums); @@ -3753,11 +3791,17 @@ int com_mempool(int a_argc, char **a_argv, void **a_str_reply) return -1; } bool l_fast = (dap_cli_server_cmd_check_option(a_argv, arg_index, a_argc, "-brief") != -1) ? true : false; + size_t l_limit = 0, l_offset = 0; + const char *l_limit_str = NULL, *l_offset_str = NULL; + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-limit", &l_limit_str); + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-offset", &l_offset_str); + l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 0; + l_offset = l_offset_str ? strtoul(l_offset_str, NULL, 10) : 0; if(l_chain) { - s_com_mempool_list_print_for_chain(l_net, l_chain, l_wallet_addr, l_jobj_chains, l_hash_out_type, l_fast); + s_com_mempool_list_print_for_chain(l_net, l_chain, l_wallet_addr, l_jobj_chains, l_hash_out_type, l_fast, l_limit, l_offset); } else { DL_FOREACH(l_net->pub.chains, l_chain) { - s_com_mempool_list_print_for_chain(l_net, l_chain, l_wallet_addr, l_jobj_chains, l_hash_out_type, l_fast); + s_com_mempool_list_print_for_chain(l_net, l_chain, l_wallet_addr, l_jobj_chains, l_hash_out_type, l_fast, l_limit, l_offset); } } json_object_object_add(obj_ret, "chains", l_jobj_chains); @@ -6356,6 +6400,8 @@ int com_tx_history(int a_argc, char ** a_argv, void **a_str_reply) const char *l_net_str = NULL; const char *l_chain_str = NULL; const char *l_tx_hash_str = NULL; + const char *l_limit_str = NULL; + const char *l_offset_str = NULL; dap_chain_t * l_chain = NULL; dap_chain_net_t * l_net = NULL; @@ -6478,7 +6524,11 @@ int com_tx_history(int a_argc, char ** a_argv, void **a_str_reply) } } else if (l_addr) { // history addr and wallet - json_obj_out = dap_db_history_addr(l_addr, l_chain, l_hash_out_type, dap_chain_addr_to_str(l_addr)); + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-limit", &l_limit_str); + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-offset", &l_offset_str); + size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 0; + size_t l_offset = l_offset_str ? strtoul(l_offset_str, NULL, 10) : 0; + json_obj_out = dap_db_history_addr(l_addr, l_chain, l_hash_out_type, dap_chain_addr_to_str(l_addr), l_limit, l_offset); if (!json_obj_out) { dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_DAP_DB_HISTORY_ADDR_ERR, "something went wrong in tx_history"); @@ -6496,8 +6546,12 @@ int com_tx_history(int a_argc, char ** a_argv, void **a_str_reply) if (!json_obj_summary) { return DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_MEMORY_ERR; } - - json_object* json_arr_history_all = dap_db_history_tx_all(l_chain, l_net, l_hash_out_type, json_obj_summary, l_brief_out); + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-limit", &l_limit_str); + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-offset", &l_offset_str); + size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 0; + size_t l_offset = l_offset_str ? strtoul(l_offset_str, NULL, 10) : 0; + json_object* json_arr_history_all = dap_db_history_tx_all(l_chain, l_net, l_hash_out_type, json_obj_summary, + l_limit, l_offset, l_brief_out); if (!json_arr_history_all) { dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_DAP_DB_HISTORY_ALL_ERR, "something went wrong in tx_history"); diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c index 21d965bef165834416458e556c3aaa118202a05a..5ec0f0a1597ddaed1a139a8a2f8bd2a4f6c30ac9 100644 --- a/modules/net/dap_chain_node_cli_cmd_tx.c +++ b/modules/net/dap_chain_node_cli_cmd_tx.c @@ -295,7 +295,7 @@ static void s_tx_header_print(json_object* json_obj_datum, dap_chain_tx_hash_pro * @return char* */ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain, - const char *a_hash_out_type, const char * l_addr_str) + const char *a_hash_out_type, const char * l_addr_str, size_t a_limit, size_t a_offset) { json_object* json_obj_datum = json_object_new_array(); if (!json_obj_datum){ @@ -331,6 +331,18 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain, bool l_is_need_correction = false; uint256_t l_corr_value = {}, l_unstake_value = {}; json_object *l_corr_object = NULL; + + size_t l_arr_start = 0; + if (a_offset) + l_arr_start = a_offset * a_limit; + size_t l_arr_end = a_chain->callback_count_atom(a_chain); + if (a_limit) { + l_arr_end = l_arr_start + a_limit; + size_t l_length = a_chain->callback_count_atom(a_chain); + if (l_arr_end > l_length) + l_arr_end = l_length; + } + size_t i_tmp = 1; // load transactions dap_chain_datum_iter_t *l_datum_iter = a_chain->callback_datum_iter_create(a_chain); @@ -342,6 +354,11 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain, // go to next datum continue; // it's a transaction + if (i_tmp < l_arr_start || i_tmp > l_arr_end) { + i_tmp++; + continue; + } + i_tmp++; bool l_is_unstake = false; dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *)l_datum->data; dap_list_t *l_list_in_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_IN_ALL, NULL); @@ -589,7 +606,10 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain, return json_obj_datum; } -json_object* dap_db_history_tx_all(dap_chain_t *l_chain, dap_chain_net_t* l_net, const char *l_hash_out_type, json_object * json_obj_summary, bool out_brief) { +json_object *dap_db_history_tx_all(dap_chain_t *l_chain, dap_chain_net_t *l_net, + const char *l_hash_out_type, json_object *json_obj_summary, + size_t a_limit, size_t a_offset, bool out_brief) +{ log_it(L_DEBUG, "Start getting tx from chain"); size_t l_tx_count = 0; size_t l_tx_ledger_accepted = 0; @@ -598,6 +618,18 @@ json_object* dap_db_history_tx_all(dap_chain_t *l_chain, dap_chain_net_t* l_net, *l_cell_tmp = NULL; dap_chain_atom_iter_t *l_iter = NULL; json_object * json_arr_out = json_object_new_array(); + size_t l_arr_start = 0; + if (a_offset) { + l_arr_start = a_limit * a_offset; + } + size_t l_arr_end = l_chain->callback_count_atom(l_chain); + if (a_limit) { + l_arr_end = l_arr_start + a_limit; + if (l_arr_end > l_chain->callback_count_atom(l_chain)) { + l_arr_end = l_chain->callback_count_atom(l_chain); + } + } + size_t i_tmp = 1; HASH_ITER(hh, l_chain->cells, l_cell, l_cell_tmp) { l_iter = l_chain->callback_atom_iter_create(l_chain, l_cell->id, 0); size_t l_atom_size = 0; @@ -607,6 +639,11 @@ json_object* dap_db_history_tx_all(dap_chain_t *l_chain, dap_chain_net_t* l_net, dap_chain_datum_t **l_datums = l_cell->chain->callback_atom_get_datums(l_ptr, l_atom_size, &l_datums_count); for (size_t i = 0; i < l_datums_count; i++) { if (l_datums[i]->header.type_id == DAP_CHAIN_DATUM_TX) { + if (i_tmp < l_arr_start || i_tmp >= l_arr_end) { + i_tmp++; + continue; + } + i_tmp++; l_tx_count++; dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*)l_datums[i]->data; dap_hash_fast_t l_ttx_hash = {0}; @@ -1034,6 +1071,8 @@ int com_ledger(int a_argc, char ** a_argv, void **reply) enum {SUBCMD_NONE, SUBCMD_LIST_COIN, SUB_CMD_LIST_LEDGER_THRESHOLD, SUB_CMD_LIST_LEDGER_BALANCE, SUB_CMD_LIST_LEDGER_THRESHOLD_WITH_HASH}; int l_sub_cmd = SUBCMD_NONE; dap_chain_hash_fast_t l_tx_threshold_hash; + const char *l_limit_str = NULL; + const char *l_offset_str = NULL; if (dap_cli_server_cmd_find_option_val(a_argv, 2, 3, "coins", NULL )) l_sub_cmd = SUBCMD_LIST_COIN; if (dap_cli_server_cmd_find_option_val(a_argv, 2, 3, "balance", NULL )) @@ -1056,6 +1095,10 @@ int com_ledger(int a_argc, char ** a_argv, void **reply) return DAP_CHAIN_NODE_CLI_COM_LEDGER_PARAM_ERR; } dap_cli_server_cmd_find_option_val(a_argv, 0, a_argc, "-net", &l_net_str); + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-limit", &l_limit_str); + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-offset", &l_offset_str); + size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 0; + size_t l_offset = l_offset_str ? strtoul(l_offset_str, NULL, 10) : 0; if (l_net_str == NULL){ dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_NET_PARAM_ERR, "Command 'list' requires key -net"); return DAP_CHAIN_NODE_CLI_COM_LEDGER_NET_PARAM_ERR; @@ -1066,27 +1109,27 @@ int com_ledger(int a_argc, char ** a_argv, void **reply) return DAP_CHAIN_NODE_CLI_COM_LEDGER_LACK_ERR; } if (l_sub_cmd == SUB_CMD_LIST_LEDGER_THRESHOLD){ - json_object* json_obj_out = dap_ledger_threshold_info(l_ledger); + json_object* json_obj_out = dap_ledger_threshold_info(l_ledger, l_limit, l_offset); if (json_obj_out){ json_object_array_add(*json_arr_reply, json_obj_out); } return 0; } if (l_sub_cmd == SUB_CMD_LIST_LEDGER_THRESHOLD_WITH_HASH){ - json_object *json_obj_out = dap_ledger_threshold_hash_info(l_ledger, &l_tx_threshold_hash); + json_object *json_obj_out = dap_ledger_threshold_hash_info(l_ledger, &l_tx_threshold_hash, l_limit, l_offset); if (json_obj_out){ json_object_array_add(*json_arr_reply, json_obj_out); } return 0; } if (l_sub_cmd == SUB_CMD_LIST_LEDGER_BALANCE){ - json_object *json_obj_out = dap_ledger_balance_info(l_ledger); + json_object *json_obj_out = dap_ledger_balance_info(l_ledger, l_limit, l_offset); if (json_obj_out){ json_object_array_add(*json_arr_reply, json_obj_out); } return 0; } - json_object *json_obj_datum = dap_ledger_token_info(l_ledger); + json_object *json_obj_datum = dap_ledger_token_info(l_ledger, l_limit, l_offset); if (json_obj_datum) { json_object_array_add(*json_arr_reply, json_obj_datum); diff --git a/modules/net/include/dap_chain_ledger.h b/modules/net/include/dap_chain_ledger.h index f120bc48bce4bac0dcebf670e10e577fbd69a842..a6fcd882663520241a1815cf791632e75990feaa 100644 --- a/modules/net/include/dap_chain_ledger.h +++ b/modules/net/include/dap_chain_ledger.h @@ -230,14 +230,14 @@ int dap_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_toke int dap_ledger_token_load(dap_ledger_t *a_ledger, byte_t *a_token, size_t a_token_size); int dap_ledger_token_decl_add_check(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token, size_t a_token_size); char *dap_ledger_token_decl_add_err_code_to_str(int a_code); -json_object *dap_ledger_token_info(dap_ledger_t *a_ledger); +json_object *dap_ledger_token_info(dap_ledger_t *a_ledger, size_t a_limit, size_t a_offset); // Get all token-declarations dap_list_t* dap_ledger_token_decl_all(dap_ledger_t *a_ledger); -json_object *dap_ledger_threshold_info(dap_ledger_t *a_ledger); -json_object *dap_ledger_threshold_hash_info(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *l_tx_treshold_hash); -json_object *dap_ledger_balance_info(dap_ledger_t *a_ledger); +json_object *dap_ledger_threshold_info(dap_ledger_t *a_ledger, size_t a_limit, size_t a_offset); +json_object *dap_ledger_threshold_hash_info(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *l_tx_treshold_hash, size_t a_limit, size_t a_offset); +json_object *dap_ledger_balance_info(dap_ledger_t *a_ledger, size_t a_limit, size_t a_offset); size_t dap_ledger_token_auth_signs_valid(dap_ledger_t *a_ledger, const char * a_token_ticker); size_t dap_ledger_token_auth_signs_total(dap_ledger_t *a_ledger, const char * a_token_ticker); diff --git a/modules/net/include/dap_chain_node_cli_cmd_tx.h b/modules/net/include/dap_chain_node_cli_cmd_tx.h index 8c203515b3130d3988b1d3bd84a55c6829f6fd4c..06aafc4e5d3be8d26023b7476826bb23eb26d16a 100644 --- a/modules/net/include/dap_chain_node_cli_cmd_tx.h +++ b/modules/net/include/dap_chain_node_cli_cmd_tx.h @@ -40,7 +40,7 @@ void s_dap_chain_tx_hash_processed_ht_free(dap_chain_tx_hash_processed_ht_t **l_ * return history json */ json_object * dap_db_history_tx(dap_chain_hash_fast_t* a_tx_hash, dap_chain_t * a_chain, const char *a_hash_out_type, dap_chain_net_t * l_net); -json_object * dap_db_history_addr(dap_chain_addr_t * a_addr, dap_chain_t * a_chain, const char *a_hash_out_type, const char * l_addr_str); +json_object * dap_db_history_addr(dap_chain_addr_t * a_addr, dap_chain_t * a_chain, const char *a_hash_out_type, const char * l_addr_str, size_t a_limit, size_t a_offset); json_object * dap_db_tx_history_to_json(dap_chain_hash_fast_t* a_tx_hash, dap_hash_fast_t * l_atom_hash, dap_chain_datum_tx_t * l_tx, @@ -50,7 +50,9 @@ json_object * dap_db_tx_history_to_json(dap_chain_hash_fast_t* a_tx_hash, int l_ret_code, bool *accepted_tx, bool out_brief); -json_object* dap_db_history_tx_all(dap_chain_t *l_chain, dap_chain_net_t* l_net, const char *l_hash_out_type, json_object * json_obj_summary, bool out_brief); +json_object *dap_db_history_tx_all(dap_chain_t *l_chain, dap_chain_net_t *l_net, + const char *l_hash_out_type, json_object *json_obj_summary, + size_t a_limit, size_t a_offset, bool out_brief); /** * ledger command diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c index cc5e0e76d1e4d9d0393624fc62c5cae8a54ebf5f..115e2cb647226df9fbb41213f02aa231537fc6d0 100644 --- a/modules/service/xchange/dap_chain_net_srv_xchange.c +++ b/modules/service/xchange/dap_chain_net_srv_xchange.c @@ -104,7 +104,7 @@ int dap_chain_net_srv_xchange_init() "\tShows transaction history for the selected order\n" "srv_xchange order status -net <net_name> -order <order_hash>" "\tShows current amount of unselled coins from the selected order and percentage of its completion\n" - "srv_xchange orders -net <net_name> [-status {opened|closed|all}] [-token_from <token_ticker>] [-token_to <token_ticker>]\n" + "srv_xchange orders -net <net_name> [-status {opened|closed|all}] [-token_from <token_ticker>] [-token_to <token_ticker>] [-limit <limit>] [-offset <offset>]\n" "\tGet the exchange orders list within specified net name\n" "srv_xchange purchase -order <order hash> -net <net_name> -w <wallet_name> -value <value> -fee <value>\n" @@ -1449,9 +1449,9 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v uint256_t l_fee = dap_chain_balance_scan(l_fee_str); dap_hash_fast_t l_tx_hash = {}; dap_chain_hash_fast_from_str(l_order_hash_str, &l_tx_hash); - dap_chain_wallet_close(l_wallet); char *l_tx_hash_ret = NULL; int l_ret_code = dap_chain_net_srv_xchange_remove(l_net, &l_tx_hash, l_fee, l_wallet, &l_tx_hash_ret); + dap_chain_wallet_close(l_wallet); switch (l_ret_code) { case XCHANGE_REMOVE_ERROR_OK: dap_cli_server_cmd_set_reply_text(a_str_reply, "Order successfully removed. Created inactivate tx with hash %s", l_tx_hash_ret); @@ -1477,7 +1477,6 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v dap_cli_server_cmd_set_reply_text(a_str_reply, "An error occurred with an unknown code: %d.", l_ret_code); break; } - DAP_DELETE(l_sign_str); return l_ret_code; } break; @@ -1983,8 +1982,31 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply) } uint64_t l_printed_orders_count = 0; + const char *l_limit_str = NULL; + const char *l_offset_str = NULL; + dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-limit", &l_limit_str); + dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-offset", &l_offset_str); + size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 0; + size_t l_offset = l_offset_str ? strtoul(l_offset_str, NULL, 10) : 0; + size_t l_arr_start = 0; + if (l_limit > 1) { + l_arr_start = l_limit * l_offset; + } + size_t l_arr_end = dap_list_length(l_tx_list); + if (l_offset) { + l_arr_end = l_arr_start + l_limit; + if (l_arr_end > dap_list_length(l_tx_list)) { + l_arr_end = dap_list_length(l_tx_list); + } + } + size_t i_tmp = 0; // Print all txs for (dap_list_t *it = l_tx_list; it; it = it->next) { + if (i_tmp < l_arr_start || i_tmp > l_arr_end) { + i_tmp++; + continue; + } + i_tmp++; dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *)it->data; dap_chain_tx_out_cond_t *l_out_cond = dap_chain_datum_tx_out_cond_get(l_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE , NULL); if (!l_out_cond || l_out_cond->header.srv_uid.uint64 != DAP_CHAIN_NET_SRV_XCHANGE_ID) @@ -2355,6 +2377,11 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply) *a_str_reply = dap_string_free(l_reply_str, false); break; }else if (strcmp(l_price_subcommand,"history") == 0){ + const char *l_limit_str = NULL, *l_offset_str = NULL; + dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-limit", &l_limit_str); + dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-offset", &l_offset_str); + size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 0; + size_t l_offset = l_offset_str ? strtoul(l_offset_str, NULL, 10) : 0; dap_string_t *l_reply_str = dap_string_new(""); dap_time_t l_time[2]; @@ -2369,9 +2396,24 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply) dap_cli_server_cmd_set_reply_text(a_str_reply,"Can't find transactions"); return -6; } + size_t l_arr_start = 0; + size_t l_arr_end = l_datum_num; + if (l_offset > 1) { + l_arr_start = l_limit * l_offset; + } + if (l_limit) { + l_arr_end = l_arr_start + l_limit; + } + size_t i_tmp = 0; dap_list_t * l_cur = l_datum_list0; while(l_cur){ + if (i_tmp < l_arr_start || i_tmp > l_arr_end) { + i_tmp++; + l_cur = dap_list_next(l_cur); + continue; + } + i_tmp++; dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*) ((dap_chain_datum_t*) l_cur->data)->data; if(l_tx){ dap_hash_fast_t l_tx_hash = {}; @@ -2423,6 +2465,11 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply) dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "list", &l_list_subcommand); if( l_list_subcommand ){ if (strcmp(l_list_subcommand,"all") == 0){ + const char *l_limit_str = NULL, *l_offset_str = NULL; + dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-limit", &l_limit_str); + dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-offset", &l_offset_str); + size_t l_offset = l_offset_str ? strtoul(l_offset_str, NULL, 10) : 0; + size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 0; dap_string_t *l_reply_str = dap_string_new(""); char ** l_tickers = NULL; size_t l_tickers_count = 0; @@ -2430,9 +2477,23 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply) size_t l_pairs_count = 0; if(l_tickers){ + size_t l_arr_start = 0; + size_t l_arr_end = l_tickers_count; + if (l_offset > 1) { + l_arr_start = l_limit * l_offset; + } + if (l_limit) { + l_arr_end = l_arr_start + l_limit; + } + size_t i_tmp = 0; for(size_t i = 0; i< l_tickers_count; i++){ for(size_t j = i+1; j< l_tickers_count; j++){ if(l_tickers[i] && l_tickers[j]){ + if (i_tmp < l_arr_start || i_tmp > l_arr_end) { + i_tmp++; + continue; + } + i_tmp++; dap_string_append_printf(l_reply_str,"%s:%s ", l_tickers[i], l_tickers[j]); l_pairs_count++; } diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c index c1df202f3b46dc6de89103b55cb1fbe099ec5828..96ec6b4786cece464de182eb8184909edfeef45e 100644 --- a/modules/type/blocks/dap_chain_cs_blocks.c +++ b/modules/type/blocks/dap_chain_cs_blocks.c @@ -176,7 +176,7 @@ int dap_chain_cs_blocks_init() "block -net <net_name> -chain <chain_name> dump <block_hash>\n" "\t\tDump block info\n\n" - "block -net <net_name> -chain <chain_name> list [{signed | first_signed}]" + "block -net <net_name> -chain <chain_name> list [{signed | first_signed}] [-limit] [-offset]" " [-from_hash <block_hash>] [-to_hash <block_hash>] [-from_date <YYMMDD>] [-to_date <YYMMDD>]" " [{-cert <signing_cert_name> | -pkey_hash <signing_cert_pkey_hash>} [-unspent]]\n" "\t\t List blocks\n\n" @@ -744,7 +744,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) case SUBCMD_LIST:{ const char *l_cert_name = NULL, *l_from_hash_str = NULL, *l_to_hash_str = NULL, - *l_from_date_str = NULL, *l_to_date_str = NULL, *l_pkey_hash_str = NULL; + *l_from_date_str = NULL, *l_to_date_str = NULL, *l_pkey_hash_str = NULL, *l_limit_str = NULL, *l_offset_str = NULL; bool l_unspent_flag = false, l_first_signed_flag = false, l_signed_flag = false, l_hash_flag = false; size_t l_block_count = 0; dap_pkey_t * l_pub_key = NULL; @@ -760,6 +760,10 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-to_hash", &l_to_hash_str); dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-from_dt", &l_from_date_str); dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-to_dt", &l_to_date_str); + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-limit", &l_limit_str); + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-offset", &l_offset_str); + size_t l_offset = l_offset_str ? strtoul(l_offset_str, NULL, 10) : 0; + size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 0; if (l_signed_flag && l_first_signed_flag) { dap_cli_server_cmd_set_reply_text(a_str_reply, "Choose only one option from 'singed' and 'first_signed'"); @@ -826,7 +830,23 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) pthread_rwlock_rdlock(&PVT(l_blocks)->rwlock); dap_string_t *l_str_tmp = dap_string_new(NULL); + size_t l_start_arr = 0; + if(l_offset > 1) { + l_start_arr = l_offset * l_limit; + } + size_t l_arr_end = PVT(l_blocks)->blocks_count; + if (l_limit) { + l_arr_end = l_start_arr + l_limit; + if (l_arr_end > PVT(l_blocks)->blocks_count) + l_arr_end = PVT(l_blocks)->blocks_count; + } + size_t i_tmp = 0; for (dap_chain_block_cache_t *l_block_cache = PVT(l_blocks)->blocks; l_block_cache; l_block_cache = l_block_cache->hh.next) { + if (i_tmp < l_start_arr || i_tmp >= l_arr_end) { + i_tmp++; + continue; + } + i_tmp++; dap_time_t l_ts = l_block_cache->block->hdr.ts_created; if (l_from_time && l_ts < l_from_time) continue; diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c index 72bc9984ebd5c5fd5c6143ba4f2c3235b36edbf7..001c4382bbe4e3749c268978185d91879757bc85 100644 --- a/modules/type/dag/dap_chain_cs_dag.c +++ b/modules/type/dag/dap_chain_cs_dag.c @@ -164,7 +164,7 @@ int dap_chain_cs_dag_init() "\tdoesn't changes after sign add to event. \n\n" "dag event dump -net <net_name> -chain <chain_name> -event <event_hash> -from {events | events_lasts | threshold | round.new | round.<Round id in hex>} [-H {hex | base58(default)}]\n" "\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" + "dag event list -net <net_name> -chain <chain_name> -from {events | events_lasts | threshold | round.new | round.<Round id in hex>} [-limit] [-offset]\n\n" "\tShow event list \n\n" "dag event count -net <net_name> -chain <chain_name>\n" "\tShow count event \n\n" @@ -1916,6 +1916,9 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply) } break; case SUBCMD_EVENT_LIST: { + const char *l_limit_str = NULL, *l_offset_str = NULL; + dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-limit", &l_limit_str); + dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-offset", &l_offset_str); if (l_from_events_str && strcmp(l_from_events_str,"round.new") == 0) { char * l_gdb_group_events = DAP_CHAIN_CS_DAG(l_chain)->gdb_group_events_round_new; dap_string_t * l_str_tmp = dap_string_new(""); @@ -1923,9 +1926,23 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply) dap_global_db_obj_t * l_objs; size_t l_objs_count = 0; l_objs = dap_global_db_get_all_sync(l_gdb_group_events,&l_objs_count); + char *ptr; + size_t l_limit = l_limit_str ? strtoull(l_limit_str, &ptr, 10) : 0; + size_t l_offset = l_offset_str ? strtoull(l_offset_str, &ptr, 10) : 0; + size_t l_arr_start = 0; + if (l_offset) { + l_arr_start = l_offset * l_limit; + dap_string_append_printf(l_str_tmp, "limit: %lu", l_arr_start); + } + size_t l_arr_end = l_objs_count; + if (l_limit) { + l_arr_end = l_arr_start + l_limit; + if (l_arr_end > l_objs_count) + l_arr_end = l_objs_count; + } dap_string_append_printf(l_str_tmp,"%s.%s: Found %zu records :\n",l_net->pub.name,l_chain->name,l_objs_count); - for (size_t i = 0; i < l_objs_count; i++) { + for (size_t i = l_arr_start; i < l_arr_end; i++) { if (!strcmp(DAG_ROUND_CURRENT_KEY, l_objs[i].key)) { dap_string_append_printf(l_str_tmp, "\t%s: %" DAP_UINT64_FORMAT_U "\n", l_objs[i].key, *(uint64_t *)l_objs[i].value); @@ -1951,13 +1968,32 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply) } else if (!l_from_events_str || (strcmp(l_from_events_str,"events") == 0)) { dap_string_t * l_str_tmp = dap_string_new(NULL); pthread_mutex_lock(&PVT(l_dag)->events_mutex); + size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 0; + size_t l_offset = l_offset_str ? strtoul(l_offset_str, NULL, 10) : 0; + size_t l_arr_start = 0; + if (l_offset > 1) { + l_arr_start = l_offset * l_limit; + dap_string_append_printf(l_str_tmp, "limit: %lu\n", l_arr_start); + } + size_t l_arr_end = HASH_COUNT(PVT(l_dag)->events); + if (l_limit) { + l_arr_end = l_arr_start + l_limit; + if (l_arr_end > HASH_COUNT(PVT(l_dag)->events)) + l_arr_end = HASH_COUNT(PVT(l_dag)->events); + } + size_t i_tmp = 0; dap_chain_cs_dag_event_item_t * l_event_item = NULL,*l_event_item_tmp = NULL; HASH_ITER(hh,PVT(l_dag)->events,l_event_item, l_event_item_tmp ) { - char buf[50]; - dap_time_to_str_rfc822(buf, 50, l_event_item->event->header.ts_created); - dap_string_append_printf(l_str_tmp,"\t%s: ts_create=%s\n", - dap_chain_hash_fast_to_str_static( &l_event_item->hash), - buf); + if (i_tmp < l_arr_start || i_tmp >= l_arr_end) { + i_tmp++; + } else { + i_tmp++; + char buf[50]; + dap_time_to_str_rfc822(buf, 50, l_event_item->event->header.ts_created); + dap_string_append_printf(l_str_tmp, "\t%s: ts_create=%s\n", + dap_chain_hash_fast_to_str_static(&l_event_item->hash), + buf); + } } size_t l_events_count = HASH_COUNT(PVT(l_dag)->events); pthread_mutex_unlock(&PVT(l_dag)->events_mutex); @@ -1969,8 +2005,27 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply) dap_string_t * l_str_tmp = dap_string_new(NULL); pthread_mutex_lock(&PVT(l_dag)->events_mutex); dap_chain_cs_dag_event_item_t * l_event_item = NULL,*l_event_item_tmp = NULL; + size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 0; + size_t l_offset = l_offset_str ? strtoul(l_offset_str, NULL, 10) : 0; + size_t l_arr_start = 0; + if (l_offset) { + l_arr_start = l_offset * l_limit; + dap_string_append_printf(l_str_tmp, "limit: %lu", l_arr_start); + } + size_t l_arr_end = HASH_COUNT(PVT(l_dag)->events_treshold); + if (l_limit) { + l_arr_end = l_arr_start + l_limit; + if (l_arr_end > HASH_COUNT(PVT(l_dag)->events_treshold)) + l_arr_end = HASH_COUNT(PVT(l_dag)->events_treshold); + } + size_t i_tmp = 0; dap_string_append_printf(l_str_tmp,"\nDAG threshold events:\n"); HASH_ITER(hh,PVT(l_dag)->events_treshold,l_event_item, l_event_item_tmp ) { + if (i_tmp < l_arr_start || i_tmp > l_arr_end) { + i_tmp++; + continue; + } + i_tmp++; char buf[50]; dap_time_to_str_rfc822(buf, 50, l_event_item->event->header.ts_created); dap_string_append_printf(l_str_tmp,"\t%s: ts_create=%s\n",