diff --git a/modules/chain/include/dap_chain.h b/modules/chain/include/dap_chain.h index f59f10a6367fe6975a46a575e2b2b9a2f6d3f070..ee066d615550300e37807300dc263aad7a5a68cd 100644 --- a/modules/chain/include/dap_chain.h +++ b/modules/chain/include/dap_chain.h @@ -54,6 +54,7 @@ typedef struct dap_chain_atom_iter { size_t cur_size; dap_chain_hash_fast_t *cur_hash; uint64_t cur_num; + dap_time_t cur_ts; } dap_chain_atom_iter_t; typedef struct dap_chain_datum_iter { @@ -96,6 +97,7 @@ typedef void (*dap_chain_callback_ptr_t)(dap_chain_t *, void * ); typedef dap_chain_atom_verify_res_t (*dap_chain_callback_atom_t)(dap_chain_t *a_chain, dap_chain_atom_ptr_t a_atom, size_t a_atom_size, dap_hash_fast_t *a_atom_hash, bool a_atom_new); typedef dap_chain_atom_ptr_t (*dap_chain_callback_atom_form_treshold_t)(dap_chain_t *, size_t *); +typedef json_object *(*dap_chain_callback_atom_to_json)(json_object **a_arr_out, dap_chain_t *a_chain, dap_chain_atom_ptr_t a_atom, size_t a_atom_size, const char *a_hex_out_type); typedef dap_chain_atom_verify_res_t (*dap_chain_callback_atom_verify_t)(dap_chain_t *, dap_chain_atom_ptr_t , size_t, dap_hash_fast_t*); typedef size_t (*dap_chain_callback_atom_get_hdr_size_t)(void); @@ -200,6 +202,7 @@ typedef struct dap_chain { dap_chain_callback_atom_iter_find_by_hash_t callback_atom_find_by_hash; dap_chain_callback_atom_iter_get_by_num_t callback_atom_get_by_num; dap_chain_callback_datum_find_by_hash_t callback_datum_find_by_hash; + dap_chain_callback_atom_to_json callback_atom_dump_json; dap_chain_callback_block_find_by_hash_t callback_block_find_by_tx_hash; diff --git a/modules/common/include/dap_chain_datum_decree.h b/modules/common/include/dap_chain_datum_decree.h index 1d6722f12c9e351a1f1f06788ae4d0dd81959c4a..70ef4f65bd0effd30b298a3ff4bd8ac65925e9c0 100644 --- a/modules/common/include/dap_chain_datum_decree.h +++ b/modules/common/include/dap_chain_datum_decree.h @@ -128,6 +128,38 @@ DAP_STATIC_INLINE const char *dap_chain_datum_decree_subtype_to_str(uint16_t a_d } } +DAP_STATIC_INLINE uint16_t dap_chain_datum_decree_type_from_str(const char *a_decree_type) { + if (!dap_strcmp(a_decree_type, "fee")){ + return DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_FEE; + } else if (!dap_strcmp(a_decree_type, "owners")) { + return DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_OWNERS; + } else if (!dap_strcmp(a_decree_type, "owners_min")) { + return DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_OWNERS_MIN; + } else if (!dap_strcmp(a_decree_type, "stake_approve")) { + return DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_APPROVE; + } else if (!dap_strcmp(a_decree_type, "stake_invalidate")) { + return DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_INVALIDATE; + } else if (!dap_strcmp(a_decree_type, "min_value")) { + return DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALUE; + } else if (!dap_strcmp(a_decree_type, "min_validators_count")) { + return DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALIDATORS_COUNT; + } else if (!dap_strcmp(a_decree_type, "ban")) { + return DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_BAN; + } else if (!dap_strcmp(a_decree_type, "unban")) { + return DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_UNBAN; + } else if (!dap_strcmp(a_decree_type, "reward")) { + return DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_REWARD; + } else if (!dap_strcmp(a_decree_type, "validator_max_weight")) { + return DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_MAX_WEIGHT; + } else if (!dap_strcmp(a_decree_type, "emergency_validators")) { + return DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_EMERGENCY_VALIDATORS; + } else if (!dap_strcmp(a_decree_type, "check_signs_structure")) { + return DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_CHECK_SIGNS_STRUCTURE; + } else { + return 0; + } +} + DAP_STATIC_INLINE const char *dap_chain_datum_decree_tsd_type_to_str(uint16_t a_decree_tsd_type) { switch (a_decree_tsd_type) { case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE: diff --git a/modules/net/dap_chain_node_cli.c b/modules/net/dap_chain_node_cli.c index 73de66e80ec091a5214b5a0cb1e7f1ec278d5372..68391bb0f3da610c60eba83fc4d4999e2e33700f 100644 --- a/modules/net/dap_chain_node_cli.c +++ b/modules/net/dap_chain_node_cli.c @@ -342,6 +342,17 @@ int dap_chain_node_cli_init(dap_config_t * g_config) "decree info -net <net_name>\n" "Displays information about the parameters of the decrees in the network.\n"); + //Find command + dap_cli_server_cmd_add("find", cmd_find, "The command searches for the specified elements by the specified attributes", + "find datum -net <net_name> [-chain <chain_name>] -hash <datum_hash>\n" + "\tSearches for datum by hash in the specified network in chains and mempool.\n" + "find atom -net <net_name> [-chain <chain_name>] -hash <atom_hash>\n" + "\tSearches for an atom by hash in a specified network in chains.\n" + "find decree -net <net_name> [-chain <chain_name>] -type <type_decree> [-where <chains|mempool>]\n" + "\tSearches for decrees by hash in the specified decree type in the specified network in its chains.\n" + "\tTypes decree: fee, owners, owners_min, stake_approve, stake_invalidate, min_value, " + "min_validators_count, ban, unban, reward, validator_max_weight, emergency_validators, check_signs_structure\n"); + // Exit - always last! dap_cli_server_cmd_add ("exit", com_exit, "Stop application and exit", "exit\n" ); diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c index 7c18b966bd173163e046e22bb43aacda5610a719..ca0232f229ff7f52f08af307635da7a6c72deacb 100644 --- a/modules/net/dap_chain_node_cli_cmd.c +++ b/modules/net/dap_chain_node_cli_cmd.c @@ -3358,20 +3358,9 @@ int _cmd_mempool_check(dap_chain_net_t *a_net, dap_chain_t *a_chain, const char bool l_found_in_chains = false; int l_ret_code = 0; dap_hash_fast_t l_atom_hash = {}; - if (a_chain) - l_datum = s_com_mempool_check_datum_in_chain(a_chain, a_datum_hash); - else { - dap_chain_t *it = NULL; - DL_FOREACH(a_net->pub.chains, it) { - l_datum = s_com_mempool_check_datum_in_chain(it, a_datum_hash); - if (l_datum) { - l_chain_name = it->name; - break; - } - } - } - if (!l_datum) { - l_found_in_chains = true; + // FIND in chain + { + // dap_hash_fast_t l_datum_hash; if (dap_chain_hash_fast_from_hex_str(a_datum_hash, &l_datum_hash)) { dap_json_rpc_error_add(*a_json_arr_reply, COM_MEMPOOL_CHECK_ERR_INCORRECT_HASH_STR, @@ -3390,6 +3379,23 @@ int _cmd_mempool_check(dap_chain_net_t *a_net, dap_chain_t *a_chain, const char } } } + if (l_datum) + l_found_in_chains = true; + } + // FIND in mempool + if (!l_found_in_chains) { + if (a_chain) + l_datum = s_com_mempool_check_datum_in_chain(a_chain, a_datum_hash); + else { + dap_chain_t *it = NULL; + DL_FOREACH(a_net->pub.chains, it) { + l_datum = s_com_mempool_check_datum_in_chain(it, a_datum_hash); + if (l_datum) { + l_chain_name = it->name; + break; + } + } + } } json_object *l_jobj_datum = json_object_new_object(); json_object *l_datum_hash = json_object_new_string(a_datum_hash); @@ -4001,6 +4007,217 @@ int com_mempool(int a_argc, char **a_argv, void **a_str_reply) return ret; } +typedef enum _s_where_search{ + ALL, + CHAINS, + MEMPOOL +}_s_where_search_t; + +void _cmd_find_type_decree_in_chain(json_object *a_out, dap_chain_t *a_chain, uint16_t a_decree_type, _s_where_search_t a_where, const char *a_hash_out_type) { + json_object *l_common_decree_arr = json_object_new_array(); + json_object *l_service_decree_arr = json_object_new_array(); + if (a_where == ALL || a_where == CHAINS) { + dap_chain_cell_t *l_cell, *l_iter_tmp; + HASH_ITER(hh, a_chain->cells, l_cell, l_iter_tmp) { + dap_chain_atom_iter_t *l_atom_iter = l_cell->chain->callback_atom_iter_create(l_cell->chain, l_cell->id, + NULL); + dap_chain_atom_ptr_t l_atom; + uint64_t l_atom_size = 0; + for (l_atom = l_cell->chain->callback_atom_iter_get(l_atom_iter, DAP_CHAIN_ITER_OP_FIRST, &l_atom_size); + l_atom && l_atom_size; + l_atom = l_cell->chain->callback_atom_iter_get(l_atom_iter, DAP_CHAIN_ITER_OP_NEXT, &l_atom_size)) { + size_t l_datum_count = 0; + dap_chain_datum_t **l_datums = l_cell->chain->callback_atom_get_datums(l_atom, l_atom_size, + &l_datum_count); + json_object *l_obj_atom = json_object_new_object(); + char l_buff_ts[50] = {'\0'}; + dap_time_to_str_rfc822(&l_buff_ts, 50, l_atom_iter->cur_ts); + for (size_t i = 0; i < l_datum_count; i++) { + dap_chain_datum_t *l_datum = l_datums[i]; + if (l_datum[i].header.type_id != DAP_CHAIN_DATUM_DECREE) continue; + dap_chain_datum_decree_t *l_decree = (dap_chain_datum_decree_t *) l_datum[i].data; + if (l_decree->header.sub_type == a_decree_type) { + json_object *l_jobj_atom = json_object_new_object(); + json_object *l_jobj_atom_create = json_object_new_string(l_buff_ts); + json_object *l_jobj_atom_hash = json_object_new_string( + !dap_strcmp(a_hash_out_type, "base58") ? + dap_enc_base58_encode_hash_to_str_static(l_atom_iter->cur_hash) : + dap_hash_fast_to_str_static(l_atom_iter->cur_hash)); + json_object_object_add(l_jobj_atom, "hash", l_jobj_atom_hash); + json_object_object_add(l_jobj_atom, "created", l_jobj_atom_create); + json_object *l_jobj_decree = json_object_new_object(); + size_t l_decree_size = dap_chain_datum_decree_get_size(l_decree); + dap_chain_datum_decree_dump_json(l_jobj_decree, l_decree, l_decree_size, a_hash_out_type); + json_object *l_obj_source = json_object_new_object(); + json_object_object_add(l_obj_source, "atom", l_jobj_atom); + json_object_object_add(l_jobj_decree, "source", l_obj_source); + (l_decree->header.type == DAP_CHAIN_DATUM_DECREE_TYPE_COMMON) ? + json_object_array_add(l_common_decree_arr, l_jobj_decree) : + json_object_array_add(l_service_decree_arr, l_jobj_decree); + } + } + } + l_cell->chain->callback_atom_iter_delete(l_atom_iter); + } + } + if (a_where == ALL || a_where == MEMPOOL) { + char *l_gdb_group_mempool = dap_chain_net_get_gdb_group_mempool_new(a_chain); + size_t l_mempool_count = 0; + dap_global_db_obj_t *l_objs = dap_global_db_get_all_sync(l_gdb_group_mempool, &l_mempool_count); + for (size_t i = 0; i < l_mempool_count; i++) { + dap_chain_datum_t *l_datum = (dap_chain_datum_t *) (l_objs[i].value); + if (l_datum->header.type_id != DAP_CHAIN_DATUM_DECREE) continue; + dap_chain_datum_decree_t *l_decree = (dap_chain_datum_decree_t *) l_datum->data; + if (l_decree->header.sub_type == a_decree_type) { + json_object *l_jobj_decree = json_object_new_object(); + size_t l_decree_size = dap_chain_datum_decree_get_size(l_decree); + dap_chain_datum_decree_dump_json(l_jobj_decree, l_decree, l_decree_size, a_hash_out_type); + json_object_object_add(l_jobj_decree, "source", json_object_new_string("mempool")); + (l_decree->header.type == DAP_CHAIN_DATUM_DECREE_TYPE_COMMON) ? + json_object_array_add(l_common_decree_arr, l_jobj_decree) : + json_object_array_add(l_service_decree_arr, l_jobj_decree); + } + } + dap_global_db_objs_delete(l_objs, l_mempool_count); + } + json_object_object_add(a_out, "common", l_common_decree_arr); + json_object_object_add(a_out, "service", l_service_decree_arr); +} + +int cmd_find(int a_argc, char **a_argv, void **a_reply) { + json_object **a_json_reply = (json_object **)a_reply; + int arg_index = 1; + dap_chain_net_t *l_net = NULL; + dap_chain_t *l_chain = NULL; + enum _subcmd {SUBCMD_DATUM, SUBCMD_ATOM, SUBCMD_DECREE}; + enum _subcmd l_cmd = 0; + if (a_argv[1]) { + if (!dap_strcmp(a_argv[1], "datum")) { + l_cmd = SUBCMD_DATUM; + } else if (!dap_strcmp(a_argv[1], "atom")) { + l_cmd = SUBCMD_ATOM; + } else if (!dap_strcmp(a_argv[1], "decree")) { + l_cmd = SUBCMD_DECREE; + } else { + dap_json_rpc_error_add(*a_json_reply,DAP_CHAIN_NODE_CLI_FUND_ERR_UNKNOWN_SUBCMD,"Invalid sub command specified. Sub command %s " + "is not supported.", a_argv[1]); + return DAP_CHAIN_NODE_CLI_FUND_ERR_UNKNOWN_SUBCMD; + } + } + int cmd_parse_status = dap_chain_node_cli_cmd_values_parse_net_chain_for_json(*a_json_reply, &arg_index, a_argc, a_argv, &l_chain, &l_net, CHAIN_TYPE_INVALID); + if (cmd_parse_status != 0){ + dap_json_rpc_error_add(*a_json_reply, cmd_parse_status, "Request parsing error (code: %d)", cmd_parse_status); + return cmd_parse_status; + } + 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); + switch (l_cmd) { + case SUBCMD_DATUM: { + const char *l_datum_hash = NULL; + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-hash", &l_datum_hash); + if (!l_datum_hash) { + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-datum", &l_datum_hash); + if (!l_datum_hash) { + dap_json_rpc_error_add(*a_json_reply, DAP_CHAIN_NODE_CLI_FIND_ERR_HASH_IS_NOT_SPECIFIED, + "The hash of the datum is not specified."); + return DAP_CHAIN_NODE_CLI_FIND_ERR_HASH_IS_NOT_SPECIFIED; + } + } + return _cmd_mempool_check(l_net, l_chain, l_datum_hash, l_hash_out_type, a_reply); + } break; + case SUBCMD_ATOM: { + const char *l_atom_hash_str = NULL; + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-hash", &l_atom_hash_str); + dap_hash_fast_t l_atom_hash = {0}; + if (!l_atom_hash_str) { + dap_json_rpc_error_add(*a_json_reply, DAP_CHAIN_NODE_CLI_FIND_ERR_HASH_IS_NOT_SPECIFIED, "The hash of the atom is not specified."); + return DAP_CHAIN_NODE_CLI_FIND_ERR_HASH_IS_NOT_SPECIFIED; + } + if (dap_chain_hash_fast_from_str(l_atom_hash_str, &l_atom_hash)) { + dap_json_rpc_error_add(*a_json_reply, DAP_CHAIN_NODE_CLI_FIND_ERR_PARSE_HASH, "Failed to convert the value '%s' to a hash.", l_atom_hash_str); + return DAP_CHAIN_NODE_CLI_FIND_ERR_PARSE_HASH; + } + json_object *l_obj_atom = json_object_new_object(); + json_object *l_obj_atom_hash = json_object_new_string(l_atom_hash_str); + json_object_object_add(l_obj_atom, "hash", l_obj_atom_hash); + dap_chain_atom_ptr_t l_atom_ptr = NULL; + size_t l_atom_size = 0; + if (l_chain) { + l_atom_ptr = dap_chain_get_atom_by_hash(l_chain, &l_atom_hash, &l_atom_size); + } else { + for (l_chain = l_net->pub.chains ; l_chain; l_chain = l_chain->next){ + l_atom_ptr = dap_chain_get_atom_by_hash(l_chain, &l_atom_hash, &l_atom_size); + if (l_atom_ptr) break; + } + } + json_object *l_obj_source = NULL; + json_object *l_jobj_find = NULL; + if (l_atom_ptr) { + l_obj_source = json_object_new_object(); + json_object *l_obj_net = json_object_new_string(l_net->pub.name); + json_object *l_obj_chain = json_object_new_string(l_chain->name); + json_object_object_add(l_obj_source, "net", l_obj_net); + json_object_object_add(l_obj_source, "chain", l_obj_chain); + l_jobj_find = json_object_new_boolean(TRUE); + json_object_object_add(l_obj_atom, "source", l_obj_source); + json_object_object_add(l_obj_atom, "dump", l_chain->callback_atom_dump_json(a_json_reply, l_chain, l_atom_ptr, l_atom_size, l_hash_out_type)); + } else { + l_jobj_find = json_object_new_boolean(FALSE); + } + json_object_object_add(l_obj_atom, "find", l_jobj_find); + json_object_array_add(*a_json_reply, l_obj_atom); + } break; + case SUBCMD_DECREE: { + const char* l_type_decre_str = NULL; + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-type", &l_type_decre_str); + if (!l_type_decre_str){ + dap_json_rpc_error_add(*a_json_reply, DAP_CHIAN_NODE_CLI_FIND_ERR_SUBTYPE_DECREE_IS_NOT_SPECIFIED, + "The type of decree you are looking for is not specified."); + return DAP_CHIAN_NODE_CLI_FIND_ERR_SUBTYPE_DECREE_IS_NOT_SPECIFIED; + } + uint16_t l_subtype_decree = dap_chain_datum_decree_type_from_str(l_type_decre_str); + if (!l_subtype_decree) { + dap_json_rpc_error_add(*a_json_reply, DAP_CHAIN_NODE_CLI_FIND_ERR_UNKNOWN_SUBTYPE_DECREE, + "There is no decree of type '%s'.", l_type_decre_str); + return DAP_CHAIN_NODE_CLI_FIND_ERR_UNKNOWN_SUBTYPE_DECREE; + } + const char *l_with_type_str = NULL; + const char *l_where_str = NULL; + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-where", &l_where_str); + _s_where_search_t l_where = ALL; + if (l_where_str) { + if (!dap_strcmp(l_where_str, "chains")) { + l_where = CHAINS; + } else if (!dap_strcmp(l_where_str, "mempool")) { + l_where = MEMPOOL; + } else { + dap_json_rpc_error_add(*a_json_reply, DAP_CHAIN_NODE_CLI_FIND_ERR_UNKNOWN_PARAMETR_WHERE, + "'%s' is not a valid place to look. Use mempool or chains.", + l_where_str); + return DAP_CHAIN_NODE_CLI_FIND_ERR_UNKNOWN_PARAMETR_WHERE; + } + } + json_object *l_obj = json_object_new_object(); + json_object_object_add(l_obj, "type", json_object_new_string(l_type_decre_str)); + json_object *l_jobj_chains = json_object_new_object(); + if (l_chain) { + json_object *l_jobj_data = json_object_new_object(); + _cmd_find_type_decree_in_chain(l_jobj_data, l_chain, l_subtype_decree, l_where, l_hash_out_type); + json_object_object_add(l_jobj_chains, l_chain->name, l_jobj_data); + } else { + for (l_chain = l_net->pub.chains; l_chain; l_chain = l_chain->next) { + json_object *l_jobj_data = json_object_new_object(); + _cmd_find_type_decree_in_chain(l_jobj_data, l_chain, l_subtype_decree, l_where, l_hash_out_type); + json_object_object_add(l_jobj_chains, l_chain->name, l_jobj_data); + } + } + json_object_object_add(l_obj, "chains", l_jobj_chains); + json_object_array_add(*a_json_reply, l_obj); + } break; + } + return DAP_CHAIN_NODE_CLI_FIND_OK; +} + /** * @brief * diff --git a/modules/net/include/dap_chain_node_cli_cmd.h b/modules/net/include/dap_chain_node_cli_cmd.h index 253a0bf8b9aa920b0120d201fe57c87c928e8b27..a76937af3b861d0ee346f0e740bbb77a72d1f892 100644 --- a/modules/net/include/dap_chain_node_cli_cmd.h +++ b/modules/net/include/dap_chain_node_cli_cmd.h @@ -363,4 +363,22 @@ int com_signer(int a_argc, char **a_argv, void **a_str_reply); //remove func int cmd_remove(int a_argc, char **a_argv, void **a_str_reply); +typedef enum cmd_find_list_err { + DAP_CHAIN_NODE_CLI_FIND_OK = 0, + DAP_CHAIN_NODE_CLI_FIND_ERR_PARSE_HASH = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START, + DAP_CHAIN_NODE_CLI_FUND_ERR_UNKNOWN_SUBCMD, + DAP_CHAIN_NODE_CLI_FIND_ERR_HASH_IS_NOT_SPECIFIED, + DAP_CHAIN_NODE_CLI_FIND_ERR_UNKNOWN_SUBTYPE_DECREE, + DAP_CHIAN_NODE_CLI_FIND_ERR_SUBTYPE_DECREE_IS_NOT_SPECIFIED, + DAP_CHAIN_NODE_CLI_FIND_ERR_UNKNOWN_PARAMETR_WHERE, +}cmd_find_list_err_t; +/** + * Handler coomand find + * @param a_argc + * @param a_argv + * @param a_str_reply + * @return + */ +int cmd_find(int a_argc, char **a_argv, void **a_str_reply); + void dap_notify_new_client_send_info(dap_events_socket_t *a_es, void *a_arg); diff --git a/modules/type/blocks/CMakeLists.txt b/modules/type/blocks/CMakeLists.txt index 3770f285fde25cf498200ae5b8af9f18757fcdd1..67e7ef053890c1eaad0126e5f8d15707ba1e8eb0 100644 --- a/modules/type/blocks/CMakeLists.txt +++ b/modules/type/blocks/CMakeLists.txt @@ -10,7 +10,7 @@ if(BUILD_CELLFRAME_SDK_TESTS) add_subdirectory(tests) endif() -target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_chain dap_cli_server dap_chain_net) +target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_chain dap_chain_common dap_cli_server dap_chain_net) target_include_directories(${PROJECT_NAME} INTERFACE .) target_include_directories(${PROJECT_NAME} PUBLIC include) diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c index 66b3817e868833d54a6b530c449de491fa5b7d8e..c9f9d33df4a9815cc24178d6690cd642ae12454c 100644 --- a/modules/type/blocks/dap_chain_cs_blocks.c +++ b/modules/type/blocks/dap_chain_cs_blocks.c @@ -33,6 +33,8 @@ #include "dap_chain_mempool.h" #include "dap_chain_net_srv_stake_pos_delegate.h" #include "dap_chain_cs_esbocs.h" +#include "dap_chain_datum.h" +#include "dap_enc_base58.h" #define LOG_TAG "dap_chain_cs_blocks" @@ -95,7 +97,7 @@ typedef struct dap_chain_cs_blocks_pvt { log_it(L_DEBUG, "Unlocked rwqlock, %s, %d, thread_id=%u", __FUNCTION__, __LINE__, dap_gettid()); static int s_cli_parse_cmd_hash(char ** a_argv, int a_arg_index, int a_argc, void **a_str_reply,const char * a_param, dap_chain_hash_fast_t * a_datum_hash); -static void s_cli_meta_hash_print( json_object* a_json_obj_out, const char * a_meta_title, dap_chain_block_meta_t * a_meta); +static void s_cli_meta_hash_print( json_object* a_json_obj_out, const char * a_meta_title, dap_chain_block_meta_t * a_meta, const char *a_hash_out_type); static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply); // Setup BFT consensus and select the longest chunk @@ -116,6 +118,7 @@ static size_t s_callback_atom_get_static_hdr_size(void); static dap_chain_atom_iter_t *s_callback_atom_iter_create(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id, dap_hash_fast_t *a_hash_from); static dap_chain_atom_ptr_t s_callback_atom_iter_find_by_hash(dap_chain_atom_iter_t * a_atom_iter , dap_chain_hash_fast_t * a_atom_hash, size_t * a_atom_size); +static json_object *s_callback_atom_dump_json(json_object **a_arr_out, dap_chain_t *a_chain, dap_chain_atom_ptr_t a_atom_ptr, size_t a_atom_size, const char *a_hash_out_type); static dap_chain_atom_ptr_t s_callback_atom_iter_get_by_num(dap_chain_atom_iter_t *a_atom_iter, uint64_t a_atom_num); static dap_chain_datum_t *s_callback_datum_find_by_hash(dap_chain_t *a_chain, dap_chain_hash_fast_t *a_datum_hash, dap_chain_hash_fast_t *a_block_hash, int *a_ret_code); @@ -287,8 +290,10 @@ static int s_chain_cs_blocks_new(dap_chain_t *a_chain, dap_config_t *a_chain_con a_chain->callback_atom_get_timestamp = s_chain_callback_atom_get_timestamp; a_chain->callback_atom_find_by_hash = s_callback_atom_iter_find_by_hash; + a_chain->callback_atom_dump_json = s_callback_atom_dump_json; a_chain->callback_atom_get_by_num = s_callback_atom_iter_get_by_num; a_chain->callback_datum_find_by_hash = s_callback_datum_find_by_hash; +// a_chain->callback_atom_dump_json = a_chain->callback_block_find_by_tx_hash = s_callback_block_find_by_tx_hash; a_chain->callback_calc_reward = s_callback_calc_reward; @@ -454,13 +459,22 @@ static int s_cli_parse_cmd_hash(char ** a_argv, int a_arg_index, int a_argc, voi * @param a_str_tmp * @param a_meta_title * @param a_meta + * @param a_hash_out_type */ -static void s_cli_meta_hash_print(json_object* a_json_obj_out, const char *a_meta_title, dap_chain_block_meta_t *a_meta) +static void s_cli_meta_hash_print(json_object* a_json_obj_out, const char *a_meta_title, dap_chain_block_meta_t *a_meta, const char *a_hash_out_type) { if (a_meta->hdr.data_size == sizeof (dap_chain_hash_fast_t)) { - char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; - dap_chain_hash_fast_to_str((dap_chain_hash_fast_t *)a_meta->data, l_hash_str, sizeof(l_hash_str)); + const char *l_hash_str = !dap_strcmp(a_hash_out_type, "base58") ? + dap_enc_base58_encode_hash_to_str_static(a_meta->data) : + dap_chain_hash_fast_to_str_static(a_meta->data); json_object_object_add(a_json_obj_out, a_meta_title, json_object_new_string(l_hash_str)); +// if (dap_strcmp(a_hash_out_type, "base58")) { +// const char *l_hash_str = dap_enc_base58_encode_hash_to_str_static(a_meta->data); + // +// } else { +// char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; +// dap_chain_hash_fast_to_str((dap_chain_hash_fast_t *) a_meta->data, l_hash_str, sizeof(l_hash_str)); +// } } else json_object_object_add(a_json_obj_out, a_meta_title, json_object_new_string("Error, hash size is incorrect")); } @@ -754,13 +768,13 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) json_object_object_add(json_obj_meta, "GENESIS", json_object_new_string("GENESIS")); break; case DAP_CHAIN_BLOCK_META_PREV: - s_cli_meta_hash_print(json_obj_meta,"PREV", l_meta); + s_cli_meta_hash_print(json_obj_meta,"PREV", l_meta, l_hash_out_type); break; case DAP_CHAIN_BLOCK_META_ANCHOR: - s_cli_meta_hash_print(json_obj_meta, "ANCHOR", l_meta); + s_cli_meta_hash_print(json_obj_meta, "ANCHOR", l_meta, l_hash_out_type); break; case DAP_CHAIN_BLOCK_META_LINK: - s_cli_meta_hash_print(json_obj_meta, "LINK", l_meta); + s_cli_meta_hash_print(json_obj_meta, "LINK", l_meta, l_hash_out_type); break; case DAP_CHAIN_BLOCK_META_NONCE: s_cli_meta_hex_print(json_obj_meta, "NONCE", l_meta); @@ -820,11 +834,12 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) size_t l_sign_size = dap_sign_get_size(l_sign); dap_chain_hash_fast_t l_pkey_hash; dap_sign_get_pkey_hash(l_sign, &l_pkey_hash); - char l_pkey_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; - dap_chain_hash_fast_to_str(&l_pkey_hash, l_pkey_hash_str, sizeof(l_pkey_hash_str)); + const char *l_hash_str = !dap_strcmp(l_hash_out_type, "base58") ? + dap_enc_base58_encode_hash_to_str_static(&l_pkey_hash) : + dap_chain_hash_fast_to_str_static(&l_pkey_hash); json_object_object_add(json_obj_sign, "type",json_object_new_string(dap_sign_type_to_str( l_sign->header.type ))); json_object_object_add(json_obj_sign, "size",json_object_new_uint64(l_sign_size)); - json_object_object_add(json_obj_sign, "pkey_hash",json_object_new_string(l_pkey_hash_str)); + json_object_object_add(json_obj_sign, "pkey_hash",json_object_new_string(l_hash_str)); json_object_array_add(json_arr_sign_out, json_obj_sign); } json_object_array_add(*a_json_arr_reply, json_arr_sign_out); @@ -2093,6 +2108,104 @@ static dap_chain_atom_ptr_t s_callback_block_find_by_tx_hash(dap_chain_t * a_cha return l_datum_index->block_cache->block; } +static json_object *s_callback_atom_dump_json(json_object **a_arr_out, dap_chain_t *a_chain, dap_chain_atom_ptr_t a_atom_ptr, size_t a_atom_size, const char *a_hash_out_type) { + dap_chain_block_t *l_block = (dap_chain_block_t *) a_atom_ptr; + json_object *l_obj_ret = json_object_new_object(); + char l_time_buf[DAP_TIME_STR_SIZE], l_hexbuf[32] = { '\0' }; + sprintf(l_hexbuf, "0x%04X", l_block->hdr.version); + + json_object_object_add(l_obj_ret, "version", json_object_new_string(l_hexbuf)); + sprintf(l_hexbuf, "0x%016"DAP_UINT64_FORMAT_X"", l_block->hdr.cell_id.uint64); + json_object_object_add(l_obj_ret, "cell_id", json_object_new_string(l_hexbuf)); + sprintf(l_hexbuf, "0x%016"DAP_UINT64_FORMAT_X"", l_block->hdr.chain_id.uint64); + json_object_object_add(l_obj_ret, "chain_id", json_object_new_string(l_hexbuf)); + dap_time_to_str_rfc822(l_time_buf, DAP_TIME_STR_SIZE, l_block->hdr.ts_created); + json_object_object_add(l_obj_ret, "ts_created", json_object_new_string(l_time_buf)); + + // Dump Metadata + size_t l_offset = 0; + json_object *l_jobj_metadata = json_object_new_array(); + for (uint32_t i = 0; i < l_block->hdr.meta_count; i++) { + json_object *json_obj_meta = json_object_new_object(); + dap_chain_block_meta_t *l_meta = (dap_chain_block_meta_t *) (l_block->meta_n_datum_n_sign + l_offset); + switch (l_meta->hdr.type) { + case DAP_CHAIN_BLOCK_META_GENESIS: + json_object_object_add(json_obj_meta, "GENESIS", json_object_new_string("GENESIS")); + break; + case DAP_CHAIN_BLOCK_META_PREV: + s_cli_meta_hash_print(json_obj_meta, "PREV", l_meta, a_hash_out_type); + break; + case DAP_CHAIN_BLOCK_META_ANCHOR: + s_cli_meta_hash_print(json_obj_meta, "ANCHOR", l_meta, a_hash_out_type); + break; + case DAP_CHAIN_BLOCK_META_LINK: + s_cli_meta_hash_print(json_obj_meta, "LINK", l_meta, a_hash_out_type); + break; + case DAP_CHAIN_BLOCK_META_NONCE: + s_cli_meta_hex_print(json_obj_meta, "NONCE", l_meta); + break; + case DAP_CHAIN_BLOCK_META_NONCE2: + s_cli_meta_hex_print(json_obj_meta, "NONCE2", l_meta); + break; + default: { + sprintf(l_hexbuf, "0x%0X", i); + json_object_object_add(json_obj_meta, "# -", json_object_new_string(l_hexbuf)); + int l_len = l_meta->hdr.data_size * 2 + 5; + char *l_data_hex = DAP_NEW_STACK_SIZE(char, l_len); + snprintf(l_data_hex, 2, "0x"); + dap_bin2hex(l_data_hex + 2, l_meta->data, l_meta->hdr.data_size); + json_object_object_add(json_obj_meta, "Data hex - ", json_object_new_string(l_data_hex)); + } + } + json_object_array_add(l_jobj_metadata, json_obj_meta); + l_offset += sizeof(l_meta->hdr) + l_meta->hdr.data_size; + } + json_object_object_add(l_obj_ret, "metadata", l_jobj_metadata); + json_object *l_jobj_datums = json_object_new_array(); + for (uint16_t i = 0; i < l_block->hdr.datum_count; i++) { + dap_chain_datum_t *l_datum = (dap_chain_datum_t*)(l_block->meta_n_datum_n_sign + l_offset); + json_object *l_jobj_datum = json_object_new_object(); + size_t l_datum_size = dap_chain_datum_size(l_datum); + json_object_object_add(l_jobj_datum, "datum size ",json_object_new_uint64(l_datum_size)); + if (l_datum_size < sizeof (l_datum->header) ){ + dap_json_rpc_error_add(*a_arr_out, DAP_CHAIN_NODE_CLI_COM_BLOCK_DATUM_SIZE_ERR, "ERROR: datum size %zu is smaller than header size %zu",l_datum_size, + sizeof (l_datum->header)); + break; + } + // Nested datums + sprintf(l_hexbuf,"0x%02X",l_datum->header.version_id); + json_object_object_add(l_jobj_datum, "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(l_jobj_datum, "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(l_jobj_datum, "ts_create",json_object_new_string(l_time_buf)); + json_object_object_add(l_jobj_datum, "data_size",json_object_new_int(l_datum->header.data_size)); + dap_chain_datum_dump_json(*a_arr_out, l_jobj_datum,l_datum, a_hash_out_type, a_chain->net_id); + json_object_array_add(l_jobj_datums, l_jobj_datum); + l_offset += l_datum_size; + } + json_object_object_add(l_obj_ret, "datums", l_jobj_datums); + json_object *l_jobj_signatures = json_object_new_array(); + size_t l_block_signs = dap_chain_block_get_signs_count(l_block, a_atom_size); + for (uint32_t i = 0; i < l_block_signs; i++) { + json_object* json_obj_sign = json_object_new_object(); + dap_sign_t * l_sign = dap_chain_block_sign_get(l_block, dap_chain_block_get_size(l_block), i); + size_t l_sign_size = dap_sign_get_size(l_sign); + dap_chain_hash_fast_t l_pkey_hash; + dap_sign_get_pkey_hash(l_sign, &l_pkey_hash); + const char *l_hash_str = !dap_strcmp(a_hash_out_type, "base58") ? + dap_enc_base58_encode_hash_to_str_static(&l_pkey_hash) : + dap_chain_hash_fast_to_str_static(&l_pkey_hash); + json_object_object_add(json_obj_sign, "type",json_object_new_string(dap_sign_type_to_str( l_sign->header.type ))); + json_object_object_add(json_obj_sign, "size",json_object_new_uint64(l_sign_size)); + json_object_object_add(json_obj_sign, "pkey_hash",json_object_new_string(l_hash_str)); + json_object_array_add(l_jobj_signatures, json_obj_sign); + } + json_object_object_add(l_obj_ret, "signatures", l_jobj_signatures); + return l_obj_ret; +} + /** * @brief s_callback_atom_get_datum * @param a_event @@ -2165,6 +2278,7 @@ static dap_chain_atom_ptr_t s_callback_atom_iter_get(dap_chain_atom_iter_t *a_at a_atom_iter->cur_size = l_item->block_size; a_atom_iter->cur_hash = &l_item->block_hash; a_atom_iter->cur_num = l_item->block_number; + a_atom_iter->cur_ts = l_item->ts_created; } else *a_atom_iter = (dap_chain_atom_iter_t) { .chain = a_atom_iter->chain, .cell_id = a_atom_iter->cell_id }; diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c index 45e5125c520478c01697efbd28a8b959b8db99ee..6263a75ab810841623091b007b14949efcba917a 100644 --- a/modules/type/dag/dap_chain_cs_dag.c +++ b/modules/type/dag/dap_chain_cs_dag.c @@ -135,6 +135,7 @@ static uint64_t s_dap_chain_callback_get_count_tx(dap_chain_t *a_chain); static dap_list_t *s_dap_chain_callback_get_txs(dap_chain_t *a_chain, size_t a_count, size_t a_page, bool a_reverse); static uint64_t s_dap_chain_callback_get_count_atom(dap_chain_t *a_chain); +static json_object *s_dap_chain_callback_atom_to_json(json_object **a_arr_out, dap_chain_t *a_chain, dap_chain_atom_ptr_t a_atom, size_t a_atom_size, const char *a_hash_out_type); static dap_list_t *s_callback_get_atoms(dap_chain_t *a_chain, size_t a_count, size_t a_page, bool a_reverse); static bool s_seed_mode = false, s_debug_more = false, s_threshold_enabled = false; @@ -246,6 +247,7 @@ static int s_chain_cs_dag_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg) a_chain->callback_count_atom = s_dap_chain_callback_get_count_atom; // Get atom list in chain a_chain->callback_get_atoms = s_callback_get_atoms; + a_chain->callback_atom_dump_json = s_dap_chain_callback_atom_to_json; // Others a_chain->_inheritor = l_dag; @@ -1117,6 +1119,7 @@ static dap_chain_atom_ptr_t s_chain_callback_atom_iter_get(dap_chain_atom_iter_t a_atom_iter->cur_size = l_item->event_size; a_atom_iter->cur_hash = &l_item->hash; a_atom_iter->cur_num = l_item->event_number; + a_atom_iter->cur_ts = l_item->ts_created; } else *a_atom_iter = (dap_chain_atom_iter_t) { .chain = a_atom_iter->chain, .cell_id = a_atom_iter->cell_id }; @@ -2004,3 +2007,60 @@ static dap_list_t *s_callback_get_atoms(dap_chain_t *a_chain, size_t a_count, si pthread_mutex_unlock(&PVT(l_dag)->events_mutex); return l_list; } + + +static json_object *s_dap_chain_callback_atom_to_json(json_object **a_arr_out, dap_chain_t *a_chain, dap_chain_atom_ptr_t a_atom, size_t a_atom_size, const char *a_hash_out_type){ + json_object *l_jobj = json_object_new_object(); + dap_chain_cs_dag_event_t *l_event = (dap_chain_cs_dag_event_t*)a_atom; + char l_buf[150] = {'\0'}; + // Header + sprintf(l_buf,"%hu",l_event->header.version); + json_object_object_add(l_jobj,"version", json_object_new_string(l_buf)); + json_object_object_add(l_jobj,"round ID", json_object_new_uint64(l_event->header.round_id)); + sprintf(l_buf,"0x%016"DAP_UINT64_FORMAT_x"",l_event->header.cell_id.uint64); + json_object_object_add(l_jobj,"cell_id", json_object_new_string(l_buf)); + sprintf(l_buf,"0x%016"DAP_UINT64_FORMAT_x"",l_event->header.chain_id.uint64); + json_object_object_add(l_jobj,"chain_id", json_object_new_string(l_buf)); + dap_time_to_str_rfc822(l_buf, DAP_TIME_STR_SIZE, l_event->header.ts_created); + json_object_object_add(l_jobj,"ts_created", json_object_new_string(l_buf)); + // Hash links + json_object *l_jobj_hash_links = json_object_new_array(); + for (uint16_t i=0; i < l_event->header.hash_count; i++){ + dap_chain_hash_fast_t * l_hash = (dap_chain_hash_fast_t *) (l_event->hashes_n_datum_n_signs + i*sizeof (dap_chain_hash_fast_t)); + const char *l_hash_str = !dap_strcmp(a_hash_out_type, "base58") ? + dap_enc_base58_encode_hash_to_str_static(l_hash) : + dap_hash_fast_to_str_static(l_hash); + json_object_array_add(l_jobj_hash_links, json_object_new_string(l_hash_str)); + } + json_object_object_add(l_jobj, "hash_links", l_jobj_hash_links); + size_t l_offset = l_event->header.hash_count*sizeof (dap_chain_hash_fast_t); + // Nested datum + dap_chain_datum_t * l_datum = (dap_chain_datum_t*) (l_event->hashes_n_datum_n_signs + l_offset); + const char *l_datum_type = NULL; + DAP_DATUM_TYPE_STR(l_datum->header.type_id, l_datum_type) + json_object_object_add(l_jobj, "datum_type", json_object_new_string(l_datum_type)); + dap_chain_datum_dump_json(*a_arr_out, l_jobj, l_datum, a_hash_out_type, a_chain->net_id); + json_object *l_jobj_signatures = json_object_new_array(); + l_offset += dap_chain_datum_size(l_datum); + // Signatures + while (l_offset + sizeof (l_event->header) < a_atom_size ){ + json_object *l_jobj_signature = json_object_new_object(); + dap_sign_t * l_sign =(dap_sign_t *) (l_event->hashes_n_datum_n_signs +l_offset); + size_t l_sign_size = dap_sign_get_size(l_sign); + if (l_sign_size == 0 ){ + dap_json_rpc_error_add(*a_arr_out, DAP_CHAIN_NODE_CLI_COM_DAG_SIGN_ERR," wrong sign size 0, stop parsing headers"); + break; + } + dap_chain_hash_fast_t l_pkey_hash; + dap_sign_get_pkey_hash(l_sign, &l_pkey_hash); + const char *l_hash_str = dap_strcmp(a_hash_out_type, "hex") + ? dap_enc_base58_encode_hash_to_str_static(&l_pkey_hash) + : dap_chain_hash_fast_to_str_static(&l_pkey_hash); + json_object_object_add(l_jobj_signature,"type", json_object_new_string(dap_sign_type_to_str( l_sign->header.type ))); + json_object_object_add(l_jobj_signature,"pkey_hash", json_object_new_string(l_hash_str)); + json_object_array_add(l_jobj_signatures, l_jobj_signature); + l_offset += l_sign_size; + } + json_object_object_add(l_jobj, "signatures", l_jobj_signatures); + return l_jobj; +} diff --git a/modules/type/none/dap_chain_cs_none.c b/modules/type/none/dap_chain_cs_none.c index 046eeef125ac5167411d904dd0247bb6f8d23145..fc3c037ecd583e850c94f6e44883d21e01e39947 100644 --- a/modules/type/none/dap_chain_cs_none.c +++ b/modules/type/none/dap_chain_cs_none.c @@ -72,6 +72,8 @@ static void s_nonconsensus_callback_atom_iter_delete(dap_chain_atom_iter_t * a_a static dap_chain_atom_ptr_t s_nonconsensus_callback_atom_iter_find_by_hash(dap_chain_atom_iter_t * a_atom_iter, dap_chain_hash_fast_t * a_atom_hash, size_t * a_atom_size); +static json_object *s_nonconsensus_callback_atom_to_json(json_object **a_arr_out, dap_chain_t *a_chain, dap_chain_atom_ptr_t a_atom, size_t a_atom_size, const char *a_hash_out_type); + // Get event(s) from gdb static dap_chain_atom_ptr_t s_nonconsensus_callback_atom_iter_get(dap_chain_atom_iter_t *a_atom_iter, dap_chain_iter_op_t a_operation, size_t *a_atom_size); static dap_chain_atom_ptr_t *s_nonconsensus_callback_atom_iter_get_links(dap_chain_atom_iter_t *a_atom_iter, size_t *a_links_size_ptr, size_t **a_lasts_sizes_ptr); // Get list of linked events @@ -190,6 +192,7 @@ static int s_cs_callback_new(dap_chain_t *a_chain, dap_config_t UNUSED_ARG *a_ch a_chain->callback_atom_iter_delete = s_nonconsensus_callback_atom_iter_delete; a_chain->callback_atom_iter_get = s_nonconsensus_callback_atom_iter_get; // Linear pass through a_chain->callback_atom_find_by_hash = s_nonconsensus_callback_atom_iter_find_by_hash; + a_chain->callback_atom_dump_json = s_nonconsensus_callback_atom_to_json; a_chain->callback_atom_iter_get_links = s_nonconsensus_callback_atom_iter_get_links; // Get the next element from chain from the current one @@ -428,6 +431,23 @@ static dap_chain_atom_ptr_t s_nonconsensus_callback_atom_iter_find_by_hash(dap_c return l_ret; } + +/** + * @brief Serializes dap_chain_atom_ptr in none consensus to JSON + * @param a_chain + * @param a_atom + * @param a_atom_size + * @param a_hash_out_type + * @return + */ +static json_object *s_nonconsensus_callback_atom_to_json(json_object **a_arr_out, dap_chain_t *a_chain, dap_chain_atom_ptr_t a_atom, size_t a_atom_size, const char *a_hash_out_type) +{ + json_object *obj_ret = json_object_new_object(); + dap_chain_datum_t *l_datum = (dap_chain_datum_t*)a_atom; + dap_chain_datum_dump_json(*a_arr_out, obj_ret, l_datum, a_hash_out_type, a_chain->net_id); + return obj_ret; +} + /** * @brief Get the first dag event from database *