diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c index 6e034e231d906486a40d87f48fcbdadee6561473..0f665559fe155d0be3ed5bb3e3a76a128b109cec 100644 --- a/modules/type/blocks/dap_chain_cs_blocks.c +++ b/modules/type/blocks/dap_chain_cs_blocks.c @@ -70,6 +70,7 @@ typedef struct dap_chain_cs_blocks_pvt { // All the blocks are here dap_chain_block_cache_t *blocks; + dap_chain_block_cache_t *blocks_num; _Atomic uint64_t blocks_count; // Brnches and forks @@ -216,7 +217,7 @@ int dap_chain_cs_blocks_init() "\t\tComplete the current new round, verify it and if everything is ok - publish new blocks in chain\n\n" "Blockchain explorer:\n" - "block -net <net_name> [-chain <chain_name>] dump -hash <block_hash>\n" + "block -net <net_name> [-chain <chain_name>] [-brief] dump {-hash <block_hash> | -num <block_number>}\n" "\t\tDump block info\n\n" "block -net <net_name> [-chain <chain_name>] list [{signed | first_signed}] [-limit] [-offset] [-head]" @@ -397,6 +398,21 @@ dap_chain_block_cache_t * dap_chain_block_cache_get_by_hash(dap_chain_cs_blocks_ return l_ret; } +/** + * @brief dap_chain_block_cache_get_by_number + * @param a_blocks + * @param a_block_number + * @return + */ +dap_chain_block_cache_t * dap_chain_block_cache_get_by_number(dap_chain_cs_blocks_t * a_blocks, uint64_t a_block_number) +{ + dap_chain_block_cache_t * l_ret = NULL; + pthread_rwlock_rdlock(& PVT(a_blocks)->rwlock); + HASH_FIND_BYHASHVALUE(hh2, PVT(a_blocks)->blocks_num, &a_block_number, sizeof (a_block_number), a_block_number, l_ret); + pthread_rwlock_unlock(& PVT(a_blocks)->rwlock); + return l_ret; +} + int dap_chain_block_add_fork_notificator(dap_chain_cs_blocks_callback_fork_resolved_t a_callback, void *a_arg) { if (!a_callback) @@ -760,7 +776,9 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) case SUBCMD_DUMP:{ const char *l_hash_out_type = NULL; const char *l_hash_str = NULL; + const char *l_num_str = NULL; dap_chain_hash_fast_t l_block_hash={0}; + bool l_brief = (dap_cli_server_cmd_check_option(a_argv, arg_index, a_argc, "-brief") != -1) ? true : false; dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-H", &l_hash_out_type); if(!l_hash_out_type) l_hash_out_type = "hex"; @@ -769,13 +787,21 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) return DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR; } dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-hash", &l_hash_str); - if (!l_hash_str) { - dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_BLOCK_HASH_ERR, "Enter block hash "); + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-num", &l_num_str); + if (!l_hash_str && !l_num_str) { + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_BLOCK_HASH_ERR, "Enter block hash or block number"); return DAP_CHAIN_NODE_CLI_COM_BLOCK_HASH_ERR; } dap_chain_hash_fast_from_str(l_hash_str, &l_block_hash); - dap_chain_block_cache_t *l_block_cache = dap_chain_block_cache_get_by_hash(l_blocks, &l_block_hash); + dap_chain_block_cache_t *l_block_cache = NULL; + if (l_hash_str) + l_block_cache = dap_chain_block_cache_get_by_hash(l_blocks, &l_block_hash); + else { + uint16_t num = 0; + dap_digit_from_string(l_num_str, &num, sizeof(uint16_t)); + l_block_cache = dap_chain_block_cache_get_by_number(l_blocks, num); + } if (!l_block_cache) { dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_BLOCK_FIND_ERR, "Can't find block %s ", l_hash_str); return DAP_CHAIN_NODE_CLI_COM_BLOCK_FIND_ERR; @@ -787,7 +813,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) json_object* json_obj_inf = json_object_new_object(); json_object_object_add(json_obj_inf, "block_number", json_object_new_uint64(l_block_cache->block_number)); - json_object_object_add(json_obj_inf, "hash", json_object_new_string(l_hash_str)); + json_object_object_add(json_obj_inf, "hash", json_object_new_string(l_block_cache->block_hash_str)); snprintf(l_hexbuf, sizeof(l_hexbuf), "0x%04X",l_block->hdr.version); json_object_object_add(json_obj_inf, "version", json_object_new_string(l_hexbuf)); @@ -846,22 +872,30 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) json_object* json_obj_tx = json_object_new_object(); dap_chain_datum_t * l_datum = l_block_cache->datum[i]; size_t l_datum_size = dap_chain_datum_size(l_datum); - json_object_object_add(json_obj_tx, "datum_size",json_object_new_uint64(l_datum_size)); - if (l_datum_size < sizeof (l_datum->header) ){ - dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_BLOCK_DATUM_SIZE_ERR, "ERROR: datum size %zu is smaller than header size %zu \n",l_datum_size, - sizeof (l_datum->header)); - break; + if (l_brief){ + const char *l_hash_str = dap_strcmp(l_hash_out_type, "hex") + ? dap_enc_base58_encode_hash_to_str_static(&l_block_cache->datum_hash[i]) + : dap_chain_hash_fast_to_str_static(&l_block_cache->datum_hash[i]); + json_object_object_add(json_obj_tx, "num",json_object_new_uint64(i)); + json_object_object_add(json_obj_tx, "hash",json_object_new_string(l_hash_str)); + } else { + json_object_object_add(json_obj_tx, "datum size ",json_object_new_uint64(l_datum_size)); + if (l_datum_size < sizeof (l_datum->header) ){ + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_BLOCK_DATUM_SIZE_ERR, "ERROR: datum size %zu is smaller than header size %zu \n",l_datum_size, + sizeof (l_datum->header)); + break; + } + // Nested datums + snprintf(l_hexbuf, sizeof(l_hexbuf), "0x%02X",l_datum->header.version_id); + json_object_object_add(json_obj_tx, "version",json_object_new_string(l_hexbuf)); + const char * l_datum_type_str = "UNKNOWN"; + DAP_DATUM_TYPE_STR(l_datum->header.type_id, l_datum_type_str); + json_object_object_add(json_obj_tx, "type_id",json_object_new_string(l_datum_type_str)); + dap_time_to_str_rfc822(l_time_buf, DAP_TIME_STR_SIZE, l_datum->header.ts_create); + json_object_object_add(json_obj_tx, "ts_create",json_object_new_string(l_time_buf)); + json_object_object_add(json_obj_tx, "data_size",json_object_new_int(l_datum->header.data_size)); + dap_chain_datum_dump_json(*a_json_arr_reply, json_obj_tx,l_datum,l_hash_out_type,l_net->pub.id, true); } - // Nested datums - snprintf(l_hexbuf, sizeof(l_hexbuf), "0x%02X",l_datum->header.version_id); - json_object_object_add(json_obj_tx, "version",json_object_new_string(l_hexbuf)); - const char * l_datum_type_str = "UNKNOWN"; - DAP_DATUM_TYPE_STR(l_datum->header.type_id, l_datum_type_str); - json_object_object_add(json_obj_tx, "type_id",json_object_new_string(l_datum_type_str)); - dap_time_to_str_rfc822(l_time_buf, DAP_TIME_STR_SIZE, l_datum->header.ts_create); - json_object_object_add(json_obj_tx, "ts_create",json_object_new_string(l_time_buf)); - json_object_object_add(json_obj_tx, "data_size",json_object_new_int(l_datum->header.data_size)); - dap_chain_datum_dump_json(*a_json_arr_reply, json_obj_tx,l_datum,l_hash_out_type,l_net->pub.id, true); json_object_array_add(json_arr_datum_out, json_obj_tx); } // Signatures @@ -1532,6 +1566,7 @@ static int s_callback_cs_blocks_purge(dap_chain_t *a_chain) dap_chain_block_cache_delete(l_block); } PVT(l_blocks)->blocks_count = 0; + HASH_CLEAR(hh2, PVT(l_blocks)->blocks_num); pthread_rwlock_unlock(&PVT(l_blocks)->rwlock); dap_chain_block_datum_index_t *l_datum_index = NULL, *l_datum_index_tmp = NULL; @@ -1697,7 +1732,8 @@ static bool s_select_longest_branch(dap_chain_cs_blocks_t * a_blocks, dap_chain_ for (l_curr_index = 0; l_last_new_forked_item && l_curr_index < a_main_branch_length; l_last_new_forked_item = l_last_new_forked_item->hh.prev, ++l_curr_index){ s_delete_atom_datums(l_blocks, l_last_new_forked_item->block_cache); --PVT(l_blocks)->blocks_count; - HASH_DEL(PVT(l_blocks)->blocks, l_last_new_forked_item->block_cache); + HASH_DEL(PVT(l_blocks)->blocks_num, l_last_new_forked_item->block_cache); + HASH_DELETE(hh2, PVT(l_blocks)->blocks, l_last_new_forked_item->block_cache); } // Next we add all atoms from new main branch into blockchain @@ -1709,6 +1745,7 @@ static bool s_select_longest_branch(dap_chain_cs_blocks_t * a_blocks, dap_chain_ dap_chain_block_cache_t *l_curr_atom = l_item->block_cache; ++PVT(l_blocks)->blocks_count; HASH_ADD(hh, PVT(l_blocks)->blocks, block_hash, sizeof(l_curr_atom->block_hash), l_curr_atom); + HASH_ADD_BYHASHVALUE(hh2, PVT(l_blocks)->blocks_num, block_number, sizeof(l_curr_atom->block_number), l_curr_atom->block_number, l_curr_atom); debug_if(s_debug_more, L_DEBUG, "Verified atom %p: ACCEPTED", l_curr_atom); s_add_atom_datums(l_blocks, l_curr_atom); dap_chain_atom_notify(a_blocks->chain, l_curr_atom->block->hdr.cell_id, &l_curr_atom->block_hash, (byte_t*)l_curr_atom->block, l_curr_atom->block_size); @@ -1775,6 +1812,7 @@ static dap_chain_atom_verify_res_t s_callback_atom_add(dap_chain_t * a_chain, da if (l_last_block && dap_hash_fast_compare(&l_last_block->block_hash, &l_block_prev_hash)){ ++PVT(l_blocks)->blocks_count; HASH_ADD(hh, PVT(l_blocks)->blocks, block_hash, sizeof(l_block_cache->block_hash), l_block_cache); + HASH_ADD_BYHASHVALUE(hh2, PVT(l_blocks)->blocks_num, block_number, sizeof(l_block_cache->block_number), l_block_cache->block_number, l_block_cache); debug_if(s_debug_more, L_DEBUG, "Verified atom %p: ACCEPTED", a_atom); s_add_atom_datums(l_blocks, l_block_cache); dap_chain_atom_notify(a_chain, l_block->hdr.cell_id, &l_block_cache->block_hash, (byte_t*)l_block, a_atom_size); @@ -1866,6 +1904,7 @@ static dap_chain_atom_verify_res_t s_callback_atom_add(dap_chain_t * a_chain, da } } HASH_ADD(hh, PVT(l_blocks)->blocks, block_hash, sizeof(l_block_cache->block_hash), l_block_cache); + HASH_ADD_BYHASHVALUE(hh2, PVT(l_blocks)->blocks_num, block_number, sizeof(l_block_cache->block_number), l_block_cache->block_number, l_block_cache); ++PVT(l_blocks)->blocks_count; debug_if(s_debug_more, L_DEBUG, "Verified genesis atom %p: ACCEPTED", a_atom); s_add_atom_datums(l_blocks, l_block_cache); diff --git a/modules/type/blocks/include/dap_chain_block_cache.h b/modules/type/blocks/include/dap_chain_block_cache.h index 24eca3786dd8cc36cd05b4cbb3de864d5d077ec8..cd0b39c6b36e9f30306f286d7df06edd869f41c5 100644 --- a/modules/type/blocks/include/dap_chain_block_cache.h +++ b/modules/type/blocks/include/dap_chain_block_cache.h @@ -65,7 +65,7 @@ typedef struct dap_chain_block_cache { dap_list_t *forked_branches; // uthash handle - UT_hash_handle hh; + UT_hash_handle hh, hh2; } dap_chain_block_cache_t; typedef struct dap_chain_block_forked_branch_atoms_table{ diff --git a/modules/type/blocks/include/dap_chain_cs_blocks.h b/modules/type/blocks/include/dap_chain_cs_blocks.h index 697270d7b30e242844498bf48327eb5526897eeb..b8d74b2caf5b83029b15841d96b4effc66e45252 100644 --- a/modules/type/blocks/include/dap_chain_cs_blocks.h +++ b/modules/type/blocks/include/dap_chain_cs_blocks.h @@ -89,6 +89,7 @@ typedef struct dap_chain_cs_blocks_hardfork_fees { int dap_chain_cs_blocks_init(); void dap_chain_cs_blocks_deinit(); dap_chain_block_cache_t *dap_chain_block_cache_get_by_hash(dap_chain_cs_blocks_t *a_blocks, dap_chain_hash_fast_t *a_block_hash); +dap_chain_block_cache_t * dap_chain_block_cache_get_by_number(dap_chain_cs_blocks_t * a_blocks, uint64_t a_block_number); dap_chain_cs_blocks_hardfork_fees_t *dap_chain_cs_blocks_fees_aggregate(dap_chain_t *a_chain); int dap_chain_block_add_fork_notificator(dap_chain_cs_blocks_callback_fork_resolved_t a_callback, void *a_arg);