diff --git a/dap-sdk b/dap-sdk index 90e987710ed420a624be5619dc0d813b25947d9b..628e8fd05782d701bb1be115d3b5ba8268ee8fa6 160000 --- a/dap-sdk +++ b/dap-sdk @@ -1 +1 @@ -Subproject commit 90e987710ed420a624be5619dc0d813b25947d9b +Subproject commit 628e8fd05782d701bb1be115d3b5ba8268ee8fa6 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/consensus/esbocs/dap_chain_cs_esbocs.c b/modules/consensus/esbocs/dap_chain_cs_esbocs.c index 80b293580fb91af5c88f0a4455208fe27031fa1e..653f59ec2e54591e6e0ecf315809cb8a74115085 100644 --- a/modules/consensus/esbocs/dap_chain_cs_esbocs.c +++ b/modules/consensus/esbocs/dap_chain_cs_esbocs.c @@ -130,7 +130,6 @@ struct precached_key { uint64_t frequency; dap_hash_fast_t pkey_hash; size_t pkey_size; - struct precached_key *prev, *next; byte_t sign_pkey[]; }; @@ -162,7 +161,7 @@ typedef struct dap_chain_esbocs_pvt { uint16_t min_validators_count; bool check_signs_structure; // Internal cache - struct precached_key *precached_keys; + dap_list_t *precached_keys; } dap_chain_esbocs_pvt_t; #define PVT(a) ((dap_chain_esbocs_pvt_t *)a->_pvt) @@ -2769,11 +2768,13 @@ static size_t s_callback_block_sign(dap_chain_cs_blocks_t *a_blocks, dap_chain_b return dap_chain_block_sign_add(a_block_ptr, a_block_size, l_esbocs_pvt->blocks_sign_key); } -static uint64_t s_get_precached_key_hash(struct precached_key **a_precached_keys_list, dap_sign_t *a_source_sign, dap_hash_fast_t *a_result) +static uint64_t s_get_precached_key_hash(dap_list_t **a_precached_keys_list, dap_sign_t *a_source_sign, dap_hash_fast_t *a_result) { bool l_found = false; struct precached_key *l_key = NULL; - DL_FOREACH(*a_precached_keys_list, l_key) { + dap_list_t *l_cur; + for (l_cur = *a_precached_keys_list; l_cur; l_cur = l_cur->next) { + l_key = (struct precached_key*)l_cur->data; if (l_key->pkey_size == a_source_sign->header.sign_pkey_size && !memcmp(l_key->sign_pkey, dap_sign_get_pkey(a_source_sign, NULL), l_key->pkey_size)) { l_found = true; @@ -2782,31 +2783,28 @@ static uint64_t s_get_precached_key_hash(struct precached_key **a_precached_keys } } if (l_found) { - struct precached_key *l_key_swap = NULL; - DL_FOREACH(*a_precached_keys_list, l_key_swap) { - if (l_key_swap == l_key) - break; - if (l_key_swap->frequency < l_key->frequency) { - struct precached_key *l_swapper = l_key->next; - l_key->next = l_key_swap->next; - l_key_swap->next = l_swapper; - l_swapper = l_key->prev; - l_key->prev = l_key_swap->prev; - l_key_swap->prev = l_swapper; - break; - } - } if (a_result) *a_result = l_key->pkey_hash; - return l_key->frequency; + uint64_t l_freq = l_key->frequency; + while (l_cur != *a_precached_keys_list) { + struct precached_key* l_prev_key = (struct precached_key*)l_cur->prev->data; + if (l_key->frequency > l_prev_key->frequency) { + l_cur->prev->data = l_cur->data; + l_cur->data = l_prev_key; + l_key = l_prev_key; + l_cur = l_cur->prev; + } else + break; + } + return l_freq; } - struct precached_key *l_key_new = DAP_NEW_SIZE(struct precached_key, + struct precached_key *l_key_new = DAP_NEW_Z_SIZE(struct precached_key, sizeof(struct precached_key) + a_source_sign->header.sign_pkey_size); l_key_new->pkey_size = a_source_sign->header.sign_pkey_size; l_key_new->frequency = 0; memcpy(l_key_new->sign_pkey, dap_sign_get_pkey(a_source_sign, NULL), l_key_new->pkey_size); dap_sign_get_pkey_hash(a_source_sign, &l_key_new->pkey_hash); - DL_APPEND(*a_precached_keys_list, l_key_new); + *a_precached_keys_list = dap_list_append(*a_precached_keys_list, l_key_new); if (a_result) *a_result = l_key_new->pkey_hash; return 0; diff --git a/modules/net/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c index 144b69959c5047e5a094f0ae115207ce73ad769b..383f3ec95e042098793f7e05932e31d5cf296163 100644 --- a/modules/net/dap_chain_ledger.c +++ b/modules/net/dap_chain_ledger.c @@ -625,14 +625,14 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain l_tsd = (dap_tsd_t *)((byte_t *)l_tsd + l_tsd_size); l_tsd_size = dap_tsd_size(l_tsd); if (l_offset + l_tsd_size > a_tsd_total_size || l_offset + l_tsd_size < l_offset) { - log_it(L_WARNING, "Wrong TSD size %zu, exiting TSD parse", l_tsd_size); + log_it(L_WARNING, "Wrong TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size); return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE); } switch (l_tsd->type) { // set flags case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_SET_FLAGS: { if (l_tsd->size != sizeof(uint16_t)) { - log_it(L_WARNING, "Wrong SET_FLAGS TSD size %zu, exiting TSD parse", l_tsd_size); + log_it(L_WARNING, "Wrong SET_FLAGS TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size); return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE); } if (!a_apply) @@ -643,7 +643,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain // unset flags case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_UNSET_FLAGS: { if (l_tsd->size != sizeof(uint16_t)) { - log_it(L_WARNING, "Wrong UNSET_FLAGS TSD size %zu, exiting TSD parse", l_tsd_size); + log_it(L_WARNING, "Wrong UNSET_FLAGS TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size); return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE); } if (!a_apply) @@ -654,7 +654,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain // set total supply case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SUPPLY: { // 256 if (l_tsd->size != sizeof(uint256_t)) { - log_it(L_WARNING, "Wrong TOTAL_SUPPLY TSD size %zu, exiting TSD parse", l_tsd_size); + log_it(L_WARNING, "Wrong TOTAL_SUPPLY TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size); return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE); } if (!a_item_apply_to) { @@ -675,7 +675,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain // Allowed tx receiver addres list add, remove or clear case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_ADD: { if (l_tsd->size != sizeof(dap_chain_addr_t)) { - log_it(L_WARNING, "Wrong TX_RECEIVER_ALLOWED_ADD TSD size %zu, exiting TSD parse", l_tsd_size); + log_it(L_WARNING, "Wrong TX_RECEIVER_ALLOWED_ADD TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size); return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE); } // Check if its correct @@ -714,7 +714,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_REMOVE: { if (l_tsd->size != sizeof(dap_chain_addr_t)) { - log_it(L_WARNING, "Wrong TX_RECEIVER_ALLOWED_REMOVE TSD size %zu, exiting TSD parse", l_tsd_size); + log_it(L_WARNING, "Wrong TX_RECEIVER_ALLOWED_REMOVE TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size); return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE); } // Check if its correct @@ -757,7 +757,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_CLEAR: { if (l_tsd->size != 0) { - log_it(L_WARNING, "Wrong TX_RECEIVER_ALLOWED_CLEAR TSD size %zu, exiting TSD parse", l_tsd_size); + log_it(L_WARNING, "Wrong TX_RECEIVER_ALLOWED_CLEAR TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size); return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE); } DAP_DEL_Z(l_new_tx_recv_allow); @@ -768,7 +768,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain // Blocked tx receiver addres list add, remove or clear case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_ADD: { if (l_tsd->size != sizeof(dap_chain_addr_t)) { - log_it(L_WARNING, "Wrong TX_RECEIVER_BLOCKED_ADD TSD size %zu, exiting TSD parse", l_tsd_size); + log_it(L_WARNING, "Wrong TX_RECEIVER_BLOCKED_ADD TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size); return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE); } // Check if its correct @@ -807,7 +807,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_REMOVE: { if (l_tsd->size != sizeof(dap_chain_addr_t)) { - log_it(L_WARNING, "Wrong TX_RECEIVER_BLOCKED_REMOVE TSD size %zu, exiting TSD parse", l_tsd_size); + log_it(L_WARNING, "Wrong TX_RECEIVER_BLOCKED_REMOVE TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size); return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE); } // Check if its correct @@ -850,7 +850,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_CLEAR: { if (l_tsd->size != 0) { - log_it(L_WARNING, "Wrong TX_RECEIVER_BLOCKED_CLEAR TSD size %zu, exiting TSD parse", l_tsd_size); + log_it(L_WARNING, "Wrong TX_RECEIVER_BLOCKED_CLEAR TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size); return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE); } DAP_DEL_Z(l_new_tx_recv_block); @@ -861,7 +861,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain // Blocked tx sender addres list add, remove or clear case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD: { if (l_tsd->size != sizeof(dap_chain_addr_t)) { - log_it(L_WARNING, "Wrong TX_SENDER_ALLOWED_ADD TSD size %zu, exiting TSD parse", l_tsd_size); + log_it(L_WARNING, "Wrong TX_SENDER_ALLOWED_ADD TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size); return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE); } // Check if its correct @@ -900,7 +900,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_REMOVE: { if (l_tsd->size != sizeof(dap_chain_addr_t)) { - log_it(L_WARNING, "Wrong TX_SENDER_ALLOWED_REMOVE TSD size %zu, exiting TSD parse", l_tsd_size); + log_it(L_WARNING, "Wrong TX_SENDER_ALLOWED_REMOVE TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size); return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE); } // Check if its correct @@ -944,7 +944,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_CLEAR: { if (l_tsd->size != 0) { - log_it(L_WARNING, "Wrong TX_SENDER_ALLOWED_CLEAR TSD size %zu, exiting TSD parse", l_tsd_size); + log_it(L_WARNING, "Wrong TX_SENDER_ALLOWED_CLEAR TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size); return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE); } DAP_DEL_Z(l_new_tx_send_allow); @@ -955,7 +955,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain // Blocked tx sender addres list add, remove or clear case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_ADD: { if (l_tsd->size != sizeof(dap_chain_addr_t)) { - log_it(L_WARNING, "Wrong TX_SENDER_BLOCKED_ADD TSD size %zu, exiting TSD parse", l_tsd_size); + log_it(L_WARNING, "Wrong TX_SENDER_BLOCKED_ADD TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size); return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE); } // Check if its correct @@ -996,7 +996,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_REMOVE: { if (l_tsd->size != sizeof(dap_chain_addr_t)) { - log_it(L_WARNING, "Wrong TX_SENDER_BLOCKED_REMOVE TSD size %zu, exiting TSD parse", l_tsd_size); + log_it(L_WARNING, "Wrong TX_SENDER_BLOCKED_REMOVE TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size); return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE); } // Check if its correct @@ -1039,7 +1039,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_CLEAR: { if (l_tsd->size != 0) { - log_it(L_WARNING, "Wrong TX_SENDER_BLOCKED_CLEAR TSD size %zu, exiting TSD parse", l_tsd_size); + log_it(L_WARNING, "Wrong TX_SENDER_BLOCKED_CLEAR TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size); return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE); } DAP_DEL_Z(l_new_tx_send_block); @@ -1049,7 +1049,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain case DAP_CHAIN_DATUM_TOKEN_TSD_TOKEN_DESCRIPTION: { if (l_tsd->size == 0 || l_tsd->data[l_tsd->size - 1] != 0) { - log_it(L_ERROR, "Wrong TOKEN_DESCRIPTION TSD format or size %zu, exiting TSD parse", l_tsd_size); + log_it(L_ERROR, "Wrong TOKEN_DESCRIPTION TSD format or size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size); return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE); } if (!a_apply) @@ -1061,7 +1061,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain // Set signs count value need to emission be valid case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SIGNS_VALID: { if (l_tsd->size != sizeof(uint16_t)) { - log_it(L_WARNING, "Wrong SIGNS_VALID TSD size %zu, exiting TSD parse", l_tsd_size); + log_it(L_WARNING, "Wrong SIGNS_VALID TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size); return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE); } l_new_signs_valid = dap_tsd_get_scalar(l_tsd, uint16_t); @@ -1069,7 +1069,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_ADD: { if (l_tsd->size < sizeof(dap_pkey_t) || l_tsd->size != dap_pkey_get_size((dap_pkey_t *)l_tsd->data)) { - log_it(L_WARNING, "Wrong TOTAL_PKEYS_ADD TSD size %zu, exiting TSD parse", l_tsd_size); + log_it(L_WARNING, "Wrong TOTAL_PKEYS_ADD TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size); return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE); } if (!l_new_pkeys && l_new_signs_total && !l_was_pkeys_copied) { @@ -1142,7 +1142,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_REMOVE: { if (l_tsd->size != sizeof(dap_hash_t)) { - log_it(L_WARNING, "Wrong TOTAL_PKEYS_REMOVE TSD size %zu, exiting TSD parse", l_tsd_size); + log_it(L_WARNING, "Wrong TOTAL_PKEYS_REMOVE TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size); return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE); } if (!l_new_pkeys && l_new_signs_total && !l_was_pkeys_copied) { @@ -1201,7 +1201,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain } if (l_tsd->size != sizeof(dap_chain_datum_token_tsd_delegate_from_stake_lock_t) && l_tsd->size != sizeof(dap_chain_datum_token_tsd_delegate_from_stake_lock_t) + 256 /* Legacy size */) { - log_it(L_WARNING, "Wrong DELEGATE_EMISSION_FROM_STAKE_LOCK TSD size %zu, exiting TSD parse", l_tsd_size); + log_it(L_WARNING, "Wrong DELEGATE_EMISSION_FROM_STAKE_LOCK TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size); return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE); } dap_chain_datum_token_tsd_delegate_from_stake_lock_t *l_delegate = dap_tsd_get_object(l_tsd, dap_chain_datum_token_tsd_delegate_from_stake_lock_t); @@ -1410,21 +1410,21 @@ int s_token_add_check(dap_ledger_t *a_ledger, byte_t *a_token, size_t a_token_si dap_sign_t *l_sign = (dap_sign_t *)(l_signs_ptr + l_signs_size); if (l_signs_offset + l_signs_size + sizeof(dap_sign_t) > l_token_size || l_signs_offset + l_signs_size + sizeof(dap_sign_t) < l_signs_offset) { - log_it(L_WARNING, "Incorrect size %zu of datum token, expected at least %zu", l_token_size, + log_it(L_WARNING, "Incorrect size %"DAP_UINT64_FORMAT_U" of datum token, expected at least %zu", l_token_size, l_signs_offset + l_signs_size + sizeof(dap_sign_t)); DAP_DELETE(l_token); return DAP_LEDGER_CHECK_INVALID_SIZE; } uint64_t l_sign_size = dap_sign_get_size(l_sign); if (!l_sign_size || l_sign_size + l_signs_size < l_signs_size) { - log_it(L_WARNING, "Incorrect size %zu of datum token sign", l_sign_size); + log_it(L_WARNING, "Incorrect size %"DAP_UINT64_FORMAT_U" of datum token sign", l_sign_size); DAP_DELETE(l_token); return DAP_LEDGER_CHECK_INVALID_SIZE; } l_signs_size += l_sign_size; } if (l_token_size != l_signs_offset + l_signs_size) { - log_it(L_WARNING, "Incorrect size %zu of datum token, expected %zu", l_token_size, l_signs_offset + l_signs_size); + log_it(L_WARNING, "Incorrect size %"DAP_UINT64_FORMAT_U" of datum token, expected %zu", l_token_size, l_signs_offset + l_signs_size); DAP_DELETE(l_token); return DAP_LEDGER_CHECK_INVALID_SIZE; } diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c index f96876ca0c123643f522706371c5c3aef96b8354..da8ffae15f4b4d66f531bfdead3345f396a8e072 100644 --- a/modules/net/dap_chain_net.c +++ b/modules/net/dap_chain_net.c @@ -107,6 +107,7 @@ #include "dap_stream_cluster.h" #include "dap_http_ban_list_client.h" #include "dap_net.h" +#include "dap_context.h" #include <stdio.h> #include <sys/types.h> @@ -154,16 +155,18 @@ typedef struct dap_chain_net_pvt{ dap_chain_node_info_t *node_info; // Current node's info dap_balancer_type_t balancer_type; - bool load_mode; - uint16_t permanent_links_count; - dap_link_info_t **permanent_links; + uint16_t permanent_links_addrs_count; + dap_stream_node_addr_t *permanent_links_addrs; + uint16_t permanent_links_hosts_count; + struct request_link_info **permanent_links_hosts; + uint16_t authorized_nodes_count; dap_stream_node_addr_t *authorized_nodes_addrs; uint16_t seed_nodes_count; - struct request_link_info **seed_nodes_info; + struct request_link_info **seed_nodes_hosts; struct chain_sync_context sync_context; @@ -188,11 +191,9 @@ typedef struct dap_chain_net_pvt{ #define PVT_S(a) ((dap_chain_net_pvt_t *)a.pvt) static dap_chain_net_t *s_nets_by_name = NULL, *s_nets_by_id = NULL; -static pthread_mutex_t s_net_cond_lock = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t s_net_cond = PTHREAD_COND_INITIALIZER; -static uint16_t s_net_loading_count = 0; static const char *c_net_states[] = { + [NET_STATE_LOADING] = "NET_STATE_LOADING", [NET_STATE_OFFLINE] = "NET_STATE_OFFLINE", [NET_STATE_LINKS_PREPARE ] = "NET_STATE_LINKS_PREPARE", [NET_STATE_LINKS_CONNECTING] = "NET_STATE_LINKS_CONNECTING", @@ -202,7 +203,7 @@ static const char *c_net_states[] = { }; static inline const char * dap_chain_net_state_to_str(dap_chain_net_state_t a_state) { - return a_state < NET_STATE_OFFLINE || a_state > NET_STATE_ONLINE ? "NET_STATE_INVALID" : c_net_states[a_state]; + return a_state < NET_STATE_LOADING || a_state > NET_STATE_ONLINE ? "NET_STATE_INVALID" : c_net_states[a_state]; } // Node link callbacks @@ -226,7 +227,7 @@ static void s_net_states_notify(dap_chain_net_t * l_net); static void s_nodelist_change_notify(dap_store_obj_t *a_obj, void *a_arg); //static void s_net_proc_kill( dap_chain_net_t * a_net ); static int s_net_init(const char *a_net_name, const char *a_path, uint16_t a_acl_idx); -static bool s_net_load(void *a_arg); +static void *s_net_load(void *a_arg); static int s_net_try_online(dap_chain_net_t *a_net); static int s_cli_net(int argc, char ** argv, void **a_str_reply); static uint8_t *s_net_set_acl(dap_chain_hash_fast_t *a_pkey_hash); @@ -353,12 +354,12 @@ static struct request_link_info *s_balancer_link_from_cfg(dap_chain_net_t *a_net l_idx = dap_random_uint16() % PVT(a_net)->seed_nodes_count; break; } - if ( !PVT(a_net)->seed_nodes_info[l_idx] ) { + if ( !PVT(a_net)->seed_nodes_hosts[l_idx] ) { // Unresolved before? Let's try again const char **l_seed_nodes_hosts = dap_config_get_array_str(a_net->pub.config, "general", "seed_nodes_hosts", NULL); - PVT(a_net)->seed_nodes_info[l_idx] = s_net_resolve_host(l_seed_nodes_hosts[l_idx]); + PVT(a_net)->seed_nodes_hosts[l_idx] = s_net_resolve_host(l_seed_nodes_hosts[l_idx]); } - return PVT(a_net)->seed_nodes_info[l_idx]; + return PVT(a_net)->seed_nodes_hosts[l_idx]; } dap_chain_node_info_t *dap_chain_net_get_my_node_info(dap_chain_net_t *a_net) @@ -435,8 +436,8 @@ static void s_link_manager_callback_connected(dap_link_t *a_link, uint64_t a_net static bool s_net_check_link_is_permanent(dap_chain_net_t *a_net, dap_stream_node_addr_t a_addr) { dap_chain_net_pvt_t *l_net_pvt = PVT(a_net); - for (uint16_t i = 0; i < l_net_pvt->permanent_links_count; i++) { - if (l_net_pvt->permanent_links[i]->node_addr.uint64 == a_addr.uint64) + for (uint16_t i = 0; i < l_net_pvt->permanent_links_addrs_count; i++) { + if (l_net_pvt->permanent_links_addrs[i].uint64 == a_addr.uint64) return true; } return false; @@ -521,23 +522,47 @@ int s_link_manager_link_request(uint64_t a_net_id) return dap_worker_exec_callback_on(dap_worker_get_auto(), dap_chain_net_balancer_request, l_arg), 0; } +struct request_link_info *s_get_permanent_link_info(dap_chain_net_t *a_net, dap_chain_node_addr_t *a_address) +{ + dap_chain_net_pvt_t *l_net_pvt = PVT(a_net); + for (uint16_t i = 0; i < l_net_pvt->permanent_links_addrs_count; ++i) { + if (l_net_pvt->permanent_links_addrs[i].uint64 == a_address->uint64 && + i < l_net_pvt->permanent_links_hosts_count && + i < l_net_pvt->permanent_links_hosts[i]->addr[0] && + i < l_net_pvt->permanent_links_hosts[i]->port) + return l_net_pvt->permanent_links_hosts[i]; + } + return NULL; +} + int s_link_manager_fill_net_info(dap_link_t *a_link) { // sanity check dap_return_val_if_pass(!a_link, -1); // func work - dap_chain_node_info_t *l_node_info = NULL; - for (dap_chain_net_t *net = s_nets_by_name; net; net = net->hh.next) { - if (( l_node_info = dap_chain_node_info_read(net, &a_link->addr) )) + const char *l_host = NULL; + uint16_t l_port = 0; + struct request_link_info *l_permanent_link = NULL; + for (dap_chain_net_t *l_net = s_nets_by_name; l_net; l_net = l_net->hh.next) { + if ( dap_chain_net_get_state(l_net) > NET_STATE_OFFLINE && ( l_permanent_link = s_get_permanent_link_info(l_net, &a_link->addr) )) { + l_host = l_permanent_link->addr; + l_port = l_permanent_link->port; break; + } } - if (!l_node_info) - return -3; - a_link->uplink.ready = true; - if ( dap_link_manager_link_update(&a_link->addr, l_node_info->ext_host, l_node_info->ext_port) ) - a_link->uplink.ready = true; - DAP_DELETE(l_node_info); - return 0; + dap_chain_node_info_t *l_node_info = NULL; + if (!l_host || !l_host[0] || !l_port) { + for (dap_chain_net_t *net = s_nets_by_name; net; net = net->hh.next) { + if (( l_node_info = dap_chain_node_info_read(net, &a_link->addr) )) + break; + } + if (!l_node_info) + return -3; + l_host = l_node_info->ext_host; + l_port = l_node_info->ext_port; + } + a_link->uplink.ready = !dap_link_manager_link_update(&a_link->addr, l_host, l_port); + return DAP_DELETE(l_node_info), 0; } json_object *s_net_sync_status(dap_chain_net_t *a_net) @@ -569,7 +594,11 @@ json_object *s_net_sync_status(dap_chain_net_t *a_net) l_jobj_chain_status = json_object_new_string("unknown"); break; } - if (l_chain->state == CHAIN_SYNC_STATE_IDLE) { + if (dap_chain_net_get_load_mode(a_net)) { + char *l_percent_str = dap_strdup_printf("%d %c", l_chain->load_progress, '%'); + l_jobj_percent = json_object_new_string(l_percent_str); + DAP_DELETE(l_percent_str); + } else if (l_chain->state == CHAIN_SYNC_STATE_IDLE) { l_jobj_percent = json_object_new_string(" - %"); } else { double l_percent = dap_min((double)l_chain->callback_count_atom(l_chain) * 100 / l_chain->atom_num_last, 100.0); @@ -647,6 +676,9 @@ static dap_chain_net_t *s_net_new(const char *a_net_name, dap_config_t *a_cfg) *a_native_ticker= dap_config_get_item_str(a_cfg, "general", "native_ticker"); dap_chain_net_id_t l_net_id; + if(!a_node_role) + return log_it(L_ERROR, "Can't create l_net, can't read node role config"), NULL; + if(!l_net_name_str || !l_net_id_str || dap_chain_net_id_parse(l_net_id_str, &l_net_id)) return log_it(L_ERROR, "Can't create l_net, can't read name or ID config"), NULL; @@ -730,30 +762,28 @@ bool s_net_disk_load_notify_callback(UNUSED_ARG void *a_arg) { */ void dap_chain_net_load_all() { - pthread_mutex_lock(&s_net_cond_lock); - s_net_loading_count = HASH_COUNT(s_nets_by_name); - if (!s_net_loading_count) { - log_it(L_ERROR, "Can't find any nets"); - pthread_mutex_unlock(&s_net_cond_lock); - return; - } + uint16_t l_nets_count = HASH_COUNT(s_nets_by_name); + if (!l_nets_count) + return log_it(L_ERROR, "No networks initialized!"); + pthread_t l_tids[l_nets_count]; + dap_chain_net_t *l_net = s_nets_by_name; dap_timerfd_t *l_load_notify_timer = dap_timerfd_start(5000, (dap_timerfd_callback_t)s_net_disk_load_notify_callback, NULL); - for (dap_chain_net_t *net = s_nets_by_name; net; net = net->hh.next) - dap_proc_thread_callback_add(NULL, s_net_load, net); - while (s_net_loading_count) - pthread_cond_wait(&s_net_cond, &s_net_cond_lock); - pthread_mutex_unlock(&s_net_cond_lock); + for (int i = 0; i < l_nets_count; ++i) { + pthread_create(&l_tids[i], NULL, s_net_load, l_net); + l_net = l_net->hh.next; + } + for (int i = 0; i < l_nets_count; ++i) { + pthread_join(l_tids[i], NULL); + } dap_timerfd_delete_mt(l_load_notify_timer->worker, l_load_notify_timer->esocket_uuid); } dap_string_t* dap_cli_list_net() { dap_string_t *l_string_ret = dap_string_new(""); - unsigned l_net_i = 0; dap_string_append(l_string_ret, "Available networks and chains:\n"); for (dap_chain_net_t *net = s_nets_by_name; net; net = net->hh.next) { dap_string_append_printf(l_string_ret, "\t%s:\n", net->pub.name); - ++l_net_i; dap_chain_t *l_chain = net->pub.chains; while (l_chain) { dap_string_append_printf( l_string_ret, "\t\t%s\n", l_chain->name ); @@ -815,8 +845,7 @@ void s_set_reply_text_node_status(void **a_str_reply, dap_chain_net_t * a_net){ char* l_sync_current_link_text_block = NULL; if (PVT(a_net)->state != NET_STATE_OFFLINE) l_sync_current_link_text_block = dap_strdup_printf(", active links %zu from %u", - dap_link_manager_links_count(a_net->pub.id.uint64), - 0 /*HASH_COUNT(PVT(a_net)->net_links)*/); + dap_link_manager_links_count(a_net->pub.id.uint64), 0); dap_cli_server_cmd_set_reply_text(a_str_reply, "Network \"%s\" has state %s (target state %s)%s%s", a_net->pub.name, c_net_states[PVT(a_net)->state], @@ -1236,7 +1265,12 @@ static int s_cli_net(int argc, char **argv, void **reply) return DAP_JSON_RPC_ERR_CODE_MEMORY_ALLOCATED; } json_object_object_add(l_jobj_return, "to", l_jobj_to); - dap_chain_net_state_go_to(l_net, NET_STATE_ONLINE); + if (dap_chain_net_state_go_to(l_net, NET_STATE_ONLINE)) { + json_object_put(l_jobj_return); + dap_json_rpc_error_add(*a_json_arr_reply, DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START, "%s", + "Can't change state of loading network\n"); + return DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START; + } l_ret = DAP_CHAIN_NET_JSON_RPC_OK; } else if ( strcmp(l_go_str,"offline") == 0 ) { json_object *l_jobj_to = json_object_new_string(c_net_states[NET_STATE_OFFLINE]); @@ -1246,7 +1280,12 @@ static int s_cli_net(int argc, char **argv, void **reply) return DAP_JSON_RPC_ERR_CODE_MEMORY_ALLOCATED; } json_object_object_add(l_jobj_return, "to", l_jobj_to); - dap_chain_net_state_go_to(l_net, NET_STATE_OFFLINE); + if ( dap_chain_net_state_go_to(l_net, NET_STATE_OFFLINE) ) { + json_object_put(l_jobj_return); + dap_json_rpc_error_add(*a_json_arr_reply, DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START, "%s", + "Can't change state of loading network\n"); + return DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START; + } l_ret = DAP_CHAIN_NET_JSON_RPC_OK; } else if (strcmp(l_go_str, "sync") == 0) { json_object *l_jobj_to = json_object_new_string("resynchronizing"); @@ -1257,9 +1296,15 @@ static int s_cli_net(int argc, char **argv, void **reply) } json_object_object_add(l_jobj_return, "start", l_jobj_to); if (PVT(l_net)->state_target == NET_STATE_ONLINE) - dap_chain_net_state_go_to(l_net, NET_STATE_ONLINE); + l_ret = dap_chain_net_state_go_to(l_net, NET_STATE_ONLINE); else - dap_chain_net_state_go_to(l_net, NET_STATE_SYNC_CHAINS); + l_ret = dap_chain_net_state_go_to(l_net, NET_STATE_SYNC_CHAINS); + if (l_ret) { + json_object_put(l_jobj_return); + dap_json_rpc_error_add(*a_json_arr_reply, DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START, "%s", + "Can't change state of loading network\n"); + return DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START; + } l_ret = DAP_CHAIN_NET_JSON_RPC_OK; } else { json_object_put(l_jobj_return); @@ -1723,6 +1768,56 @@ int dap_chain_net_test_init() #endif +int s_nodes_addrs_init(dap_config_t *a_cfg, const char *a_addrs_type, dap_stream_node_addr_t **a_addrs, uint16_t *a_addrs_count) +{ + dap_return_val_if_pass(!a_cfg || !a_addrs_type || !a_addrs || !a_addrs_count, -1); + const char **l_nodes_addrs = dap_config_get_array_str(a_cfg, "general", a_addrs_type, a_addrs_count); + if (*a_addrs_count) { + *a_addrs = DAP_NEW_Z_COUNT(dap_chain_node_addr_t, *a_addrs_count); + if (!*a_addrs) { + log_it(L_CRITICAL, "%s", c_error_memory_alloc); + return -1; + } + for (uint16_t i = 0; i < *a_addrs_count; ++i) { + dap_chain_node_addr_t l_addr; + if (dap_stream_node_addr_from_str(&l_addr, l_nodes_addrs[i])) { + log_it(L_ERROR, "Incorrect format of %s address \"%s\", fix net config and restart node", a_addrs_type, l_nodes_addrs[i]); + return -2; + } + (*a_addrs)[i].uint64 = l_addr.uint64; + } + } + return 0; +} + +int s_nodes_hosts_init(dap_chain_net_t *a_net, dap_config_t *a_cfg, const char *a_hosts_type, struct request_link_info ***a_hosts, uint16_t *a_hosts_count) +{ + dap_return_val_if_pass(!a_cfg || !a_hosts_type || !a_hosts || !a_hosts_count, -1); + const char **l_nodes_addrs = dap_config_get_array_str(a_cfg, "general", a_hosts_type, a_hosts_count); + if (*a_hosts_count) { + *a_hosts = DAP_NEW_Z_COUNT(struct request_link_info *, *a_hosts_count); + if (!*a_hosts) { + log_it(L_CRITICAL, "%s", c_error_memory_alloc); + return -1; + } + uint16_t i = 0, e = 0; + for (; i < *a_hosts_count; ++i) { + if (!( (*a_hosts)[i] = s_net_resolve_host(l_nodes_addrs[i]) )) { + log_it(L_ERROR, "Incorrect address [ %s : %u ], fix \"%s\" network config" + "or check internet connection and restart node", + (*a_hosts)[i]->addr, (*a_hosts)[i]->port, a_net->pub.name); + ++e; + continue; + } + } + debug_if(e, L_ERROR, "%d / %d %s links are invalid or can't be accessed, fix \"%s\"" + "network config or check internet connection and restart node", + e, i, a_hosts_type, a_net->pub.name); + + } + return 0; +} + /** * @brief load network config settings from cellframe-node.cfg file * @@ -1741,7 +1836,6 @@ int s_net_init(const char *a_net_name, const char *a_path, uint16_t a_acl_idx) return log_it(L_ERROR,"Can't create net \"%s\"", a_net_name), dap_config_close(l_cfg), -1; dap_chain_net_pvt_t *l_net_pvt = PVT(l_net); - l_net_pvt->load_mode = true; l_net_pvt->acl_idx = a_acl_idx; // Transaction can be sent to bridged networks uint16_t l_net_ids_count = 0; @@ -1762,88 +1856,21 @@ int s_net_init(const char *a_net_name, const char *a_path, uint16_t a_acl_idx) l_net->pub.bridged_networks = DAP_REALLOC_COUNT(l_net->pub.bridged_networks, j); // Can be NULL, it's ok } - const char **l_permanent_nodes_addrs = dap_config_get_array_str(l_cfg, "general", "permanent_nodes_addrs", &l_net_pvt->permanent_links_count); - if (l_net_pvt->permanent_links_count) { - l_net_pvt->permanent_links = DAP_NEW_Z_COUNT(dap_link_info_t *, l_net_pvt->permanent_links_count); - if (!l_net_pvt->permanent_links) { - log_it(L_CRITICAL, "%s", c_error_memory_alloc); - dap_chain_net_delete(l_net); - dap_config_close(l_cfg); - return -4; - } - } - for (uint16_t i = 0; i < l_net_pvt->permanent_links_count; ++i) { - l_net_pvt->permanent_links[i] = DAP_NEW_Z(dap_link_info_t); - if (!l_net_pvt->permanent_links[i]) { - log_it(L_CRITICAL, "%s", c_error_memory_alloc); - dap_chain_net_delete(l_net); - dap_config_close(l_cfg); - return -4; - } - if (dap_stream_node_addr_from_str(&l_net_pvt->permanent_links[i]->node_addr, l_permanent_nodes_addrs[i])) { - log_it(L_ERROR, "Incorrect format of node address \"%s\", fix net config and restart node", l_permanent_nodes_addrs[i]); - dap_chain_net_delete(l_net); - dap_config_close(l_cfg); - return -16; - } - } - uint16_t l_permalink_hosts_count = 0, i, e; - const char **l_permanent_links_hosts = dap_config_get_array_str(l_cfg, "general", "permanent_nodes_hosts", &l_permalink_hosts_count); - for (i = 0, e = 0; i < dap_min(l_permalink_hosts_count, l_net_pvt->permanent_links_count); ++i) { - struct request_link_info *l_tmp = s_net_resolve_host( l_permanent_links_hosts[i] ); - if ( !l_tmp ) { - log_it(L_ERROR, "Incorrect address \"%s\", fix \"%s\" network config" - "or check internet connection and restart node", - a_net_name, l_permanent_links_hosts[i]); - ++e; - continue; - } - l_net_pvt->permanent_links[i]->uplink_port = l_tmp->port; - dap_strncpy(l_net_pvt->permanent_links[i]->uplink_addr, l_tmp->addr, DAP_HOSTADDR_STRLEN); - DAP_DELETE(l_tmp); - } - debug_if(e, L_ERROR, "%d / %d permanent links are invalid or can't be accessed, fix \"%s\"" - "network config or check internet connection and restart node", - e, i, a_net_name); - - const char **l_authorized_nodes_addrs = dap_config_get_array_str(l_cfg, "general", "authorized_nodes_addrs", &l_net_pvt->authorized_nodes_count); - if (!l_net_pvt->authorized_nodes_count) - log_it(L_WARNING, "Can't read PoA nodes addresses"); - else - l_net_pvt->authorized_nodes_addrs = DAP_NEW_Z_COUNT(dap_chain_node_addr_t, l_net_pvt->authorized_nodes_count); - for (i = 0; i < l_net_pvt->authorized_nodes_count; ++i) { - dap_chain_node_addr_t l_addr; - if (dap_stream_node_addr_from_str(&l_addr, l_authorized_nodes_addrs[i])) { - log_it(L_ERROR, "Incorrect format of node address \"%s\", fix net config and restart node", l_authorized_nodes_addrs[i]); - dap_chain_net_delete(l_net); - dap_config_close(l_cfg); - return -17; - } - l_net_pvt->authorized_nodes_addrs[i].uint64 = l_addr.uint64; - } - const char **l_seed_nodes_hosts = dap_config_get_array_str(l_cfg, "general", "seed_nodes_hosts", &l_net_pvt->seed_nodes_count); - if (!l_net_pvt->seed_nodes_count) - l_seed_nodes_hosts = dap_config_get_array_str(l_cfg, "general", "bootstrap_hosts", &l_net_pvt->seed_nodes_count); - if (!l_net_pvt->seed_nodes_count) - log_it(L_WARNING, "Can't read seed nodes addresses, work with local balancer only"); - else if (!( l_net_pvt->seed_nodes_info = DAP_NEW_Z_COUNT(struct request_link_info*, l_net_pvt->seed_nodes_count) )) { - log_it(L_CRITICAL, "%s", c_error_memory_alloc); + // read permanent and authorized nodes addrs + if ( + s_nodes_addrs_init(l_cfg, "permanent_nodes_addrs", &l_net_pvt->permanent_links_addrs, &l_net_pvt->permanent_links_addrs_count) || + s_nodes_addrs_init(l_cfg, "authorized_nodes_addrs", &l_net_pvt->authorized_nodes_addrs, &l_net_pvt->authorized_nodes_count) || + s_nodes_hosts_init(l_net, l_cfg, "permanent_nodes_hosts", &l_net_pvt->permanent_links_hosts, &l_net_pvt->permanent_links_hosts_count) || + s_nodes_hosts_init(l_net, l_cfg, "seed_nodes_hosts", &l_net_pvt->seed_nodes_hosts, &l_net_pvt->seed_nodes_count) || + (!l_net_pvt->seed_nodes_count && s_nodes_hosts_init(l_net, l_cfg, "bootstrap_hosts", &l_net_pvt->seed_nodes_hosts, &l_net_pvt->seed_nodes_count) ) + ) { dap_chain_net_delete(l_net); dap_config_close(l_cfg); return -4; } - for (i = 0, e = 0; i < l_net_pvt->seed_nodes_count; ++i) { - if (!( l_net_pvt->seed_nodes_info[i] = s_net_resolve_host(l_seed_nodes_hosts[i]) )) { - log_it(L_ERROR, "Incorrect address \"%s\", fix \"%s\" network config" - "or check internet connection and restart node", - a_net_name, l_seed_nodes_hosts[i]); - ++e; - continue; - } - } - debug_if(e, L_ERROR, "%d / %d seed links are invalid or can't be accessed, fix \"%s\"" - "network config or check internet connection and restart node", - e, i, a_net_name); + debug_if(!l_net_pvt->authorized_nodes_count, L_WARNING, "Can't read PoA nodes addresses"); + if (!l_net_pvt->seed_nodes_count) + log_it(L_WARNING, "Can't read seed nodes addresses, work with local balancer only"); /* *** Chains init by configs *** */ DIR *l_chains_dir = opendir(a_path); @@ -1875,12 +1902,14 @@ int s_net_init(const char *a_net_name, const char *a_path, uint16_t a_acl_idx) dap_chain_t *l_chain; dap_chain_type_t *l_types_arr; char l_occupied_default_types[CHAIN_TYPE_MAX] = { 0 }; - uint16_t k; HASH_ITER(hh, l_all_chain_configs, l_chain_config, l_tmp_cfg) { if (( l_chain = dap_chain_load_from_cfg(l_net->pub.name, l_net->pub.id, l_chain_config) )) { DL_APPEND(l_net->pub.chains, l_chain); l_types_arr = l_chain->default_datum_types; - for (i = 0, k = l_chain->default_datum_types_count; i < k; ++i) { + uint16_t + i = 0, + k = l_chain->default_datum_types_count; + for ( ; i < k; ++i) { if ( l_occupied_default_types[l_types_arr[i]] ) { if ( i < k - 1 ) l_types_arr[i] = @@ -1937,7 +1966,7 @@ int s_net_init(const char *a_net_name, const char *a_path, uint16_t a_acl_idx) return 0; } -bool s_net_load(void *a_arg) +static void *s_net_load(void *a_arg) { dap_chain_net_t *l_net = a_arg; int l_err_code = 0; @@ -1951,12 +1980,12 @@ bool s_net_load(void *a_arg) dap_chain_net_pvt_t *l_net_pvt = PVT(l_net); // reload ledger cache at once - if (s_chain_net_reload_ledger_cache_once(l_net)) { + /*if (s_chain_net_reload_ledger_cache_once(l_net)) { log_it(L_WARNING,"Start one time ledger cache reloading"); dap_ledger_purge(l_net->pub.ledger, false); dap_chain_net_srv_stake_purge(l_net); } else - dap_chain_net_srv_stake_load_cache(l_net); + dap_chain_net_srv_stake_load_cache(l_net);*/ // load chains dap_chain_t *l_chain = l_net->pub.chains; @@ -2001,7 +2030,6 @@ bool s_net_load(void *a_arg) log_it(L_NOTICE, "[%s] Chain [%s] processing took %f seconds", l_chain->net_name, l_chain->name, time_taken); l_chain = l_chain->next; } - l_net_pvt->load_mode = false; dap_ledger_load_end(l_net->pub.ledger); // Do specific role actions post-chain created @@ -2173,14 +2201,11 @@ bool s_net_load(void *a_arg) dap_proc_thread_timer_add(NULL, s_sync_timer_callback, l_net, c_sync_timer_period); log_it(L_INFO, "Chain network \"%s\" initialized", l_net->pub.name); + l_net_pvt->state = NET_STATE_OFFLINE; ret: if (l_err_code) log_it(L_ERROR, "Loading chains of net %s finished with (%d) error code.", l_net->pub.name, l_err_code); - pthread_mutex_lock(&s_net_cond_lock); - s_net_loading_count--; - pthread_cond_signal(&s_net_cond); - pthread_mutex_unlock(&s_net_cond_lock); - return false; + return NULL; } dap_global_db_cluster_t *dap_chain_net_get_mempool_cluster(dap_chain_t *a_chain) @@ -2433,14 +2458,14 @@ char * dap_chain_net_get_gdb_group_mempool_by_chain_type(dap_chain_net_t *a_net, * @param l_net * @return */ -dap_chain_net_state_t dap_chain_net_get_state (dap_chain_net_t * l_net) +dap_chain_net_state_t dap_chain_net_get_state (dap_chain_net_t *a_net) { - return PVT(l_net)->state; + return PVT(a_net)->state; } -dap_chain_cell_id_t * dap_chain_net_get_cur_cell( dap_chain_net_t * l_net) +dap_chain_cell_id_t * dap_chain_net_get_cur_cell( dap_chain_net_t *a_net) { - return PVT(l_net)->node_info ? &PVT(l_net)->node_info->cell_id: 0; + return PVT(a_net)->node_info ? &PVT(a_net)->node_info->cell_id: 0; } /** @@ -2794,7 +2819,7 @@ int dap_chain_datum_remove(dap_chain_t *a_chain, dap_chain_datum_t *a_datum, siz bool dap_chain_net_get_load_mode(dap_chain_net_t * a_net) { - return PVT(a_net)->load_mode; + return PVT(a_net)->state == NET_STATE_LOADING; } int dap_chain_net_add_reward(dap_chain_net_t *a_net, uint256_t a_reward, uint64_t a_block_num) @@ -3245,7 +3270,7 @@ static bool s_net_states_proc(void *a_arg) */ int dap_chain_net_state_go_to(dap_chain_net_t *a_net, dap_chain_net_state_t a_new_state) { - if (PVT(a_net)->load_mode) { + if (dap_chain_net_get_load_mode(a_net)) { log_it(L_ERROR, "Can't change state of loading network '%s'", a_net->pub.name); return -1; } @@ -3272,25 +3297,12 @@ int dap_chain_net_state_go_to(dap_chain_net_t *a_net, dap_chain_net_state_t a_ne dap_link_manager_set_net_condition(a_net->pub.id.uint64, true); uint16_t l_permalink_hosts_count = 0; dap_config_get_array_str(a_net->pub.config, "general", "permanent_nodes_hosts", &l_permalink_hosts_count); - l_permalink_hosts_count = dap_min(l_permalink_hosts_count, PVT(a_net)->permanent_links_count); - for (uint16_t i = 0; i < l_permalink_hosts_count; ++i) { - dap_link_info_t *l_permalink_info = PVT(a_net)->permanent_links[i]; - if ( !*l_permalink_info->uplink_addr ) { - // Unresolved before? Let's try again - const char **l_permanent_links_hosts = dap_config_get_array_str(a_net->pub.config, "general", "permanent_nodes_hosts", NULL); - struct request_link_info *l_tmp = s_net_resolve_host(l_permanent_links_hosts[i]); - if (l_tmp) { - l_permalink_info->uplink_port = l_tmp->port; - dap_strncpy(l_permalink_info->uplink_addr, l_tmp->addr, DAP_HOSTADDR_STRLEN); - DAP_DELETE(l_tmp); - } else { - log_it(L_ERROR, "Can't resolve permanent link address %s for net %s, possibly an internet connection issue", - l_permanent_links_hosts[i], a_net->pub.name); - continue; - } - } - if (dap_chain_net_link_add(a_net, &l_permalink_info->node_addr, l_permalink_info->uplink_addr, l_permalink_info->uplink_port)) { - log_it(L_ERROR, "Can't create permanent link to addr " NODE_ADDR_FP_STR, NODE_ADDR_FP_ARGS_S(l_permalink_info->node_addr)); + for (uint16_t i = 0; i < PVT(a_net)->permanent_links_addrs_count; ++i) { + if (dap_chain_net_link_add(a_net, PVT(a_net)->permanent_links_addrs + i, + i < PVT(a_net)->permanent_links_hosts_count ? (PVT(a_net)->permanent_links_hosts[i])->addr : NULL, + i < PVT(a_net)->permanent_links_hosts_count ? (PVT(a_net)->permanent_links_hosts[i])->port : 0) + ) { + log_it(L_ERROR, "Can't create permanent link to addr " NODE_ADDR_FP_STR, NODE_ADDR_FP_ARGS(PVT(a_net)->permanent_links_addrs + i)); continue; } PVT(a_net)->state = NET_STATE_LINKS_CONNECTING; diff --git a/modules/net/dap_chain_net_node_list.c b/modules/net/dap_chain_net_node_list.c index a4d6cb70db35f5732cd880609480a4fded514e3c..ba669e0342d7570a5d3380c723caf212e45ceb68 100644 --- a/modules/net/dap_chain_net_node_list.c +++ b/modules/net/dap_chain_net_node_list.c @@ -107,7 +107,7 @@ void dap_chain_net_node_check_http_issue_link(dap_http_simple_t *a_http_simple, } const char *l_key = dap_stream_node_addr_to_str_static( (dap_chain_node_addr_t){.uint64 = addr} ); if (!l_key) { - log_it(L_ERROR, "Bad node address %zu", addr); + log_it(L_ERROR, "Bad node address %"DAP_UINT64_FORMAT_U, addr); *l_return_code = Http_Status_BadRequest; return; } @@ -287,7 +287,7 @@ int dap_chain_net_node_list_request(dap_chain_net_t *a_net, uint16_t a_port, boo if (!l_link_node_request) return log_it(L_CRITICAL, "%s", c_error_memory_alloc), -4; - char *l_request = dap_strdup_printf( "%s/%s?version=1,method=%c,addr=%zu,port=%hu,net=%s", + char *l_request = dap_strdup_printf( "%s/%s?version=1,method=%c,addr=%"DAP_UINT64_FORMAT_U",port=%hu,net=%s", DAP_UPLINK_PATH_NODE_LIST, DAP_NODE_LIST_URI_HASH, a_cmd, g_node_addr.uint64, a_port, a_net->pub.name ); int l_ret = -1; 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 f4d5bbff06446efa04b4038a84dccf8ce57eda75..644a40e19fc7cd937f1269010b179eb61a837275 100644 --- a/modules/net/dap_chain_node_cli_cmd.c +++ b/modules/net/dap_chain_node_cli_cmd.c @@ -2258,9 +2258,6 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE; return DAP_CHAIN_NODE_CLI_COM_TX_WALLET_INTERNAL_ERR; } - l_addr = l_net ? dap_chain_wallet_get_addr(l_wallet,l_net->pub.id ) : NULL; - - const char *l_addr_str = dap_chain_addr_to_str_static(l_addr); json_object * json_obj_wall = json_object_new_object(); json_object_object_add(json_obj_wall, "Wallet name", json_object_new_string(l_wallet->name)); if (l_sign_count > 1) { @@ -2274,8 +2271,10 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE; } else json_object_object_add(json_obj_wall, "Sign type", json_object_new_string(l_sign_type_str)); json_object_object_add(json_obj_wall, "Status", json_object_new_string("successfully created")); - if ( l_addr_str ) { - json_object_object_add(json_obj_wall, "new address", json_object_new_string(l_addr_str)); + + const char *l_addr_str = NULL; + if ( l_net && (l_addr_str = dap_chain_addr_to_str_static(dap_chain_wallet_get_addr(l_wallet,l_net->pub.id))) ) { + json_object_object_add(json_obj_wall, "new address", json_object_new_string(l_addr_str) ); } json_object_array_add(json_arr_out, json_obj_wall); dap_chain_wallet_close(l_wallet); @@ -3359,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, @@ -3391,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); @@ -4002,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 * @@ -5435,7 +5651,7 @@ int com_tx_cond_remove(int a_argc, char ** a_argv, void **a_json_arr_reply) uint256_t l_cond_value_sum = {}; size_t l_num_of_hashes = dap_list_length(l_hashes_list); - log_it(L_INFO, "Found %"DAP_UINT64_FORMAT_U" hashes. Start returning funds from transactions.", l_num_of_hashes); + log_it(L_INFO, "Found %zu hashes. Start returning funds from transactions.", l_num_of_hashes); for (dap_list_t * l_tmp = l_hashes_list; l_tmp; l_tmp=l_tmp->next){ dap_hash_fast_t *l_hash = (dap_hash_fast_t*)l_tmp->data; // get tx by hash @@ -8462,7 +8678,7 @@ static dap_tsd_t *s_alloc_metadata (const char *a_file, const int a_meta) struct stat l_st; stat (a_file, &l_st); char l_size[513]; - snprintf(l_size, 513, "%ld", l_st.st_size); + snprintf(l_size, 513, "%lld", l_st.st_size); return dap_tsd_create_string(SIGNER_FILESIZE, l_size); } break; diff --git a/modules/net/dap_chain_node_client.c b/modules/net/dap_chain_node_client.c index e08164a47dc01ee669a7bec7dc74788c25339631..d417ca03cfb801e528b3335c74884e1b28569853 100644 --- a/modules/net/dap_chain_node_client.c +++ b/modules/net/dap_chain_node_client.c @@ -400,7 +400,7 @@ int dap_chain_node_client_wait(dap_chain_node_client_t *a_client, int a_waited_s // prepare for signal waiting struct timespec l_cond_timeout; clock_gettime(CLOCK_REALTIME, &l_cond_timeout); - l_cond_timeout.tv_sec += a_timeout_ms; + l_cond_timeout.tv_sec += a_timeout_ms/1000; int l_ret_wait = pthread_cond_timedwait(&a_client->wait_cond, &a_client->wait_mutex, &l_cond_timeout); if (l_ret_wait == 0) { if (a_client->state != a_waited_state) { diff --git a/modules/net/include/dap_chain_net.h b/modules/net/include/dap_chain_net.h index 304a9037505539a26d3b511d569940396d014976..052ffb7b6d94407e588b3cc6917c3af842b61d8b 100644 --- a/modules/net/include/dap_chain_net.h +++ b/modules/net/include/dap_chain_net.h @@ -48,7 +48,8 @@ typedef struct dap_chain_net_decree dap_chain_net_decree_t; typedef struct decree_table decree_table_t; typedef struct anchor_table anchor_table_t; typedef enum dap_chain_net_state { - NET_STATE_OFFLINE = 0, + NET_STATE_LOADING = 0, + NET_STATE_OFFLINE, NET_STATE_LINKS_PREPARE, NET_STATE_LINKS_CONNECTING, NET_STATE_LINKS_ESTABLISHED, 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/service/stake/dap_chain_net_srv_stake_pos_delegate.c b/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c index 283f78856f8622a16833a82f823d5e8b57d281d1..6c26497597eb3194f7309b5f61cc350a35495d67 100644 --- a/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c +++ b/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c @@ -137,14 +137,12 @@ int dap_chain_net_srv_stake_pos_delegate_init() "srv_stake order create staker -net <net_name> -w <wallet_with_m_tokens> -value <stake_value> -fee <value> -tax <percent>" " [-addr <for_tax_collecting>] [-cert <for_order_signing>] [-H {hex(default) | base58}]\n" "\tCreates an order allowing the validator to delegate it's key with specified params\n" - "srv_stake order update -net <net_name> -order <order_hash> [-params]\n" - "\tUpdates an order with specified hash\n" "srv_stake order list [fee | validator | staker] -net <net_name>\n" "\tGet orders list of specified type within specified net name\n" "srv_stake order remove -net <net_name> -order <order_hash>\n" "\tRemove order with specified hash\n" "\t\t === Commands for work with stake delegate ===\n" - "srv_stake delegate {-cert <pub_cert_name> -value <datoshi> | " + "srv_stake delegate {[-cert <pub_cert_name> | -pkey <pkey> -sign_type <sign_type>] -value <datoshi> | " "-order <order_hash> {[-tax_addr <wallet_addr_for_tax_collecting>] | " "-cert <priv_cert_name> [-node_addr <for_validator_node>]}}" " -net <net_name> -w <wallet_name> -fee <value>\n" @@ -1529,7 +1527,7 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, voi { json_object **a_json_arr_reply = (json_object **)a_str_reply; enum { - CMD_NONE, CMD_CREATE_FEE, CMD_CREATE_VALIDATOR, CMD_CREATE_STAKER, CMD_UPDATE, CMD_LIST, + CMD_NONE, CMD_CREATE_FEE, CMD_CREATE_VALIDATOR, CMD_CREATE_STAKER, CMD_LIST, CMD_LIST_STAKER, CMD_LIST_VALIDATOR, CMD_LIST_FEE, CMD_REMOVE }; int l_cmd_num = CMD_NONE; @@ -1542,8 +1540,6 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, voi else l_cmd_num = CMD_CREATE_FEE; } - else if (dap_cli_server_cmd_check_option(a_argv, a_arg_index, dap_min(a_argc, a_arg_index + 1), "update") >= 0) - l_cmd_num = CMD_UPDATE; else if (dap_cli_server_cmd_check_option(a_argv, a_arg_index, dap_min(a_argc, a_arg_index + 1), "list") >= 0) l_cmd_num = CMD_LIST; else if (dap_cli_server_cmd_check_option(a_argv, a_arg_index, dap_min(a_argc, a_arg_index + 1), "remove") >= 0) @@ -1792,13 +1788,11 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, voi DAP_DELETE(l_tx_hash_str); } break; - case CMD_REMOVE: - case CMD_UPDATE: { + case CMD_REMOVE: { const char *l_order_hash_str = NULL; dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-order", &l_order_hash_str); if (!l_order_hash_str) { - dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_ORDER_PARAM_ERR, "Command 'srv_stake order %s' requires prameter -order\n", - l_cmd_num == CMD_REMOVE ? "remove" : "update"); + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_ORDER_PARAM_ERR, "Command 'srv_stake order remove' requires prameter -order\n"); return DAP_CHAIN_NODE_CLI_SRV_STAKE_ORDER_PARAM_ERR; } char *l_order_hash_hex_str; @@ -1819,47 +1813,14 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, voi DAP_DELETE(l_order_hash_hex_str); return DAP_CHAIN_NODE_CLI_SRV_STAKE_ORDER_ORDER_ERR; } - if (l_cmd_num == CMD_REMOVE) { - if (dap_chain_net_srv_order_delete_by_hash_str_sync(l_net, l_order_hash_hex_str)) { - dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_ORDER_REMOVE_ERR, "Can't remove order %s\n", l_order_hash_str); - return DAP_CHAIN_NODE_CLI_SRV_STAKE_ORDER_REMOVE_ERR; - } - json_object * l_json_obj_create_val = json_object_new_object(); - json_object_object_add(l_json_obj_create_val, "status", json_object_new_string("success")); - json_object_array_add(*a_json_arr_reply, l_json_obj_create_val); - DAP_DELETE(l_order_hash_hex_str); - } else { // l_cmd_num == CMD_UPDATE - const char *l_cert_str = NULL, *l_value_str = NULL; - // TODO make orders updatable - /*uint256_t l_value = {0}; - if (l_value_str) { - l_value = dap_chain_balance_scan(l_value_str); - if (IS_ZERO_256(l_value)) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Format -value <uint256_t>"); - return -8; - } - } - dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-cert", &l_cert_str); - if (!l_cert_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'order update' requires parameter -cert"); - return -7; - } - dap_cert_t *l_cert = dap_cert_find_by_name(l_cert_str); - if (!l_cert) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't load cert %s", l_cert_str); - return -9; - } - l_key = l_cert->enc_key; - // Remove old order and create the order & put it to GDB - dap_chain_net_srv_order_delete_by_hash_str_sync(l_net, l_order_hash_hex_str); - DAP_DELETE(l_order_hash_hex_str); - DAP_DELETE(l_order_hash_base58_str); - l_order_hash_hex_str = s_fee_order_create(l_net, &l_value, l_key); - if(!l_order_hash_hex_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't create new order"); - return -15; - }*/ + if (dap_chain_net_srv_order_delete_by_hash_str_sync(l_net, l_order_hash_hex_str)) { + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_ORDER_REMOVE_ERR, "Can't remove order %s\n", l_order_hash_str); + return DAP_CHAIN_NODE_CLI_SRV_STAKE_ORDER_REMOVE_ERR; } + json_object * l_json_obj_create_val = json_object_new_object(); + json_object_object_add(l_json_obj_create_val, "status", json_object_new_string("success")); + json_object_array_add(*a_json_arr_reply, l_json_obj_create_val); + DAP_DELETE(l_order_hash_hex_str); } break; case CMD_LIST: { @@ -1997,6 +1958,8 @@ typedef enum s_cli_srv_stake_delegate_err{ DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_WALLET_ERR, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_NO_CERT_ERR, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_WRONG_CERT_ERR, + DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_WRONG_SIGN_ERR, + DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_INVALID_PKEY_ERR, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_UNRECOGNIZED_ADDR_ERR, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_NO_ORDER_ERR, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_INVALID_ORDER_ERR, @@ -2026,6 +1989,8 @@ static int s_cli_srv_stake_delegate(int a_argc, char **a_argv, int a_arg_index, const char *l_net_str = NULL, *l_wallet_str = NULL, *l_cert_str = NULL, + *l_pkey_str = NULL, + *l_sign_type_str = NULL, *l_value_str = NULL, *l_fee_str = NULL, *l_node_addr_str = NULL, @@ -2057,9 +2022,16 @@ static int s_cli_srv_stake_delegate(int a_argc, char **a_argv, int a_arg_index, dap_chain_addr_t l_signing_addr, l_sovereign_addr = {}; uint256_t l_sovereign_tax = uint256_0; dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-cert", &l_cert_str); + dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-pkey", &l_pkey_str); + dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-sign_type", &l_sign_type_str); dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-order", &l_order_hash_str); - if (!l_cert_str && !l_order_hash_str) { - dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_PARAM_ERR, "Command 'delegate' requires parameter -cert and/or -order"); + if (!l_cert_str && !l_order_hash_str && !l_pkey_str) { + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_PARAM_ERR, "Command 'delegate' requires parameter -cert and/or -order and/or -pkey"); + dap_enc_key_delete(l_enc_key); + return -13; + } + if (l_pkey_str && !l_sign_type_str) { + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_PARAM_ERR, "Command 'delegate' requires parameter -sign_type for pkey"); dap_enc_key_delete(l_enc_key); return DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_PARAM_ERR; } @@ -2093,6 +2065,21 @@ static int s_cli_srv_stake_delegate(int a_argc, char **a_argv, int a_arg_index, return DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_WRONG_CERT_ERR; } dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-node_addr", &l_node_addr_str); + } else if (l_pkey_str) { + dap_chain_hash_fast_t l_hash_public_key = {0}; + dap_sign_type_t l_type = dap_sign_type_from_str(l_sign_type_str); + if (l_type.type == SIG_TYPE_NULL) { + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_WRONG_SIGN_ERR, "Wrong sign type"); + dap_enc_key_delete(l_enc_key); + return DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_WRONG_SIGN_ERR; + } + if (dap_chain_hash_fast_from_str(l_pkey_str, &l_hash_public_key)) { + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_INVALID_PKEY_ERR, "Invalid pkey hash format"); + dap_enc_key_delete(l_enc_key); + return DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_INVALID_PKEY_ERR; + } + dap_chain_addr_fill(&l_signing_addr, l_type, &l_hash_public_key, l_net->pub.id); + dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-node_addr", &l_node_addr_str); } dap_chain_node_addr_t l_node_addr = g_node_addr; if (l_node_addr_str) { @@ -2294,15 +2281,36 @@ static int s_cli_srv_stake_delegate(int a_argc, char **a_argv, int a_arg_index, DAP_DELETE(l_tx); json_object* l_json_obj_deligate = json_object_new_object(); json_object_object_add(l_json_obj_deligate, "status", json_object_new_string("success")); - json_object_object_add(l_json_obj_deligate, "sign", json_object_new_string(l_sign_str)); + if (dap_strcmp(l_sign_str, "")) + json_object_object_add(l_json_obj_deligate, "sign", json_object_new_string(l_sign_str)); // deprecated signs error json_object_object_add(l_json_obj_deligate, "tx_hash", json_object_new_string(l_tx_hash_str)); json_object_array_add(*a_json_arr_reply, l_json_obj_deligate); DAP_DELETE(l_tx_hash_str); return 0; } + +typedef enum s_cli_srv_stake_update_err{ + DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_OK = 0, + DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_MEMORY_ERR, + DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_PARAM_ERR, + DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_PARAM_FORMAT_ERR, + DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_NET_ERR, + DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_FEE_ERR, + DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_NO_CERT_ERR, + DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_WRONG_CERT_ERR, + DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_PKEY_ERR, + DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_NO_STAKE_IN_NET_ERR, + DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_NOT_DELGATED_ERR, + DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_NO_TX_ERR, + DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_INVALID_TX_ERR, + DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_TX_SPENT_ERR, + DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_NO_WALLET_ERR, + DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_CANT_COMPOSE_ERR, +} s_cli_srv_stake_update_err_t; static int s_cli_srv_stake_update(int a_argc, char **a_argv, int a_arg_index, void **a_str_reply, const char *a_hash_out_type) { + json_object **a_json_arr_reply = (json_object **)a_str_reply; const char *l_net_str = NULL, *l_wallet_str = NULL, *l_value_str, @@ -2311,45 +2319,45 @@ static int s_cli_srv_stake_update(int a_argc, char **a_argv, int a_arg_index, vo *l_cert_str = NULL; dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-net", &l_net_str); if (!l_net_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'update' requires parameter -net"); + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_PARAM_ERR, "Command 'update' requires parameter -net"); return -3; } dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_str); if (!l_net) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Network %s not found", l_net_str); + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_NET_ERR, "Network %s not found", l_net_str); return -4; } uint256_t l_fee = {}; dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-w", &l_wallet_str); if (!l_wallet_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'update' requires parameter -w"); + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_PARAM_ERR, "Command 'update' requires parameter -w"); return -17; } dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-fee", &l_fee_str); if (!l_fee_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'update' requires parameter -fee"); + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_PARAM_ERR, "Command 'update' requires parameter -fee"); return -5; } l_fee = dap_chain_balance_scan(l_fee_str); if (IS_ZERO_256(l_fee)) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Unrecognized number in '-fee' param"); + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_FEE_ERR, "Unrecognized number in '-fee' param"); return -6; } uint256_t l_value = {}; dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-value", &l_value_str); if (!l_value_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'update' requires parameter -value"); + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_PARAM_ERR, "Command 'update' requires parameter -value"); return -7; } l_value = dap_chain_balance_scan(l_value_str); if (IS_ZERO_256(l_value)) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Unrecognized number in '-value' param"); + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_PARAM_FORMAT_ERR, "Unrecognized number in '-value' param"); return -8; } uint256_t l_value_min = dap_chain_net_srv_stake_get_allowed_min_value(l_net->pub.id); if (compare256(l_value, l_value_min) == -1) { const char *l_value_min_str; dap_uint256_to_char(l_value_min, &l_value_min_str); - dap_cli_server_cmd_set_reply_text(a_str_reply, "New delegation value should be not less than service required minimum %s", l_value_min_str); + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_PARAM_FORMAT_ERR, "New delegation value should be not less than service required minimum %s", l_value_min_str); return -25; } @@ -2357,7 +2365,7 @@ static int s_cli_srv_stake_update(int a_argc, char **a_argv, int a_arg_index, vo if (!l_tx_hash_str) { dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-cert", &l_cert_str); if (!l_cert_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'update' requires parameter -tx or -cert"); + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_PARAM_ERR, "Command 'update' requires parameter -tx or -cert"); return -13; } } @@ -2368,26 +2376,26 @@ static int s_cli_srv_stake_update(int a_argc, char **a_argv, int a_arg_index, vo dap_chain_addr_t l_signing_addr; dap_cert_t *l_cert = dap_cert_find_by_name(l_cert_str); if (!l_cert) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate not found"); + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_NO_CERT_ERR, "Specified certificate not found"); return -18; } if (!l_cert->enc_key->priv_key_data || l_cert->enc_key->priv_key_data_size == 0) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "It is not possible to update a stake using a public key."); + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_PKEY_ERR, "It is not possible to update a stake using a public key."); return -31; } if (dap_chain_addr_fill_from_key(&l_signing_addr, l_cert->enc_key, l_net->pub.id)) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate is wrong"); + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_WRONG_CERT_ERR, "Specified certificate is wrong"); return -22; } dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(l_net->pub.id); if (!l_srv_stake) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified net have no stake service activated"); + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_NO_STAKE_IN_NET_ERR, "Specified net have no stake service activated"); return -25; } dap_chain_net_srv_stake_item_t *l_stake = NULL; HASH_FIND(hh, l_srv_stake->itemlist, &l_signing_addr.data.hash_fast, sizeof(dap_hash_fast_t), l_stake); if (!l_stake) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate/pkey hash is not delegated nor this delegating is approved." + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_NOT_DELGATED_ERR, "Specified certificate/pkey hash is not delegated nor this delegating is approved." " Try to update with tx hash instead"); return -24; } @@ -2397,24 +2405,24 @@ static int s_cli_srv_stake_update(int a_argc, char **a_argv, int a_arg_index, vo const char *l_tx_hash_str_tmp = l_tx_hash_str ? l_tx_hash_str : dap_hash_fast_to_str_static(&l_tx_hash); dap_chain_datum_tx_t *l_tx = dap_ledger_tx_find_by_hash(l_net->pub.ledger, &l_tx_hash); if (!l_tx) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Transaction %s not found", l_tx_hash_str_tmp); + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_NO_TX_ERR, "Transaction %s not found", l_tx_hash_str_tmp); return -21; } int l_out_num = 0; if (!dap_chain_datum_tx_out_cond_get(l_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE, &l_out_num)) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Transaction %s is invalid", l_tx_hash_str_tmp); + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_INVALID_TX_ERR, "Transaction %s is invalid", l_tx_hash_str_tmp); return -22; } dap_hash_fast_t l_spender_hash = {}; if (dap_ledger_tx_hash_is_used_out_item(l_net->pub.ledger, &l_tx_hash, l_out_num, &l_spender_hash)) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Transaction %s is spent", l_tx_hash_str_tmp); + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_TX_SPENT_ERR, "Transaction %s is spent", l_tx_hash_str_tmp); return -23; } const char* l_sign_str = ""; dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_wallet_str, dap_chain_wallet_get_path(g_config), NULL); if (!l_wallet) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified wallet %s not found", l_wallet_str); + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_NO_WALLET_ERR, "Specified wallet %s not found", l_wallet_str); return -18; } else { l_sign_str = dap_chain_wallet_check_sign(l_wallet); @@ -2425,12 +2433,17 @@ static int s_cli_srv_stake_update(int a_argc, char **a_argv, int a_arg_index, vo dap_enc_key_delete(l_enc_key); char *l_out_hash_str = NULL; if (l_tx_new && (l_out_hash_str = s_stake_tx_put(l_tx_new, l_net, a_hash_out_type))) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "%sDelegated m-tokens value will change. Updating tx hash is %s.", l_sign_str, l_out_hash_str); + json_object* l_json_object_ret = json_object_new_object(); + if (l_sign_str) + json_object_object_add(l_json_object_ret, "sign", json_object_new_string(l_sign_str)); + json_object_object_add(l_json_object_ret, "hash", json_object_new_string(l_out_hash_str)); + json_object_object_add(l_json_object_ret, "message", json_object_new_string("Delegated m-tokens value will change")); + json_object_array_add(*a_json_arr_reply, l_json_object_ret); DAP_DELETE(l_out_hash_str); DAP_DELETE(l_tx_new); } else { l_tx_hash_str = dap_chain_hash_fast_to_str_static(&l_tx_hash); - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't compose updating transaction %s, examine log files for details", l_tx_hash_str); + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_CANT_COMPOSE_ERR, "Can't compose updating transaction %s, examine log files for details", l_tx_hash_str); DAP_DEL_Z(l_tx_new); return -21; } @@ -2686,6 +2699,7 @@ static void s_srv_stake_print(dap_chain_net_srv_stake_item_t *a_stake, uint256_t snprintf(l_node_addr, 32, ""NODE_ADDR_FP_STR"", NODE_ADDR_FP_ARGS_S(a_stake->node_addr)); json_object_object_add(l_json_obj_stake, "pkey_hash", json_object_new_string(l_pkey_hash_str)); json_object_object_add(l_json_obj_stake, "stake_value", json_object_new_string(l_balance)); + json_object_object_add(l_json_obj_stake, "effective_value", json_object_new_string(l_effective_weight)); json_object_object_add(l_json_obj_stake, "related_weight", json_object_new_string(l_rel_weight_str)); json_object_object_add(l_json_obj_stake, "tx_hash", json_object_new_string(l_tx_hash_str)); json_object_object_add(l_json_obj_stake, "node_addr", json_object_new_string(l_node_addr)); @@ -2774,6 +2788,7 @@ int dap_chain_net_srv_stake_check_validator(dap_chain_net_t * a_net, dap_hash_fa l_remote_node_info = (dap_chain_node_info_t*) dap_global_db_get_sync(a_net->pub.gdb_nodes, dap_stream_node_addr_to_str_static(l_tx_out_cond->subtype.srv_stake_pos_delegate.signer_node_addr), &l_node_info_size, NULL, NULL); + if(!l_remote_node_info) { return -6; @@ -2984,7 +2999,7 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply) } json_object* json_obj_order = json_object_new_object(); - json_object_object_add(json_obj_order, "VERSION", json_object_new_int(*(int*)l_out.header.version)); + json_object_object_add(json_obj_order, "VERSION", json_object_new_string((char*)l_out.header.version)); json_object_object_add(json_obj_order, "AUTO_PROC", json_object_new_string((l_out.header.flags & A_PROC)?"true":"false")); json_object_object_add(json_obj_order, "ORDER", json_object_new_string((l_out.header.flags & F_ORDR)?"true":"false")); json_object_object_add(json_obj_order, "AUTO_ONLINE", json_object_new_string((l_out.header.flags & A_ONLN)?"true":"false")); @@ -3123,10 +3138,14 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply) json_object_object_add(l_json_obj_keys_count, "total_keys", json_object_new_int(l_total_count)); if (dap_chain_esbocs_started(l_net->pub.id)) json_object_object_add(l_json_obj_keys_count, "inactive_keys", json_object_new_int(l_inactive_count)); - const char *l_total_weight_coins, *l_total_weight_str = - dap_uint256_to_char(l_total_weight, &l_total_weight_coins); + + + const char *l_total_weight_coins, *l_total_weight_str = dap_uint256_to_char(l_total_locked_weight, &l_total_weight_coins); json_object_object_add(l_json_obj_keys_count, "total_weight_coins", json_object_new_string(l_total_weight_coins)); json_object_object_add(l_json_obj_keys_count, "total_weight_str", json_object_new_string(l_total_weight_str)); + l_total_weight_str = dap_uint256_to_char(l_total_weight, &l_total_weight_coins); + json_object_object_add(l_json_obj_keys_count, "total_effective_weight_coins", json_object_new_string(l_total_weight_coins)); + json_object_object_add(l_json_obj_keys_count, "total_effective_weight", json_object_new_string(l_total_weight_str)); } const char *l_delegate_min_str; dap_uint256_to_char(dap_chain_net_srv_stake_get_allowed_min_value(l_net->pub.id), diff --git a/modules/service/voting/dap_chain_net_srv_voting.c b/modules/service/voting/dap_chain_net_srv_voting.c index c0d207af700b1eab185ee8bca2b4e6a513504744..8196ec0549881ee61f9e62addb59583a8dea75c6 100644 --- a/modules/service/voting/dap_chain_net_srv_voting.c +++ b/modules/service/voting/dap_chain_net_srv_voting.c @@ -1043,6 +1043,7 @@ static int s_cli_voting(int a_argc, char **a_argv, void **a_str_reply) l_val = dap_strdup_printf("%s (%s) %s\n\n", l_tw_coins, l_tw_datoshi, l_net->pub.native_ticker); json_object_object_add(json_vote_out, "Total weight", json_object_new_string(l_val)); DAP_DELETE(l_val); + json_object_array_add(*json_arr_reply, json_vote_out); }break; default:{ 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..85b25313f3d4a20faddae904c2a758d4c4eccf2d 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((dap_chain_hash_fast_t*)a_meta->data) : + dap_chain_hash_fast_to_str_static((dap_chain_hash_fast_t*)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 }; @@ -2492,10 +2606,10 @@ static uint256_t s_callback_calc_reward(dap_chain_t *a_chain, dap_hash_fast_t *a } assert(l_block); dap_time_t l_cur_time = dap_max(l_block->hdr.ts_created, DAP_REWARD_INIT_TIMESTAMP); - dap_time_t l_time_diff = l_block_time > l_cur_time ? l_block_time - l_cur_time : 1; - if (MULT_256_256(l_ret, GET_256_FROM_64(l_time_diff), &l_ret)) { - log_it(L_ERROR, "Integer overflow while multiplication execution to calculate final reward"); - return uint256_0; + if ( l_block_time > l_cur_time ) { + dap_time_t l_time_diff = l_block_time - l_cur_time; + if (MULT_256_256(l_ret, GET_256_FROM_64(l_time_diff), &l_ret)) + return log_it(L_ERROR, "Integer overflow while multiplication execution to calculate final reward"), uint256_0; } DIV_256(l_ret, GET_256_FROM_64(s_block_timediff_unit_size * l_signs_count), &l_ret); return l_ret; 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 *