diff --git a/dap-sdk b/dap-sdk index 1ef6d0e78beed6d36a1a4cdedd913d59c0211b0d..15a26c4c061355b21dba20b56bb0a92efcd49343 160000 --- a/dap-sdk +++ b/dap-sdk @@ -1 +1 @@ -Subproject commit 1ef6d0e78beed6d36a1a4cdedd913d59c0211b0d +Subproject commit 15a26c4c061355b21dba20b56bb0a92efcd49343 diff --git a/modules/chain/dap_chain.c b/modules/chain/dap_chain.c index ccaae7c3a5c33a5263fc3d166d335afa3f5701fc..87579e99628e42a39af6031136b753f07efd5cac 100644 --- a/modules/chain/dap_chain.c +++ b/modules/chain/dap_chain.c @@ -104,6 +104,8 @@ void dap_chain_deinit(void) dap_chain_t * dap_chain_create(dap_ledger_t* a_ledger, const char * a_chain_net_name, const char * a_chain_name, dap_chain_net_id_t a_chain_net_id, dap_chain_id_t a_chain_id ) { dap_chain_t * l_ret = DAP_NEW_Z(dap_chain_t); + if ( !l_ret ) + return log_it(L_ERROR, "Memory allocation error in dap_chain_create, errno=%d", errno), NULL; DAP_CHAIN_PVT_LOCAL_NEW(l_ret); memcpy(l_ret->id.raw,a_chain_id.raw,sizeof(a_chain_id)); memcpy(l_ret->net_id.raw,a_chain_net_id.raw,sizeof(a_chain_net_id)); @@ -113,6 +115,10 @@ dap_chain_t * dap_chain_create(dap_ledger_t* a_ledger, const char * a_chain_net_ pthread_rwlock_init(&l_ret->rwlock, NULL); pthread_rwlock_init(&l_ret->cell_rwlock,NULL); dap_chain_item_t * l_ret_item = DAP_NEW_Z(dap_chain_item_t); + if ( !l_ret_item ){ + DAP_DELETE(l_ret); + return log_it(L_ERROR, "Memory allocation error in dap_chain_create, errno=%d", errno), NULL; + } l_ret_item->chain = l_ret; memcpy(l_ret_item->item_id.id.raw ,a_chain_id.raw,sizeof(a_chain_id)); memcpy(l_ret_item->item_id.net_id.raw ,a_chain_net_id.raw,sizeof(a_chain_net_id)); @@ -436,7 +442,11 @@ dap_chain_t * dap_chain_load_from_cfg(dap_ledger_t* a_ledger, const char * a_cha if (l_datum_types && l_datum_types_count > 0) { l_chain->datum_types = DAP_NEW_SIZE(dap_chain_type_t, l_datum_types_count * sizeof(dap_chain_type_t)); // TODO: pls check counter for recognized types before memory allocation! - l_count_recognized = 0; + if ( !l_chain->datum_types ) { + DAP_DELETE(l_chain); + return log_it(L_ERROR, "Memory allocation error in dap_chain_load_from_cfg, errno=%d", errno), NULL; + } + l_count_recognized = 0; for (uint16_t i = 0; i < l_datum_types_count; i++) { dap_chain_type_t l_chain_type = s_chain_type_from_str(l_datum_types[i]); @@ -454,7 +464,13 @@ dap_chain_t * dap_chain_load_from_cfg(dap_ledger_t* a_ledger, const char * a_cha if (l_default_datum_types && l_default_datum_types_count > 0) { l_chain->default_datum_types = DAP_NEW_SIZE(dap_chain_type_t, l_default_datum_types_count * sizeof(dap_chain_type_t)); // TODO: pls check counter for recognized types before memory allocation! - l_count_recognized = 0; + if ( !l_chain->default_datum_types ) { + if (l_chain->datum_types) + DAP_DELETE(l_chain->datum_types); + DAP_DELETE(l_chain); + return log_it(L_ERROR, "Memory allocation error in dap_chain_load_from_cfg, errno=%d", errno), NULL; + } + l_count_recognized = 0; for (uint16_t i = 0; i < l_default_datum_types_count; i++) { dap_chain_type_t l_chain_type = s_chain_type_from_str(l_default_datum_types[i]); @@ -476,7 +492,15 @@ dap_chain_t * dap_chain_load_from_cfg(dap_ledger_t* a_ledger, const char * a_cha if (l_datum_types && l_datum_types_count) { l_chain->autoproc_datum_types = DAP_NEW_Z_SIZE(uint16_t, l_chain->datum_types_count * sizeof(uint16_t)); // TODO: pls check counter for recognized types before memory allocation! - l_count_recognized = 0; + if ( !l_chain->autoproc_datum_types ) { + if (l_chain->datum_types) + DAP_DELETE(l_chain->datum_types); + if (l_chain->default_datum_types) + DAP_DELETE(l_chain->default_datum_types); + DAP_DELETE(l_chain); + return log_it(L_ERROR, "Memory allocation error in dap_chain_load_from_cfg, errno=%d", errno), NULL; + } + l_count_recognized = 0; for (uint16_t i = 0; i < l_datum_types_count; i++) { if (!dap_strcmp(l_datum_types[i], "all") && l_chain->datum_types_count) @@ -725,15 +749,25 @@ int dap_cert_chain_file_save(dap_chain_datum_t *datum, char *net_name) const char *cert_name = cert->name; size_t cert_path_length = dap_strlen(net_name) + dap_strlen(cert_name) + 9 + dap_strlen(s_system_chain_ca_dir); char *cert_path = DAP_NEW_STACK_SIZE(char, cert_path_length); + if ( !cert_path ) { + dap_cert_delete(cert); + log_it(L_ERROR, "Memory allocation error in dap_cert_chain_file_save, errno=%d", errno); + return -1; + } snprintf(cert_path, cert_path_length, "%s/%s/%s.dcert", s_system_chain_ca_dir, net_name, cert_name); // In cert_path resolve all `..` and `.`s char *cert_path_c = dap_canonicalize_filename(cert_path, NULL); // Protect the ca folder from using "/.." in cert_name if(dap_strncmp(s_system_chain_ca_dir, cert_path_c, dap_strlen(s_system_chain_ca_dir))) { + dap_cert_delete(cert); + DAP_DELETE(cert_path_c); + DAP_DELETE(cert_path); log_it(L_ERROR, "Cert path '%s' is not in ca dir: %s", cert_path_c, s_system_chain_ca_dir); return -1; } int l_ret = dap_cert_file_save(cert, cert_path_c); + dap_cert_delete(cert); + DAP_DELETE(cert_path); DAP_DELETE(cert_path_c); // if ( access( l_cert_path, F_OK ) != -1 ) { // log_it (L_ERROR, "File %s is already exists.", l_cert_path); diff --git a/modules/chain/dap_chain_cell.c b/modules/chain/dap_chain_cell.c index f71399ed40bedf973556dda8b472ca43fbcb4d66..e771db6ae459dc081fd3a04b533c0fdb4bd4efe7 100644 --- a/modules/chain/dap_chain_cell.c +++ b/modules/chain/dap_chain_cell.c @@ -101,6 +101,10 @@ dap_chain_cell_t * dap_chain_cell_create_fill(dap_chain_t * a_chain, dap_chain_c return l_cell; } l_cell = DAP_NEW_Z(dap_chain_cell_t); + if ( !l_cell ) { + pthread_rwlock_unlock(&a_chain->cell_rwlock); + return log_it(L_ERROR, "Memory allocation error in dap_chain_cell_create_fill, errno=%d", errno), NULL; + } l_cell->chain = a_chain; l_cell->id.uint64 = a_cell_id.uint64; l_cell->file_storage_path = dap_strdup_printf("%0"DAP_UINT64_FORMAT_x".dchaincell", l_cell->id.uint64); @@ -201,17 +205,17 @@ int dap_chain_cell_load(dap_chain_t * a_chain, const char * a_cell_file_path) return -3; } unsigned long q = 0; - while (!feof(l_cell_file)) { - uint64_t l_el_size = 0; - size_t l_read = fread(&l_el_size, 1, sizeof(l_el_size), l_cell_file); + size_t l_read; + uint64_t l_el_size = 0; + while ((l_read = fread(&l_el_size, 1, sizeof(l_el_size), l_cell_file)) && !feof(l_cell_file)) { if (l_read != sizeof(l_el_size) || l_el_size == 0) { - log_it(L_ERROR, "Corrupted element size, chain %s is damaged", l_file_path); + log_it(L_ERROR, "Corrupted element size %zu, chain %s is damaged", l_el_size, l_file_path); ret = -4; break; } dap_chain_atom_ptr_t l_element = DAP_NEW_SIZE(dap_chain_atom_ptr_t, l_el_size); if (!l_element) { - log_it(L_ERROR, "Out of memory"); + log_it(L_ERROR, "Memory allocation error in dap_chain_cell_load, errno=%d", errno); ret = -5; break; } diff --git a/modules/chain/dap_chain_cs.c b/modules/chain/dap_chain_cs.c index 198e499b4d8af632eda53573d883de08e6cf8444..352092a672ff89b5d5b5f9b4c68defbc5f3de9fe 100644 --- a/modules/chain/dap_chain_cs.c +++ b/modules/chain/dap_chain_cs.c @@ -65,6 +65,10 @@ void dap_chain_cs_deinit(void) void dap_chain_cs_type_add (const char * a_cs_str, dap_chain_callback_new_cfg_t a_callback_init) { dap_chain_callback_new_cfg_item_t *l_item = DAP_NEW_Z ( dap_chain_callback_new_cfg_item_t ); + if ( !l_item ) { + log_it(L_ERROR, "Memory allocation error in dap_chain_cs_type_add, errno=%d", errno); + return; + } strncpy(l_item->name, a_cs_str, sizeof (l_item->name) - 1); l_item->name[sizeof (l_item->name) - 1] = '\0'; l_item->callback_init = a_callback_init; @@ -101,6 +105,10 @@ int dap_chain_cs_type_create(dap_chain_t * a_chain, dap_config_t * a_chain_cfg) void dap_chain_cs_add (const char * a_cs_str, dap_chain_callback_new_cfg_t a_callback_init) { dap_chain_callback_new_cfg_item_t *l_item = DAP_NEW_Z ( dap_chain_callback_new_cfg_item_t ); + if ( !l_item ) { + log_it(L_ERROR, "Memory allocation error in dap_chain_cs_add, errno=%d", errno); + return; + } strncpy(l_item->name, a_cs_str, sizeof (l_item->name) - 1); l_item->name[sizeof (l_item->name) - 1] = '\0'; l_item->callback_init = a_callback_init; diff --git a/modules/chain/dap_chain_ledger.c b/modules/chain/dap_chain_ledger.c index 742f44df087d93246d4508c07dfca9c83758feb9..0700873c77619c4cde5d7992c0eea63983b77337 100644 --- a/modules/chain/dap_chain_ledger.c +++ b/modules/chain/dap_chain_ledger.c @@ -24,7 +24,7 @@ */ #include "dap_common.h" - +#include <dirent.h> #ifdef _WIN32 #include <winsock2.h> #include <windows.h> @@ -53,10 +53,11 @@ #include "dap_global_db.h" #include "dap_chain_ledger.h" #include "dap_chain_pvt.h" -#include "json-c/json.h" -#include "json-c/json_object.h" +#include "json.h" +#include "json_object.h" #include "dap_notify_srv.h" + #define LOG_TAG "dap_chain_ledger" typedef struct dap_chain_ledger_verificator { @@ -71,59 +72,65 @@ static pthread_rwlock_t s_verificators_rwlock; #define MAX_OUT_ITEMS 10 -char* dap_chain_ledger_tx_check_err_str(dap_chain_ledger_tx_check_t a_code){ - switch (a_code) { - case DAP_CHAIN_LEDGER_TX_CHECK_OK: - return dap_strdup("DAP_CHAIN_LEDGER_TX_CHECK_OK"); - case DAP_CHAIN_LEDGER_TX_CHECK_ERROR_IS_NULL_TX: - return dap_strdup("DAP_CHAIN_LEDGER_TX_CHECK_ERROR_IS_NULL_TX"); - case DAP_CHAIN_LEDGER_TX_CHECK_ERROR_INVALID_SIZE_TX: - return dap_strdup("DAP_CHAIN_LEDGER_TX_CHECK_ERROR_INVALID_SIZE_TX"); - case DAP_CHAIN_LEDGER_TX_CACHE_CHECK_INVALID_INPUT_DATA: - return dap_strdup("DAP_CHAIN_LEDGER_TX_CACHE_CHECK_INVALID_INPUT_DATA"); - case DAP_CHAIN_LEDGER_TX_CACHE_CHECK_INVALID_SIGN_TX: - return dap_strdup("DAP_CHAIN_LEDGER_TX_CACHE_CHECK_INVALID_SIGN_TX"); - case DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TX_NO_VALID_TNPUTS_FOUND: - return dap_strdup("DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TX_NO_VALID_TNPUTS_FOUND"); - case DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NOT_FOUND_TOKEN: - return dap_strdup("DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NOT_FOUND_TOKEN"); - case DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TOKEN_NOT_VALID_STAKE_LOCK: - return dap_strdup("DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TOKEN_NOT_VALID_STAKE_LOCK"); - case DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NO_OUT_COND_STAKE_LOCK_FROM_IN_EMS: - return dap_strdup("DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NO_OUT_COND_STAKE_LOCK_FROM_IN_EMS"); - case DAP_CHAIN_LEDGER_TX_CACHE_CHECK_MULTIPLICATION_OVERFLOW_EMISSION_LOCKED_EMISSION_RATE: - return dap_strdup("DAP_CHAIN_LEDGER_TX_CACHE_CHECK_MULTIPLICATION_OVERFLOW_EMISSION_LOCKED_EMISSION_RATE"); - case DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NO_OUT_EXT_FOR_GIRDLED_IN_EMS: - return dap_strdup("DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NO_OUT_EXT_FOR_GIRDLED_IN_EMS"); - case DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NOT_FIND_OUT_NOR_OUT_EXT_BASE_TX_IN_EMS: - return dap_strdup("DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NOT_FIND_OUT_NOR_OUT_EXT_BASE_TX_IN_EMS"); - case DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TOKEN_CURRENT_SUPPLY_LOWER_EMISSION_VALUE: - return dap_strdup("DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TOKEN_CURRENT_SUPPLY_LOWER_EMISSION_VALUE"); - case DAP_CHAIN_LEDGER_TX_CACHE_CHECK_VALUE_NOT_THATS_EXPECTED_IN_EMS: - return dap_strdup("DAP_CHAIN_LEDGER_TX_CACHE_CHECK_VALUE_NOT_THATS_EXPECTED_IN_EMS"); - case DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NOT_FOUND_TICKER_FOR_STAKE_LOCK: - return dap_strdup("DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NOT_FOUND_TICKER_FOR_STAKE_LOCK"); - case DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TICKER_DIFFERENT_EXPECTED: - return dap_strdup("DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TICKER_DIFFERENT_EXPECTED"); - case DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NOT_USED_OUT_ITEM: - return dap_strdup("DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NOT_USED_OUT_ITEM"); - case DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NOT_FIND_PREV_OUT_TX: - return dap_strdup("DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NOT_FIND_PREV_OUT_TX"); - case DAP_CHAIN_LEDGER_TX_CACHE_CHECK_HASH_PKEY_TX_NOT_COMPARE_HASH_PKEY_OUT_ADDR_PREV_TX: - return dap_strdup("DAP_CHAIN_LEDGER_TX_CACHE_CHECK_HASH_PKEY_TX_NOT_COMPARE_HASH_PKEY_OUT_ADDR_PREV_TX"); - case DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREVIOUS_TX_OUTPUT_ALREADY_USED_IN_CURRENT_TX: - return dap_strdup("DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREVIOUS_TX_OUTPUT_ALREADY_USED_IN_CURRENT_TX"); - case DAP_CHAIN_LEDGER_TX_CACHE_CHECK_VERIF_CHECK_NO_VALIDATOR_COND_OUTPUT: - return dap_strdup("DAP_CHAIN_LEDGER_TX_CACHE_CHECK_VERIF_CHECK_NO_VALIDATOR_COND_OUTPUT"); - case DAP_CHAIN_LEDGER_TX_CACHE_CHECK_VERIF_CHECK_FAIL: - return dap_strdup("DAP_CHAIN_LEDGER_TX_CACHE_CHECK_VERIF_CHECK_FAIL"); - case DAP_CHAIN_LEDGET_TX_CACHE_CHECK_NO_FOUND_TOKEN_TICKER: - return dap_strdup("DAP_CHAIN_LEDGET_TX_CACHE_CHECK_NO_FOUND_TOKEN_TICKER"); - case DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PERMISSION_FAILED: - return dap_strdup("DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PERMISSION_FAILED"); - default: - return dap_strdup_printf("Code error: %d undefined", a_code); - } +static const char *s_ledger_tx_check_err_str[] = { + [DAP_CHAIN_LEDGER_TX_CHECK_OK] = "DAP_CHAIN_LEDGER_TX_CHECK_OK", + [DAP_CHAIN_LEDGER_TX_CHECK_NULL_TX] = "DAP_CHAIN_LEDGER_TX_CHECK_NULL_TX", + [DAP_CHAIN_LEDGER_TX_CHECK_INVALID_TX_SIZE] = "DAP_CHAIN_LEDGER_TX_CHECK_INVALID_TX_SIZE", + [DAP_CHAIN_LEDGER_TX_ALREADY_CACHED] = "DAP_CHAIN_LEDGER_TX_ALREADY_CACHED", + [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NULL_TX] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NULL_TX", + [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_INVALID_TX_SIGN] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_INVALID_TX_SIGN", + [DAP_CHAIN_LEDGER_TX_CACHE_IN_EMS_ALREADY_USED] = "DAP_CHAIN_LEDGER_TX_CACHE_IN_EMS_ALREADY_USED", + [DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_IN_EMS_ALREADY_USED] = "DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_IN_EMS_ALREADY_USED", + [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_EMISSION_NOT_FOUND] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_EMISSION_NOT_FOUND", + [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TX_NO_VALID_INPUTS] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TX_NO_VALID_INPUTS", + [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TICKER_NOT_FOUND] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TICKER_NOT_FOUND", + [DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_INVALID_TOKEN] = "DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_INVALID_TOKEN", + [DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_NO_OUT_COND_FOR_IN_EMS] = "DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_NO_OUT_COND_FOR_IN_EMS", + [DAP_CHAIN_LEDGER_TX_CACHE_MULT256_OVERFLOW_EMS_LOCKED_X_RATE] = "DAP_CHAIN_LEDGER_TX_CACHE_MULT256_OVERFLOW_EMS_LOCKED_X_RATE", + [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NO_OUT_EXT_FOR_GIRDLED_IN_EMS] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NO_OUT_EXT_FOR_GIRDLED_IN_EMS", + [DAP_CHAIN_LEDGER_TX_CACHE_NO_OUT_ITEMS_FOR_BASE_TX] = "DAP_CHAIN_LEDGER_TX_CACHE_NO_OUT_ITEMS_FOR_BASE_TX", + [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TOKEN_EMS_VALUE_EXEEDS_CUR_SUPPLY] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TOKEN_EMS_VALUE_EXEEDS_CUR_SUPPLY", + [DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_UNEXPECTED_VALUE] = "DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_UNEXPECTED_VALUE", + [DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_TICKER_NOT_FOUND] = "DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_TICKER_NOT_FOUND", + [DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_OTHER_TICKER_EXPECTED] = "DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_OTHER_TICKER_EXPECTED", + [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_OUT_ITEM_ALREADY_USED] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_OUT_ITEM_ALREADY_USED", + [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TX_NOT_FOUND] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TX_NOT_FOUND", + [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_OUT_ITEM_NOT_FOUND] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_OUT_ITEM_NOT_FOUND", + [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PKEY_HASHES_DONT_MATCH] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PKEY_HASHES_DONT_MATCH", + [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX", + [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NO_VERIFICATOR_SET] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NO_VERIFICATOR_SET", + [DAP_CHAIN_LEDGER_TX_CACHE_VERIFICATOR_CHECK_FAILURE] = "DAP_CHAIN_LEDGER_TX_CACHE_VERIFICATOR_CHECK_FAILURE", + [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TICKER_NOT_FOUND] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TICKER_NOT_FOUND", + [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TOKEN_NOT_FOUND] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TOKEN_NOT_FOUND", + [DAP_CHAIN_LEDGER_PERMISSION_CHECK_FAILED] = "DAP_CHAIN_LEDGER_PERMISSION_CHECK_FAILED" +}; + +static const char *s_ledger_emission_add_err_str[] = { + [DAP_CHAIN_LEDGER_EMISSION_ADD_OK] = "DAP_CHAIN_LEDGER_EMISSION_ADD_OK", + [DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_EMS_IS_NULL] = "DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_EMS_IS_NULL", + [DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_EMS_ALREADY_CACHED] = "DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_EMS_ALREADY_CACHED", + [DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_OVERFLOW] = "DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_OVERFLOW", + [DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_VALUE_EXEEDS_CURRENT_SUPPLY] = "DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_VALUE_EXEEDS_CURRENT_SUPPLY", + [DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_NOT_ENOUGH_VALID_SIGNS] = "DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_NOT_ENOUGH_VALID_SIGNS", + [DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN] = "DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN", + [DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_ZERO_VALUE] = "DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_ZERO_VALUE", + [DAP_CHAIN_LEDGER_EMISSION_ADD_TSD_CHECK_FAILED] = "DAP_CHAIN_LEDGER_EMISSION_ADD_TSD_CHECK_FAILED" +}; + +static const char *s_ledger_token_decl_err_str[] = { + [DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_OK] = "DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_OK", + [DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_LEDGER_IS_NULL] = "DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_LEDGER_IS_NULL", + [DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_DECL_DUPLICATE] = "DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_DECL_DUPLICATE", + [DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_CHECK] = "DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_CHECK", + [DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_ABSENT_TOKEN] = "DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_ABSENT_TOKEN", + [DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_NOT_ENOUGH_VALID_SIGN] = "DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_NOT_ENOUGH_VALID_SIGN", + [DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOTAL_SIGNS_EXCEED_UNIQUE_SIGNS] = "DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOTAL_SIGNS_EXCEED_UNIQUE_SIGNS" +}; + +char *dap_chain_ledger_tx_check_err_str(int a_code) { + return (a_code >= DAP_CHAIN_LEDGER_TX_CHECK_OK) && (a_code < DAP_CHAIN_LEDGER_TX_CHECK_UNKNOWN) + ? (char*)s_ledger_tx_check_err_str[(dap_chain_ledger_tx_check_t)a_code] + : dap_itoa(a_code); } typedef struct dap_chain_ledger_stake_lock_item { @@ -271,6 +278,7 @@ typedef struct dap_ledger_private { const char *net_native_ticker; uint256_t fee_value; dap_chain_addr_t fee_addr; + dap_list_t *poa_certs; // List of ledger - unspent transactions cache dap_chain_ledger_tx_item_t *threshold_txs; dap_chain_ledger_token_emission_item_t * threshold_emissions; @@ -316,6 +324,12 @@ typedef struct dap_ledger_private { } dap_ledger_private_t; #define PVT(a) ( (dap_ledger_private_t* ) a->_internal ) +typedef struct dap_ledger_hal_item { + dap_chain_hash_fast_t hash; + UT_hash_handle hh; +} dap_ledger_hal_item_t; + +static dap_ledger_hal_item_t *s_hal_items = NULL; static dap_chain_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr, const char * a_token, dap_chain_hash_fast_t *a_tx_first_hash); @@ -380,9 +394,17 @@ void dap_chain_ledger_deinit() static dap_ledger_t * dap_chain_ledger_handle_new(void) { dap_ledger_t *l_ledger = DAP_NEW_Z(dap_ledger_t); + if ( !l_ledger ) { + log_it(L_ERROR, "Memory allocation error in dap_chain_ledger_handle_new, errno=%d", errno); + return NULL; + } dap_ledger_private_t * l_ledger_pvt; l_ledger->_internal = l_ledger_pvt = DAP_NEW_Z(dap_ledger_private_t); - + if ( !l_ledger_pvt ) { + log_it(L_ERROR, "Memory allocation error in dap_chain_ledger_handle_new, errno=%d", errno); + DAP_DELETE(l_ledger); + return NULL; + } // Initialize Read/Write Lock Attribute pthread_rwlock_init(&l_ledger_pvt->ledger_rwlock, NULL); pthread_rwlock_init(&l_ledger_pvt->tokens_rwlock, NULL); @@ -433,6 +455,8 @@ struct json_object *wallet_info_json_collect(dap_ledger_t *a_ledger, dap_ledger_ if (pos) { size_t l_addr_len = pos - a_bal->key; char *l_addr_str = DAP_NEW_STACK_SIZE(char, l_addr_len + 1); + if ( !l_addr_str ) + return log_it(L_ERROR, "Memory allocation error in wallet_info_json_collect, errno=%d", errno), NULL; memcpy(l_addr_str, a_bal->key, pos - a_bal->key); *(l_addr_str + l_addr_len) = '\0'; json_object_object_add(l_network, "address", json_object_new_string(l_addr_str)); @@ -475,7 +499,7 @@ static bool s_ledger_token_update_check(dap_chain_ledger_token_item_t *a_cur_tok if (l_token_update_item && a_cur_token_item->last_update_token_time == l_token_update_item->updated_time) { if (s_debug_more) - log_it(L_WARNING,"This upadate already applied for token with ticker '%s' ", a_token_update->ticker); + log_it(L_WARNING,"This update for token '%s' was already applied", a_token_update->ticker); return false; } @@ -755,32 +779,16 @@ int dap_chain_ledger_token_decl_add_check(dap_ledger_t *a_ledger, dap_chain_datu } else { log_it(L_WARNING, "The number of unique token signs %zu is less than total token signs set to %hu.", l_signs_unique, a_token->signs_total); - return DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_UNIQUE_SIGNS_LESS_TOTAL_SIGNS; + return DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOTAL_SIGNS_EXCEED_UNIQUE_SIGNS; } -// dap_sign_t **l_signs = dap_sign_get_unique_signs(a_token->data_n_tsd, a_token->header_native_decl. // Checks passed return DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_OK; } char *dap_chain_ledger_token_decl_add_err_code_to_str(int a_code) { - switch (a_code) { - case DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_OK: - return dap_strdup("DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_OK"); - case DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_LEDGER_IS_NULL: - return dap_strdup("DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_LEDGER_IS_NULL"); - case DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_DECL_DUPLICATE: - return dap_strdup("DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_DECL_DUPLICATE"); - case DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_CHECK: - return dap_strdup("DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_CHECK"); - case DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_ABSENT_TOKEN: - return dap_strdup("DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_ABSENT_TOKEN"); - case DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_NOT_ENOUGH_VALID_SIGN: - return dap_strdup("DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_NOT_ENOUGH_VALID_SIGN"); - case DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_UNIQUE_SIGNS_LESS_TOTAL_SIGNS: - return dap_strdup("DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_UNIQUE_SIGNS_LESS_TOTAL_SIGNS"); - default: - return dap_strdup_printf("Code error added datum in ledger: %d - has no string representation.", a_code); - } + return (a_code >= DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_OK) && (a_code < DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_UNKNOWN) + ? (char*)s_ledger_token_decl_err_str[(dap_chain_ledger_token_decl_add_err_t)a_code] + : dap_itoa(a_code); } /** @@ -992,6 +1000,10 @@ void s_ledger_token_cache_update(dap_ledger_t *a_ledger, dap_chain_ledger_token_ char *l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_TOKENS_STR); size_t l_cache_size = l_token_item->datum_token_size + sizeof(uint256_t); uint8_t *l_cache = DAP_NEW_STACK_SIZE(uint8_t, l_cache_size); + if ( !l_cache ) { + log_it(L_ERROR, "Memory allocation error in s_ledger_token_cache_update, errno=%d", errno); + return; + } memcpy(l_cache, &l_token_item->current_supply, sizeof(uint256_t)); memcpy(l_cache + sizeof(uint256_t), l_token_item->datum_token, l_token_item->datum_token_size); if (dap_global_db_set(l_gdb_group, l_token_item->ticker, l_cache, l_cache_size, false, NULL, NULL)) { @@ -1071,43 +1083,6 @@ int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t * return -1; } - bool update_token = false; - if (a_token->type == DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE) - update_token = true; - - - dap_chain_ledger_token_item_t *l_token_item; - pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock); - HASH_FIND_STR(PVT(a_ledger)->tokens, a_token->ticker, l_token_item); - pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock); - - if (l_token_item != NULL) { - if (update_token == false) { - log_it(L_WARNING, "Duplicate token declaration for ticker '%s' ", a_token->ticker); - return -3; - } else if (s_ledger_token_update_check(l_token_item, a_token, a_token_size) == true) { - if (s_ledger_update_token_add_in_hash_table(l_token_item, a_token, a_token_size) == false) { - if (s_debug_more) - log_it(L_ERROR, "Failed to add ticker '%s' to hash-table", a_token->ticker); - return -5; - } - if (!IS_ZERO_256(a_token->total_supply)) { - SUBTRACT_256_256(l_token_item->total_supply, l_token_item->current_supply, - &l_token_item->current_supply); - SUBTRACT_256_256(a_token->total_supply, l_token_item->current_supply, &l_token_item->current_supply); - } else { - l_token_item->current_supply = a_token->total_supply; - } - l_token_item->total_supply = a_token->total_supply; - DAP_DEL_Z(l_token_item->datum_token); - } else { - return -2; - } - } else if (l_token_item == NULL && update_token == true) { - log_it(L_WARNING, "Can't update token that doesn't exist for ticker '%s' ", a_token->ticker); - return -6; - } - dap_chain_datum_token_t *l_token = NULL; size_t l_token_size = a_token_size; @@ -1122,143 +1097,194 @@ int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t * break; default: l_token = DAP_DUP_SIZE(a_token, a_token_size); + if ( !l_token ) { + log_it(L_ERROR, "Memory allocation error in dap_chain_ledger_token_add"); + return -6; + } break; } - if (update_token == false) {//create new token - l_token_item = DAP_NEW_Z(dap_chain_ledger_token_item_t); - snprintf(l_token_item->ticker, sizeof(l_token_item->ticker), "%s", l_token->ticker); - pthread_rwlock_init(&l_token_item->token_emissions_rwlock, NULL); - pthread_rwlock_init(&l_token_item->token_ts_updated_rwlock, NULL); - l_token_item->type = l_token->type; - l_token_item->subtype = l_token->subtype; - l_token_item->total_supply = l_token->total_supply; - l_token_item->current_supply = l_token_item->total_supply; - l_token_item->auth_signs_total = l_token->signs_total; - l_token_item->auth_signs_valid = l_token->signs_valid; - dap_sign_t **l_signs = dap_chain_datum_token_signs_parse(a_token, a_token_size, - &l_token_item->auth_signs_total, - &l_token_item->auth_signs_valid); - if (l_token_item->auth_signs_total) { - l_token_item->auth_pkeys = DAP_NEW_Z_SIZE(dap_pkey_t*, sizeof(dap_pkey_t*) * l_token_item->auth_signs_total); - l_token_item->auth_pkeys_hash = DAP_NEW_Z_SIZE(dap_chain_hash_fast_t, sizeof(dap_chain_hash_fast_t) * l_token_item->auth_signs_total);; - for (uint16_t k = 0; k < l_token_item->auth_signs_total; k++) { - l_token_item->auth_pkeys[k] = dap_pkey_get_from_sign_deserialization(l_signs[k]); - dap_pkey_get_hash(l_token_item->auth_pkeys[k], &l_token_item->auth_pkeys_hash[k]); + dap_chain_ledger_token_item_t *l_token_item; + pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock); + HASH_FIND_STR(PVT(a_ledger)->tokens, l_token->ticker, l_token_item); + pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock); + + if (l_token_item) { + if (l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE) { + log_it(L_ERROR, "Duplicate token declaration for ticker '%s'", l_token->ticker); + return -3; + } + if (s_ledger_token_update_check(l_token_item, l_token, l_token_size)) { + if (!s_ledger_update_token_add_in_hash_table(l_token_item, l_token, l_token_size)) { + log_it(L_ERROR, "Failed to update token with ticker '%s' in ledger", l_token->ticker); + return -5; + } + if (!IS_ZERO_256(l_token->total_supply)) { + SUBTRACT_256_256(l_token_item->total_supply, l_token_item->current_supply, &l_token_item->current_supply); + SUBTRACT_256_256(l_token->total_supply, l_token_item->current_supply, &l_token_item->current_supply); + } else { + l_token_item->current_supply = l_token->total_supply; } + l_token_item->total_supply = l_token->total_supply; + DAP_DELETE(l_token_item->datum_token); + } else { + log_it(L_ERROR, "Token with ticker '%s' update check failed", l_token->ticker); + return -2; } + } else if (l_token->type == DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE) { + log_it(L_WARNING, "Token with ticker '%s' does not yet exist, declare it first", l_token->ticker); + return -6; } - l_token_item->datum_token_size = l_token_size; - l_token_item->datum_token = DAP_DUP_SIZE(l_token, l_token_size); - l_token_item->datum_token->type = l_token_item->type; + if (!l_token_item) { + size_t l_auth_signs_total, l_auth_signs_valid; + dap_sign_t **l_signs = dap_chain_datum_token_signs_parse(l_token, l_token_size, &l_auth_signs_total, &l_auth_signs_valid); + if (!l_signs || !l_auth_signs_total) { + log_it(L_ERROR, "No auth signs in token '%s' datum!", l_token->ticker); + DAP_DELETE(l_token); + return -7; + } + l_token_item = DAP_NEW_Z(dap_chain_ledger_token_item_t); + if ( !l_token_item ) { + if (l_token) + DAP_DELETE(l_token); + log_it(L_ERROR, "Memory allocation error in dap_chain_ledger_token_add"); + return -8; + } + *l_token_item = (dap_chain_ledger_token_item_t) { + .version = l_token->version, + .type = l_token->type, + .subtype = l_token->subtype, + .total_supply = l_token->total_supply, + .current_supply = l_token->total_supply, + .token_emissions_rwlock = PTHREAD_RWLOCK_INITIALIZER, + .token_ts_updated_rwlock = PTHREAD_RWLOCK_INITIALIZER, + .auth_pkeys = DAP_NEW_Z_SIZE(dap_pkey_t*, sizeof(dap_pkey_t*) * l_token->signs_total), + .auth_pkeys_hash = DAP_NEW_Z_SIZE(dap_chain_hash_fast_t, sizeof(dap_chain_hash_fast_t) * l_token->signs_total), + .auth_signs_total = l_auth_signs_total, + .auth_signs_valid = l_auth_signs_valid + }; + if ( !l_token_item->auth_pkeys ) { + if (l_token) + DAP_DELETE(l_token); + DAP_DELETE(l_token_item); + log_it(L_ERROR, "Memory allocation error in dap_chain_ledger_token_add"); + return -6; + }; + if ( !l_token_item->auth_pkeys ) { + if (l_token) + DAP_DELETE(l_token); + DAP_DEL_Z(l_token_item->auth_pkeys); + DAP_DELETE(l_token_item); + log_it(L_ERROR, "Memory allocation error in dap_chain_ledger_token_add"); + return -6; + } + dap_stpcpy(l_token_item->ticker, l_token->ticker); + for (uint16_t k = 0; k < l_token_item->auth_signs_total; k++) { + l_token_item->auth_pkeys[k] = dap_pkey_get_from_sign_deserialization(l_signs[k]); + dap_pkey_get_hash(l_token_item->auth_pkeys[k], &l_token_item->auth_pkeys_hash[k]); + } + DAP_DELETE(l_signs); + } + + + l_token_item->datum_token_size = l_token_size; + l_token_item->datum_token = l_token; + l_token_item->datum_token->type = l_token->type; - if (update_token == false) { + if (l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE) { pthread_rwlock_wrlock(&PVT(a_ledger)->tokens_rwlock); HASH_ADD_STR(PVT(a_ledger)->tokens, ticker, l_token_item); pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock); } int l_res_token_tsd_parse = 0; + char *l_balance_dbg = s_debug_more ? dap_chain_balance_to_coins(l_token->total_supply) : NULL; + +#define CLEAN_UP do { DAP_DELETE(l_token); \ + DAP_DELETE(l_token_item->auth_pkeys); \ + DAP_DELETE(l_token_item->auth_pkeys_hash); \ + DAP_DELETE(l_token_item); \ + DAP_DELETE(l_balance_dbg); } while (0); + switch (l_token->type) { - case DAP_CHAIN_DATUM_TOKEN_TYPE_DECL: { - switch (l_token->subtype) { - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_SIMPLE: { - if (s_debug_more) { - char *l_balance = dap_chain_balance_to_coins(l_token->total_supply); - log_it(L_NOTICE, - "Simple token %s added (total_supply = %s total_signs_valid=%hu signs_total=%hu)", - l_token->ticker, l_balance, - l_token->signs_valid, l_token->signs_total); - DAP_DEL_Z(l_balance); - } - } - break; - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE: { - if (s_debug_more) { - char *l_balance = dap_chain_balance_to_coins(l_token->total_supply); - log_it(L_NOTICE, - "Private token %s added (total_supply = %s total_signs_valid=%hu signs_total=%hu)", - l_token->ticker, l_balance, - l_token->signs_valid, l_token->signs_total); - DAP_DEL_Z(l_balance); - } - l_res_token_tsd_parse = s_token_tsd_parse(a_ledger, l_token_item, l_token, l_token_size); - } - break; - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: { - if (s_debug_more) { - char *l_balance = dap_chain_balance_to_coins(l_token->total_supply); - log_it(L_NOTICE, - "CF20 token %s added (total_supply = %s total_signs_valid=%hu signs_total=%hu)", - l_token->ticker, l_balance, - l_token->signs_valid, l_token->signs_total); - DAP_DELETE(l_balance); - } - l_res_token_tsd_parse = s_token_tsd_parse(a_ledger, l_token_item, l_token, l_token_size); - } - break; - } - } + case DAP_CHAIN_DATUM_TOKEN_TYPE_DECL: + switch (l_token->subtype) { + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_SIMPLE: + debug_if(s_debug_more, L_INFO, "Simple token %s declared, total_supply: %s, total_signs_valid: %hu, signs_total: %hu", + l_token->ticker, l_balance_dbg, + l_token->signs_valid, l_token->signs_total); break; - case DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE: { - switch (l_token->subtype) { - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_SIMPLE: { - if (s_debug_more) { - char *l_balance = dap_chain_balance_to_coins(l_token->total_supply); - log_it(L_NOTICE, - "Simple token %s update (total_supply = %s total_signs_valid=%hu signs_total=%hu)", - l_token->ticker, l_balance, - l_token->signs_valid, l_token->signs_total); - DAP_DEL_Z(l_balance); - } - } - break; - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE: { - if (s_debug_more) { - char *l_balance = dap_chain_balance_to_coins(l_token->total_supply); - log_it(L_NOTICE, - "Private token %s updated (total_supply = %s total_signs_valid=%hu signs_total=%hu)", - l_token->ticker, l_balance, - l_token->signs_valid, l_token->signs_total); - DAP_DEL_Z(l_balance); - } - l_res_token_tsd_parse = s_token_tsd_parse(a_ledger, l_token_item, l_token, l_token_size); - s_tsd_sign_apply(a_ledger, l_token_item, a_token, a_token_size); - } - break; - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: { - if (s_debug_more) { - char *l_balance = dap_chain_balance_to_coins(l_token->total_supply); - log_it(L_NOTICE, - "CF20 token %s updated (total_supply = %s total_signs_valid=%hu signs_total=%hu)", - l_token->ticker, l_balance, - l_token->signs_valid, l_token->signs_total); - DAP_DEL_Z(l_balance); - } - l_res_token_tsd_parse = s_token_tsd_parse(a_ledger, l_token_item, l_token, l_token_size); - s_tsd_sign_apply(a_ledger, l_token_item, a_token, a_token_size); - } - break; - } - } + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE: + debug_if(s_debug_more, L_INFO, "Private token %s declared, total_supply: %s, total_signs_valid: %hu, signs_total: %hu", + l_token->ticker, l_balance_dbg, + l_token->signs_valid, l_token->signs_total); + l_res_token_tsd_parse = s_token_tsd_parse(a_ledger, l_token_item, l_token, l_token_size); + s_tsd_sign_apply(a_ledger, l_token_item, l_token, l_token_size); + break; + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: + debug_if(s_debug_more, L_INFO, "CF20 token %s declared, total_supply: %s, total_signs_valid: %hu, signs_total: %hu", + l_token->ticker, l_balance_dbg, + l_token->signs_valid, l_token->signs_total); + l_res_token_tsd_parse = s_token_tsd_parse(a_ledger, l_token_item, l_token, l_token_size); + s_tsd_sign_apply(a_ledger, l_token_item, l_token, l_token_size); break; default: - if (s_debug_more) - log_it(L_WARNING, "Unknown token declaration type 0x%04X", l_token->type); + /* Bogdanoff, unknown token subtype declaration. What shall we TODO? */ + debug_if(s_debug_more, L_ERROR, "Unknown token subtype '0x%04X' declaration! Ticker: %s, total_supply: %s, total_signs_valid: %hu, signs_total: %hu" + "Dump it!", + l_token->type, l_token->ticker, l_balance_dbg, + l_token->signs_valid, l_token->signs_total); + /* Dump it right now */ + CLEAN_UP; + return -8; + } break; + case DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE: + switch (l_token->subtype) { + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_SIMPLE: + debug_if(s_debug_more, L_INFO, "Simple token %s updated, total_supply: %s, total_signs_valid: %hu, signs_total: %hu", + l_token->ticker, l_balance_dbg, + l_token->signs_valid, l_token->signs_total); + break; + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE: + debug_if(s_debug_more, L_INFO, "Private token %s updated, total_supply: %s, total_signs_valid: %hu, signs_total: %hu", + l_token->ticker, l_balance_dbg, + l_token->signs_valid, l_token->signs_total); + l_res_token_tsd_parse = s_token_tsd_parse(a_ledger, l_token_item, l_token, l_token_size); + s_tsd_sign_apply(a_ledger, l_token_item, l_token, l_token_size); break; + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: + debug_if(s_debug_more, L_INFO, "CF20 token %s updated, total_supply: %s, total_signs_valid: %hu, signs_total: %hu", + l_token->ticker, l_balance_dbg, + l_token->signs_valid, l_token->signs_total); + l_res_token_tsd_parse = s_token_tsd_parse(a_ledger, l_token_item, l_token, l_token_size); + s_tsd_sign_apply(a_ledger, l_token_item, l_token, l_token_size); + break; + default: + /* Bogdanoff, unknown token type update. What shall we TODO? */ + debug_if(s_debug_more, L_ERROR, "Unknown token subtype '0x%04X' update! Ticker: %s, total_supply: %s, total_signs_valid: %hu, signs_total: %hu" + "Dump it!", + l_token->type, l_token->ticker, l_balance_dbg, + l_token->signs_valid, l_token->signs_total); + /* Dump it right now */ + CLEAN_UP; + return -8; + } break; + default: + debug_if(s_debug_more, L_ERROR, "Unknown token type 0x%04X, Dump it!", l_token->type); + CLEAN_UP; + return -8; } if (l_res_token_tsd_parse) { - if (s_debug_more) { - log_it(L_ERROR, "Can't parse tsd section for %s token, code error: %i", l_token->ticker, l_res_token_tsd_parse); - } + debug_if(s_debug_more, L_ERROR, "Can't parse tsd section for %s token, code error: %i", l_token->ticker, l_res_token_tsd_parse); + CLEAN_UP; return -1; } - s_threshold_emissions_proc(a_ledger); //TODO process thresholds only for no-consensus chains +#undef CLEAN_UP + DAP_DELETE(l_balance_dbg); + s_threshold_emissions_proc(a_ledger); /* TODO process thresholds only for no-consensus chains */ if (PVT(a_ledger)->cached) s_ledger_token_cache_update(a_ledger, l_token_item); - if (a_token->type == DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_SIMPLE) - DAP_DELETE(l_token); return 0; } @@ -1299,7 +1325,7 @@ static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_ite // unset flags case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_UNSET_FLAGS:{ - a_token_item->flags ^= dap_tsd_get_scalar(l_tsd,uint16_t); + a_token_item->flags &= ~dap_tsd_get_scalar(l_tsd,uint16_t); }break; // set total supply @@ -1606,7 +1632,8 @@ static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_ite if(s_debug_more) log_it(L_ERROR,"Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD (code %d)", l_add_addr_check); - DAP_DELETE(l_addrs); + if (l_addrs) + DAP_DELETE(l_addrs); return -12; } // Check if its already present @@ -1617,7 +1644,8 @@ static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_ite log_it(L_ERROR,"TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD has address %s thats already present in list", l_addr_str); DAP_DELETE(l_addr_str); - DAP_DELETE(l_addrs); + if (l_addrs) + DAP_DELETE(l_addrs); return -11; } } @@ -1761,12 +1789,11 @@ static int s_tsd_sign_apply(dap_ledger_t *a_ledger, dap_chain_ledger_token_item_ int dap_chain_ledger_token_load(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token, size_t a_token_size) { if (PVT(a_ledger)->load_mode) { - bool l_update_token = (a_token->type == DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE); dap_chain_ledger_token_item_t *l_token_item; pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock); HASH_FIND_STR(PVT(a_ledger)->tokens, a_token->ticker, l_token_item); pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock); - if (l_token_item && l_update_token == false) + if (l_token_item && a_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE) return 0; } return dap_chain_ledger_token_add(a_ledger, a_token, a_token_size); @@ -1966,7 +1993,7 @@ dap_list_t *dap_chain_ledger_token_info(dap_ledger_t *a_ledger) const char *l_type_str; const char *l_flags_str = s_flag_str_from_code(l_token_item->datum_token->header_private_decl.flags); switch (l_token_item->type) { - case DAP_CHAIN_DATUM_TOKEN_DECL: { + case DAP_CHAIN_DATUM_TOKEN_TYPE_DECL: { switch (l_token_item->subtype) { case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_SIMPLE: l_type_str = "SIMPLE"; break; @@ -2227,6 +2254,10 @@ static void s_load_cache_gdb_loaded_spent_txs_callback(dap_global_db_context_t * for (size_t i = 0; i < a_values_count; i++) { dap_chain_ledger_tx_spent_item_t *l_tx_spent_item = DAP_NEW_Z(dap_chain_ledger_tx_spent_item_t); + if ( !l_tx_spent_item ) { + log_it(L_ERROR, "Memory allocation error in s_load_cache_gdb_loaded_spent_txs_callback"); + return; + } dap_chain_hash_fast_from_str(a_values[i].key, &l_tx_spent_item->tx_hash_fast); l_tx_spent_item->cache_data = *(typeof(((dap_chain_ledger_tx_spent_item_t*)0)->cache_data)*)a_values[i].value; HASH_ADD(hh, l_ledger_pvt->spent_items, tx_hash_fast, sizeof(dap_chain_hash_fast_t), l_tx_spent_item); @@ -2258,8 +2289,17 @@ static void s_load_cache_gdb_loaded_txs_callback(dap_global_db_context_t *a_glob dap_ledger_private_t * l_ledger_pvt = PVT(l_ledger); for (size_t i = 0; i < a_values_count; i++) { dap_chain_ledger_tx_item_t *l_tx_item = DAP_NEW_Z(dap_chain_ledger_tx_item_t); + if ( !l_tx_item ) { + log_it(L_ERROR, "Memory allocation error in s_load_cache_gdb_loaded_txs_callback"); + return; + } dap_chain_hash_fast_from_str(a_values[i].key, &l_tx_item->tx_hash_fast); l_tx_item->tx = DAP_NEW_Z_SIZE(dap_chain_datum_tx_t, a_values[i].value_len - sizeof(l_tx_item->cache_data)); + if ( !l_tx_item->tx ) { + DAP_DELETE(l_tx_item); + log_it(L_ERROR, "Memory allocation error in s_load_cache_gdb_loaded_txs_callback"); + return; + } memcpy(&l_tx_item->cache_data, a_values[i].value, sizeof(l_tx_item->cache_data)); memcpy(l_tx_item->tx, a_values[i].value + sizeof(l_tx_item->cache_data), a_values[i].value_len - sizeof(l_tx_item->cache_data)); l_tx_item->ts_added = dap_nanotime_now(); @@ -2331,6 +2371,10 @@ static void s_load_cache_gdb_loaded_emissions_callback(dap_global_db_context_t * continue; } dap_chain_ledger_token_emission_item_t *l_emission_item = DAP_NEW_Z(dap_chain_ledger_token_emission_item_t); + if ( !l_emission_item ) { + log_it(L_ERROR, "Memory allocation error in s_load_cache_gdb_loaded_emissions_callback"); + return; + } dap_chain_hash_fast_from_str(a_values[i].key, &l_emission_item->datum_token_emission_hash); l_emission_item->tx_used_out = *(dap_hash_fast_t*)a_values[i].value; l_emission_item->datum_token_emission = DAP_DUP_SIZE(a_values[i].value + sizeof(dap_hash_fast_t), @@ -2427,12 +2471,13 @@ void dap_chain_ledger_load_cache(dap_ledger_t *a_ledger) * @param a_net_name char * network name, for example "kelvin-testnet" * @return dap_ledger_t* */ -dap_ledger_t *dap_chain_ledger_create(uint16_t a_flags, char *a_net_name, const char *a_net_native_ticker) +dap_ledger_t *dap_chain_ledger_create(uint16_t a_flags, char *a_net_name, const char *a_net_native_ticker, dap_list_t *a_poa_certs) { dap_ledger_t *l_ledger = dap_chain_ledger_handle_new(); l_ledger->net_name = a_net_name; dap_ledger_private_t *l_ledger_pvt = PVT(l_ledger); l_ledger_pvt->net_native_ticker = a_net_native_ticker; + l_ledger_pvt->poa_certs = a_poa_certs; l_ledger_pvt->flags = a_flags; l_ledger_pvt->check_ds = a_flags & DAP_CHAIN_LEDGER_CHECK_LOCAL_DS; l_ledger_pvt->check_cells_ds = a_flags & DAP_CHAIN_LEDGER_CHECK_CELLS_DS; @@ -2441,6 +2486,36 @@ dap_ledger_t *dap_chain_ledger_create(uint16_t a_flags, char *a_net_name, const pthread_cond_init(&l_ledger_pvt->load_cond, NULL); pthread_mutex_init(&l_ledger_pvt->load_mutex, NULL); + char * l_chains_path = dap_strdup_printf("%s/network/%s", dap_config_path(), a_net_name); + DIR * l_chains_dir = opendir(l_chains_path); + DAP_DEL_Z(l_chains_path); + + struct dirent * l_dir_entry; + uint8_t i = 0; + while ( (l_dir_entry = readdir(l_chains_dir) )!= NULL ){ + if (l_dir_entry->d_name[0] == '\0') + continue; + char * l_entry_name = dap_strdup(l_dir_entry->d_name); + if (strlen(l_entry_name) > 4) { + if ( strncmp (l_entry_name + strlen(l_entry_name)-4,".cfg",4) == 0 ) { // its .cfg file + l_entry_name [strlen(l_entry_name)-4] = 0; + log_it(L_DEBUG,"Open chain config \"%s\"...",l_entry_name); + l_chains_path = dap_strdup_printf("network/%s/%s", a_net_name, l_entry_name); + dap_config_t * l_cfg = dap_config_open(l_chains_path); + uint16_t l_whitelist_size; + char **l_whitelist = dap_config_get_array_str(l_cfg, "ledger", "hard_accept_list", &l_whitelist_size); + for (uint16_t i = 0; i < l_whitelist_size; ++i) { + dap_ledger_hal_item_t *l_hal_item = DAP_NEW_Z(dap_ledger_hal_item_t); + dap_chain_hash_fast_from_str(l_whitelist[i], &l_hal_item->hash); + HASH_ADD(hh, s_hal_items, hash, sizeof(l_hal_item->hash), l_hal_item); + } + dap_config_close(l_cfg); + log_it(L_DEBUG, "HAL items count for chain %s : %d", l_entry_name, l_whitelist_size); + } + } + DAP_DELETE (l_entry_name); + } + closedir(l_chains_dir); log_it(L_DEBUG,"Created ledger \"%s\"",a_net_name); l_ledger_pvt->load_mode = true; @@ -2465,7 +2540,7 @@ void dap_chain_ledger_set_fee(dap_ledger_t *a_ledger, uint256_t a_fee, dap_chain int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size, dap_chain_hash_fast_t *a_emission_hash) { if (!a_token_emission || !a_token_emission_size) - return DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_ERROR_EMISSION_NULL_OR_IS_EMISSION_SIZE_ZERO; + return DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_EMS_IS_NULL; int l_ret = DAP_CHAIN_LEDGER_EMISSION_ADD_OK; dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); @@ -2476,13 +2551,12 @@ int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_ HASH_FIND_STR(l_ledger_pvt->tokens, l_token_ticker, l_token_item); pthread_rwlock_unlock(&l_ledger_pvt->tokens_rwlock); - dap_chain_ledger_token_emission_item_t * l_token_emission_item = NULL; - if (!l_token_item) { - log_it(L_WARNING, "Ledger_token_emission_add_check. Token ticker %s was not found", l_token_ticker); + log_it(L_ERROR, "Check emission: token %s was not found", l_token_ticker); return DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN; } + dap_chain_ledger_token_emission_item_t * l_token_emission_item = NULL; // check if such emission is already present in table pthread_rwlock_rdlock(l_token_item ? &l_token_item->token_emissions_rwlock : &l_ledger_pvt->threshold_emissions_rwlock); @@ -2505,29 +2579,47 @@ int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_ log_it(L_ERROR, "Can't add token emission datum of %"DAP_UINT64_FORMAT_U" %s ( %s ): already present in cache", l_token_emission_item->datum_token_emission->hdr.value, l_token_ticker, l_token_hash_str); } - l_ret = DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_CAN_NOT_ADDED_EMISSION_ALREADY_IN_CACHE; + l_ret = DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_EMS_ALREADY_CACHED; }else if ( (! l_token_item) && ( l_threshold_emissions_count >= s_threshold_emissions_max)) { if(s_debug_more) - log_it(L_WARNING,"threshold for emissions is overfulled (%zu max)", - s_threshold_emissions_max); - l_ret = DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_EMISSION_OVERFULLED; + log_it(L_WARNING,"Emissions threshold overflow, max %zu items", s_threshold_emissions_max); + l_ret = DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_OVERFLOW; } if (l_ret || !PVT(a_ledger)->check_token_emission) return l_ret; + + if (s_hal_items) { + dap_ledger_hal_item_t *l_hash_found = NULL; + HASH_FIND(hh, s_hal_items, a_emission_hash, sizeof(*a_emission_hash), l_hash_found); + if (l_hash_found) { + char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE] = { '\0' }; + dap_chain_hash_fast_to_str(a_emission_hash, l_hash_str, sizeof(l_hash_str)); + debug_if(s_debug_more, L_MSG, "Event %s is whitelisted", l_hash_str); + return l_ret; + } + } + // Check emission correctness size_t l_emission_size = a_token_emission_size; dap_chain_datum_token_emission_t *l_emission = dap_chain_datum_emission_read(a_token_emission, &l_emission_size); + if (IS_ZERO_256((l_emission->hdr.value_256))) { + log_it(L_ERROR, "Emission check: zero %s emission value", l_token_item->ticker); + DAP_DELETE(l_emission); + return DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_ZERO_VALUE; + } + // if total_supply > 0 we can check current_supply if (!IS_ZERO_256(l_token_item->total_supply)){ if(compare256(l_token_item->current_supply, l_emission->hdr.value_256) < 0) { char *l_balance_cur = dap_chain_balance_print(l_token_item->current_supply); char *l_balance_em = dap_chain_balance_print(l_emission->hdr.value_256); - log_it(L_WARNING, "Ledger_token_emission_add_check. current_supply %s is lower, then l_emission->hdr.value_256: %s", + log_it(L_ERROR, "Emission check: current_supply %s < emission value %s", l_balance_cur, l_balance_em); DAP_DELETE(l_balance_cur); DAP_DELETE(l_balance_em); - return DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_VALUE_MORE_THAN_CURRENT_SUPPLY; + DAP_DELETE(l_emission); + return DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_VALUE_EXEEDS_CURRENT_SUPPLY; } } @@ -2590,7 +2682,10 @@ int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_ l_balance, a_ledger->net_name, l_emission->hdr.ticker, l_aproves, l_aproves_valid); DAP_DELETE(l_balance); } - l_ret = DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_VALID_SIGNS_NOT_ENOUGH; + l_ret = DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_NOT_ENOUGH_VALID_SIGNS; + char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE] = { '\0' }; + dap_chain_hash_fast_to_str(a_emission_hash, l_hash_str, sizeof(l_hash_str)); + log_it(L_MSG, "!!! Datum hash for HAL: %s", l_hash_str); } }else{ if(s_debug_more) @@ -2707,12 +2802,23 @@ static inline int s_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_e { dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); dap_chain_ledger_token_emission_item_t * l_token_emission_item = NULL; + char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; + dap_chain_hash_fast_to_str(a_emission_hash, l_hash_str, sizeof(l_hash_str)); int l_ret = dap_chain_ledger_token_emission_add_check(a_ledger, a_token_emission, a_token_emission_size, a_emission_hash); if (l_ret) { if (l_ret == DAP_CHAIN_CS_VERIFY_CODE_NO_DECREE) { // TODO remove emissions threshold if (HASH_COUNT(l_ledger_pvt->threshold_emissions) < s_threshold_emissions_max) { l_token_emission_item = DAP_NEW_Z(dap_chain_ledger_token_emission_item_t); + if ( !l_token_emission_item ) { + log_it(L_ERROR, "Memory allocation error in s_token_emission_add"); + return DAP_CHAIN_LEDGER_EMISSION_ADD_MEMORY_PROBLEM; + } l_token_emission_item->datum_token_emission = DAP_DUP_SIZE(a_token_emission, a_token_emission_size); + if ( !l_token_emission_item->datum_token_emission ) { + DAP_DELETE(l_token_emission_item); + log_it(L_ERROR, "Memory allocation error in s_token_emission_add"); + return DAP_CHAIN_LEDGER_EMISSION_ADD_MEMORY_PROBLEM; + } l_token_emission_item->datum_token_emission_size = a_token_emission_size; dap_hash_fast_t l_emi_hash = {0}; dap_hash_fast(a_token_emission, a_token_emission_size, &l_emi_hash); @@ -2773,13 +2879,14 @@ static inline int s_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_e } else { char *l_balance = dap_chain_balance_print(l_token_item->current_supply); char *l_value = dap_chain_balance_print(l_emission_value); - log_it(L_WARNING,"Token current supply %s lower, than emission value = %s", - l_balance, l_value); + + log_it(L_WARNING,"Token %s current supply %s < emission value %s", + l_token_item->ticker, l_balance, l_value); DAP_DELETE(l_balance); DAP_DELETE(l_value); DAP_DELETE(l_token_emission_item->datum_token_emission); DAP_DELETE(l_token_emission_item); - return DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_VALUE_MORE_THAN_CURRENT_SUPPLY; + return DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_VALUE_EXEEDS_CURRENT_SUPPLY; } if (PVT(a_ledger)->cached) s_ledger_token_cache_update(a_ledger, l_token_item); @@ -2828,7 +2935,7 @@ static inline int s_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_e if(s_debug_more) log_it(L_WARNING,"threshold for emissions is overfulled (%zu max), dropping down new data, added nothing", s_threshold_emissions_max); - l_ret = DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_EMISSION_OVERFULLED; + l_ret = DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_OVERFLOW; } } else { if (l_token_item) { @@ -2845,7 +2952,7 @@ static inline int s_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_e ((dap_chain_datum_token_emission_t *)a_token_emission)->hdr.value, c_token_ticker, l_hash_str); } } - l_ret = DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_CAN_NOT_ADDED_EMISSION_ALREADY_IN_CACHE; + l_ret = DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_EMS_ALREADY_CACHED; } return l_ret; } @@ -2933,27 +3040,10 @@ int dap_chain_ledger_token_emission_load(dap_ledger_t *a_ledger, byte_t *a_token return dap_chain_ledger_token_emission_add(a_ledger, a_token_emission, a_token_emission_size, a_token_emission_hash, false); } -char *dap_chain_ledger_token_emission_err_code_to_str(dap_chain_ledger_emission_err_code_t a_code) { - switch (a_code) { - case DAP_CHAIN_LEDGER_EMISSION_ADD_OK: - return dap_strdup("DAP_CHAIN_LEDGER_EMISSION_ADD_OK"); - case DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_ERROR_EMISSION_NULL_OR_IS_EMISSION_SIZE_ZERO: - return dap_strdup("DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_ERROR_EMISSION_NULL_OR_IS_EMISSION_SIZE_ZERO"); - case DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_CAN_NOT_ADDED_EMISSION_ALREADY_IN_CACHE: - return dap_strdup("DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_CAN_NOT_ADDED_EMISSION_ALREADY_IN_CACHE"); - case DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_EMISSION_OVERFULLED: - return dap_strdup("DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_EMISSION_OVERFULLED"); - case DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_VALUE_MORE_THAN_CURRENT_SUPPLY: - return dap_strdup("DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_VALUE_MORE_THAN_CURRENT_SUPPLY"); - case DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_VALID_SIGNS_NOT_ENOUGH: - return dap_strdup("DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_VALID_SIGNS_NOT_ENOUGH"); - case DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN: - return dap_strdup("DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN"); - case DAP_CHAIN_LEDGER_EMISSION_ADD_TSD_CHECK_FAILED: - return dap_strdup("DAP_CHAIN_LEDGER_EMISSION_ADD_TSD_CHECK_FAILED"); - default: - return dap_strdup_printf("Code emission error: %d - has no string representation.", a_code); - } +char *dap_chain_ledger_token_emission_err_code_to_str(int a_code) { + return (a_code >= DAP_CHAIN_LEDGER_EMISSION_ADD_OK && a_code < DAP_CHAIN_LEDGER_EMISSION_ADD_UNKNOWN) + ? (char*)s_ledger_emission_add_err_str[(dap_chain_ledger_emission_err_code_t)a_code] + : dap_itoa(a_code); } dap_chain_ledger_token_emission_item_t *s_emission_item_find(dap_ledger_t *a_ledger, @@ -3046,6 +3136,10 @@ void dap_chain_ledger_addr_get_token_ticker_all_depricated(dap_ledger_t *a_ledge if(l_tx_item) { l_tickers_size = 10; l_tickers = DAP_NEW_Z_SIZE(char *, l_tickers_size * sizeof(char*)); + if ( !l_tickers ) { + log_it(L_ERROR, "Memory allocation error in dap_chain_ledger_addr_get_token_ticker_all_depricated"); + return; + } while(l_tx_item) { bool l_is_not_in_list = true; for(size_t i = 0; i < l_tickers_size; i++) { @@ -3060,6 +3154,10 @@ void dap_chain_ledger_addr_get_token_ticker_all_depricated(dap_ledger_t *a_ledge if((l_tickers_pos + 1) == l_tickers_size) { l_tickers_size += (l_tickers_size / 2); l_tickers = DAP_REALLOC(l_tickers, l_tickers_size); + if ( !l_tickers ) { + log_it(L_ERROR, "Memory allocation error in dap_chain_ledger_addr_get_token_ticker_all_depricated"); + return; + } } l_tickers[l_tickers_pos] = dap_strdup(l_tx_item->cache_data.token_ticker); l_tickers_pos++; @@ -3070,6 +3168,10 @@ void dap_chain_ledger_addr_get_token_ticker_all_depricated(dap_ledger_t *a_ledge } l_tickers_size = l_tickers_pos + 1; l_tickers = DAP_REALLOC(l_tickers, l_tickers_size * sizeof(char*)); + if ( !l_tickers ) { + log_it(L_ERROR, "Memory allocation error in dap_chain_ledger_addr_get_token_ticker_all_depricated"); + return; + } } *a_tickers = l_tickers; *a_tickers_size = l_tickers_pos; @@ -3339,10 +3441,23 @@ bool s_tx_match_sign(dap_chain_datum_token_emission_t *a_datum_emission, dap_cha return false; } +static int s_callback_sign_compare(const void *a, const void *b) +{ + return !dap_pkey_match_sign((dap_pkey_t *)a, (dap_sign_t *)b); +} + +bool dap_chain_ledger_tx_poa_signed(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx) +{ + dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_SIG, NULL); + dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_sig); + return dap_list_find_custom(PVT(a_ledger)->poa_certs, l_sign, s_callback_sign_compare); +} + + /** * Checking a new transaction before adding to the cache * - * return 1 OK, -1 error + * return 0 OK, otherwise error */ // Checking a new transaction before adding to the cache int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, @@ -3359,7 +3474,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t dap_chain_hash_fast_to_str(a_tx_hash, l_tx_hash_str, sizeof(l_tx_hash_str)); log_it(L_WARNING, "Transaction %s already present in the cache", l_tx_hash_str); } - return DAP_CHAIN_LEDGER_TX_CACHE_CHECK_INVALID_INPUT_DATA; + return DAP_CHAIN_LEDGER_TX_ALREADY_CACHED; } } /* @@ -3381,7 +3496,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); if(!a_tx){ log_it(L_DEBUG, "NULL transaction, check broken"); - return DAP_CHAIN_LEDGER_TX_CACHE_CHECK_INVALID_INPUT_DATA; + return DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NULL_TX; } dap_list_t *l_list_bound_items = NULL; @@ -3398,12 +3513,12 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t dap_chain_hash_fast_t *l_emission_hash = NULL; // check all previous transactions - int l_err_num = 0; + int l_err_num = DAP_CHAIN_LEDGER_TX_CHECK_OK; int l_prev_tx_count = 0; // 1. Verify signature in current transaction if (!a_from_threshold && dap_chain_datum_tx_verify_sign(a_tx) != 1) - return DAP_CHAIN_LEDGER_TX_CACHE_CHECK_INVALID_SIGN_TX; + return DAP_CHAIN_LEDGER_TX_CACHE_CHECK_INVALID_TX_SIGN; // ---------------------------------------------------------------- // find all 'in' & conditional 'in' items in current transaction @@ -3411,7 +3526,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t &l_prev_tx_count); if (!l_list_in) { log_it(L_WARNING, "Tx check: no valid inputs found"); - return DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TX_NO_VALID_TNPUTS_FOUND; + return DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TX_NO_VALID_INPUTS; } dap_chain_ledger_tx_bound_t *bound_item; dap_chain_hash_fast_t l_hash_pkey = {}; @@ -3420,6 +3535,22 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t dap_list_t *l_list_tmp = l_list_in; for (int l_list_tmp_num = 0; l_list_tmp; l_list_tmp = dap_list_next(l_list_tmp), l_list_tmp_num++) { bound_item = DAP_NEW_Z(dap_chain_ledger_tx_bound_t); + if (!bound_item) { + log_it(L_ERROR, "Memory allocation error in dap_chain_ledger_tx_cache_check"); + if ( l_list_bound_items ) + dap_list_free_full(l_list_bound_items, NULL); + if (l_list_tx_out) + dap_list_free(l_list_tx_out); + HASH_ITER(hh, l_values_from_prev_tx, l_value_cur, l_tmp) { + HASH_DEL(l_values_from_prev_tx, l_value_cur); + DAP_DELETE(l_value_cur); + } + HASH_ITER(hh, l_values_from_cur_tx, l_value_cur, l_tmp) { + HASH_DEL(l_values_from_cur_tx, l_value_cur); + DAP_DELETE(l_value_cur); + } + return -1; + } dap_chain_tx_in_t *l_tx_in = NULL; dap_chain_addr_t l_tx_in_from={0}; dap_chain_tx_in_cond_t *l_tx_in_cond = NULL; @@ -3465,7 +3596,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t // check AUTH token emission if (!dap_hash_fast_is_blank(&l_emission_item->tx_used_out)) { debug_if(s_debug_more, L_WARNING, "Emission for IN_EMS [%s] is already used", l_tx_in_ems->header.ticker); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TX_NO_VALID_TNPUTS_FOUND; + l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_IN_EMS_ALREADY_USED; break; } bound_item->item_emission = l_emission_item; @@ -3481,14 +3612,14 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t debug_if(s_debug_more, L_WARNING, "stake_lock_emission already present in cache for IN_EMS [%s]", l_token); else debug_if(s_debug_more, L_WARNING, "stake_lock_emission is used out for IN_EMS [%s]", l_token); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TX_NO_VALID_TNPUTS_FOUND; + l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_IN_EMS_ALREADY_USED; break; } l_tx_stake_lock = dap_chain_ledger_tx_find_by_hash(a_ledger, l_emission_hash); } else { if (l_girdled_ems_used) { // Only one allowed item with girdled emission debug_if(s_debug_more, L_WARNING, "stake_lock_emission is used out for IN_EMS [%s]", l_token); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TX_NO_VALID_TNPUTS_FOUND; + l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_IN_EMS_ALREADY_USED; break; } else l_girdled_ems_used = true; @@ -3504,8 +3635,8 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t HASH_FIND_STR(PVT(a_ledger)->tokens, l_token, l_delegated_item); pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock); if (!l_delegated_item) { - debug_if(s_debug_more, L_WARNING, "Token [%s] no found", l_token); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NOT_FOUND_TOKEN; + debug_if(s_debug_more, L_WARNING, "Token [%s] not found", l_token); + l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TICKER_NOT_FOUND; break; } dap_chain_datum_token_t *l_datum_token = l_delegated_item->datum_token; @@ -3514,13 +3645,13 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t l_datum_token->header_native_decl.tsd_total_size, DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DELEGATE_EMISSION_FROM_STAKE_LOCK))) { debug_if(s_debug_more, L_WARNING, "Token [%s] not valid for stake_lock transaction", l_token); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TOKEN_NOT_VALID_STAKE_LOCK; + l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_INVALID_TOKEN; break; } dap_chain_datum_token_tsd_delegate_from_stake_lock_t *l_tsd_section = dap_tsd_get_object(l_tsd, dap_chain_datum_token_tsd_delegate_from_stake_lock_t); if (!dap_chain_ledger_token_ticker_check(a_ledger, (char *)l_tsd_section->ticker_token_from)) { - debug_if(s_debug_more, L_WARNING, "Token [%s] no found", l_tsd_section->ticker_token_from); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NOT_FOUND_TOKEN; + debug_if(s_debug_more, L_WARNING, "Token [%s] not found", l_tsd_section->ticker_token_from); + l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TICKER_NOT_FOUND; break; } @@ -3530,7 +3661,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t dap_chain_tx_out_cond_t *l_tx_stake_lock_out_cond = dap_chain_datum_tx_out_cond_get(l_tx_stake_lock, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK, NULL); if (!l_tx_stake_lock_out_cond) { debug_if(s_debug_more, L_WARNING, "No OUT_COND of stake_lock subtype for IN_EMS [%s]", l_tx_in_ems->header.ticker); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NO_OUT_COND_STAKE_LOCK_FROM_IN_EMS; + l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_NO_OUT_COND_FOR_IN_EMS; break; } uint256_t l_value_expected ={}; @@ -3543,7 +3674,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t DAP_DEL_Z(l_emission_rate_str); DAP_DEL_Z(l_locked_value_str); } - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_MULTIPLICATION_OVERFLOW_EMISSION_LOCKED_EMISSION_RATE; + l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_MULT256_OVERFLOW_EMS_LOCKED_X_RATE; break; } dap_chain_tx_out_ext_t *l_tx_out_ext = NULL; @@ -3564,7 +3695,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t dap_chain_tx_out_t *l_tx_out = (dap_chain_tx_out_t *)dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_OUT, NULL); if (!l_tx_out) { debug_if(true, L_WARNING, "Can't find OUT nor OUT_EXT item for base TX with IN_EMS [%s]", l_tx_in_ems->header.ticker); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NOT_FIND_OUT_NOR_OUT_EXT_BASE_TX_IN_EMS; + l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_NO_OUT_ITEMS_FOR_BASE_TX; break; } else l_stake_lock_ems_value = l_tx_out->header.value; @@ -3574,36 +3705,36 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t compare256(l_delegated_item->current_supply, l_stake_lock_ems_value) < 0) { char *l_balance = dap_chain_balance_print(l_delegated_item->current_supply); char *l_value_ch = dap_chain_balance_print(l_stake_lock_ems_value); - log_it(L_WARNING, "Token current supply %s lower, than emission value = %s", + log_it(L_WARNING, "Token current supply %s < emission value %s", l_balance, l_value_ch); DAP_DEL_Z(l_balance); DAP_DEL_Z(l_value_ch); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TOKEN_CURRENT_SUPPLY_LOWER_EMISSION_VALUE; + l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TOKEN_EMS_VALUE_EXEEDS_CUR_SUPPLY; break; } if (!EQUAL_256(l_value_expected, l_stake_lock_ems_value)) { char *l_value_expected_str = dap_chain_balance_print(l_value_expected); char *l_locked_value_str = dap_chain_balance_print(l_stake_lock_ems_value); - debug_if(s_debug_more, L_WARNING, "Value %s not thats expected %s for [%s]",l_locked_value_str, l_value_expected_str, + debug_if(s_debug_more, L_WARNING, "Value %s != %s expected for [%s]",l_locked_value_str, l_value_expected_str, l_tx_in_ems->header.ticker); DAP_DEL_Z(l_value_expected_str); DAP_DEL_Z(l_locked_value_str); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_VALUE_NOT_THATS_EXPECTED_IN_EMS; + l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_UNEXPECTED_VALUE; break; } if (!l_girdled_ems) { // check tiker const char *l_tx_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(a_ledger, l_emission_hash); if (!l_tx_ticker) { - debug_if(s_debug_more, L_WARNING, "No ticker found for sake_lock tx [wait %s]", l_tx_in_ems->header.ticker); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NOT_FOUND_TICKER_FOR_STAKE_LOCK; + debug_if(s_debug_more, L_WARNING, "No ticker found for stake_lock tx [expected '%s']", l_tx_in_ems->header.ticker); + l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_TICKER_NOT_FOUND; break; } if (strcmp(l_tx_ticker, (char *)l_tsd_section->ticker_token_from)) { - debug_if(s_debug_more, L_WARNING, "Ticker %s in different for expected %s", l_tx_ticker, l_tx_in_ems->header.ticker); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TICKER_DIFFERENT_EXPECTED; + debug_if(s_debug_more, L_WARNING, "Ticker '%s' != expected '%s'", l_tx_ticker, l_tx_in_ems->header.ticker); + l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_OTHER_TICKER_EXPECTED; break; } } @@ -3635,14 +3766,14 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t // 2. Check if out in previous transaction has spent int l_idx = (l_cond_type == TX_ITEM_TYPE_IN) ? l_tx_in->header.tx_out_prev_idx : l_tx_in_cond->header.tx_out_prev_idx; if (s_ledger_tx_hash_is_used_out_item(l_item_out, l_idx)) { - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NOT_USED_OUT_ITEM; + l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_OUT_ITEM_ALREADY_USED; break; } // Get one 'out' item in previous transaction bound with current 'in' item l_tx_prev_out = dap_chain_datum_tx_item_get_nth(l_tx_prev, TX_ITEM_TYPE_OUT_ALL, l_idx); if(!l_tx_prev_out) { - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NOT_FIND_PREV_OUT_TX; + l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_OUT_ITEM_NOT_FOUND; break; } // 3. Compare out in previous transaction with currently used out @@ -3650,7 +3781,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t dap_chain_ledger_tx_bound_t *l_bound_tmp = it->data; if (l_tx_prev_out == l_bound_tmp->out.tx_prev_out) { debug_if(s_debug_more, L_ERROR, "Previous transaction output already used in current tx"); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREVIOUS_TX_OUTPUT_ALREADY_USED_IN_CURRENT_TX; + l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX; break; } } @@ -3682,7 +3813,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t l_token = bound_item->out.tx_prev_out_ext_256->token; break; default: - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NOT_FIND_PREV_OUT_TX; + l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_OUT_ITEM_NOT_FOUND; break; } if (l_err_num) @@ -3699,12 +3830,12 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t dap_sign_get_pkey_hash(l_sign, &l_hash_pkey); } if (!dap_hash_fast_compare(&l_hash_pkey, l_prev_out_addr_key)) { - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_HASH_PKEY_TX_NOT_COMPARE_HASH_PKEY_OUT_ADDR_PREV_TX; + l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PKEY_HASHES_DONT_MATCH; break; } } else if(l_cond_type == TX_ITEM_TYPE_IN_COND) { // TX_ITEM_TYPE_IN_COND if(*(uint8_t *)l_tx_prev_out != TX_ITEM_TYPE_OUT_COND) { - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NOT_FIND_PREV_OUT_TX; + l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_OUT_ITEM_NOT_FOUND; break; } // 5a. Check for condition owner @@ -3732,13 +3863,13 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t pthread_rwlock_unlock(&s_verificators_rwlock); if (!l_verificator || !l_verificator->callback) { debug_if(s_debug_more, L_ERROR, "No verificator set for conditional output subtype %d", l_sub_tmp); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_VERIF_CHECK_NO_VALIDATOR_COND_OUTPUT; + l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NO_VERIFICATOR_SET; break; } if (l_verificator->callback(a_ledger, l_tx_prev_out_cond, a_tx, l_owner) == false) { debug_if(s_debug_more, L_WARNING, "Verificator check error for conditional output %s", dap_chain_tx_out_cond_subtype_to_str(l_sub_tmp)); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_VERIF_CHECK_FAIL; + l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_VERIFICATOR_CHECK_FAILURE; break; } // calculate sum of values from previous transactions @@ -3758,7 +3889,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t } if (! l_token || !*l_token ) { log_it(L_WARNING, "No token ticker found in previous transaction"); - l_err_num = DAP_CHAIN_LEDGET_TX_CACHE_CHECK_NO_FOUND_TOKEN_TICKER; + l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TICKER_NOT_FOUND; break; } // Get permissions @@ -3769,7 +3900,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t if (! l_token_item){ if(s_debug_more) log_it(L_WARNING, "No token item found for token %s", l_token); - l_err_num = DAP_CHAIN_LEDGET_TX_CACHE_CHECK_NO_FOUND_TOKEN_TICKER; + l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TOKEN_NOT_FOUND; break; } // Check permissions @@ -3783,7 +3914,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t if(s_debug_more) log_it(L_WARNING, "No permission for addr %s", l_tmp_tx_in_from?l_tmp_tx_in_from:"(null)"); DAP_DELETE(l_tmp_tx_in_from); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PERMISSION_FAILED; + l_err_num = DAP_CHAIN_LEDGER_PERMISSION_CHECK_FAILED; break; } } @@ -3795,7 +3926,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t if(s_debug_more) log_it(L_WARNING, "No permission for addr %s", l_tmp_tx_in_from?l_tmp_tx_in_from:"(null)"); DAP_DELETE(l_tmp_tx_in_from); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PERMISSION_FAILED; + l_err_num = DAP_CHAIN_LEDGER_PERMISSION_CHECK_FAILED; break; } } @@ -3803,6 +3934,16 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t HASH_FIND_STR(l_values_from_prev_tx, l_token, l_value_cur); if (!l_value_cur) { l_value_cur = DAP_NEW_Z(dap_chain_ledger_tokenizer_t); + if ( !l_value_cur ) { + log_it(L_ERROR, "Memory allocation error in dap_chain_ledger_tx_cache_check"); + if (bound_item) + DAP_DELETE(bound_item); + if ( l_list_bound_items ) + dap_list_free_full(l_list_bound_items, NULL); + if (l_list_tx_out) + dap_list_free(l_list_tx_out); + return -1; + } strcpy(l_value_cur->token_ticker, l_token); HASH_ADD_STR(l_values_from_prev_tx, token_ticker, l_value_cur); } @@ -3840,6 +3981,16 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t } } else { l_value_cur = DAP_NEW_Z(dap_chain_ledger_tokenizer_t); + if ( !l_value_cur ) { + log_it(L_ERROR, "Memory allocation error in dap_chain_ledger_tx_cache_check"); + if (bound_item) + DAP_DELETE(bound_item); + if ( l_list_bound_items ) + dap_list_free_full(l_list_bound_items, NULL); + if (l_list_tx_out) + dap_list_free(l_list_tx_out); + return -1; + } dap_stpcpy(l_value_cur->token_ticker, l_token); if (!l_main_ticker) l_main_ticker = l_value_cur->token_ticker; @@ -3912,6 +4063,16 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t HASH_FIND_STR(l_values_from_cur_tx, l_token, l_value_cur); if (!l_value_cur) { l_value_cur = DAP_NEW_Z(dap_chain_ledger_tokenizer_t); + if ( !l_value_cur ) { + log_it(L_ERROR, "Memory allocation error in dap_chain_ledger_tx_cache_check"); + if (bound_item) + DAP_DELETE(bound_item); + if ( l_list_bound_items ) + dap_list_free_full(l_list_bound_items, NULL); + if (l_list_tx_out) + dap_list_free(l_list_tx_out); + return -1; + } strcpy(l_value_cur->token_ticker, l_token); HASH_ADD_STR(l_values_from_cur_tx, token_ticker, l_value_cur); } @@ -3993,12 +4154,15 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t // 7. Check the network fee if (l_fee_check && compare256(l_fee_sum, l_ledger_pvt->fee_value) == -1) { - char *l_current_fee = dap_chain_balance_to_coins(l_fee_sum); - char *l_expected_fee = dap_chain_balance_to_coins(l_ledger_pvt->fee_value); - log_it(L_ERROR, "Fee value is invalid, expected %s pointed %s", l_expected_fee, l_current_fee); - l_err_num = -55; - DAP_DEL_Z(l_current_fee); - DAP_DEL_Z(l_expected_fee); + // Check for PoA-cert-signed "service" no-tax tx + if (!dap_chain_ledger_tx_poa_signed(a_ledger, a_tx)) { + char *l_current_fee = dap_chain_balance_to_coins(l_fee_sum); + char *l_expected_fee = dap_chain_balance_to_coins(l_ledger_pvt->fee_value); + log_it(L_ERROR, "Fee value is invalid, expected %s pointed %s", l_expected_fee, l_current_fee); + l_err_num = -55; + DAP_DEL_Z(l_current_fee); + DAP_DEL_Z(l_expected_fee); + } } if (a_main_ticker && !l_err_num) @@ -4036,29 +4200,27 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t int dap_chain_ledger_tx_add_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, size_t a_datum_size, dap_hash_fast_t *a_datum_hash) { if (!a_tx) - return DAP_CHAIN_LEDGER_TX_CHECK_ERROR_IS_NULL_TX; + return DAP_CHAIN_LEDGER_TX_CHECK_NULL_TX; size_t l_tx_size = dap_chain_datum_tx_get_size(a_tx); if (l_tx_size != a_datum_size) { - log_it (L_WARNING, "Inconsistent datum TX with data_size=%zu, tx_size=%zu", a_datum_size, l_tx_size); - return DAP_CHAIN_LEDGER_TX_CHECK_ERROR_INVALID_SIZE_TX; + log_it (L_WARNING, "Inconsistent datum TX: datum size %zu != tx size %zu", a_datum_size, l_tx_size); + return DAP_CHAIN_LEDGER_TX_CHECK_INVALID_TX_SIZE; } - int l_ret_check; - if( (l_ret_check = dap_chain_ledger_tx_cache_check(a_ledger, a_tx, a_datum_hash, false, - NULL, NULL, NULL)) < 0) { - char *l_err_str = dap_chain_ledger_tx_check_err_str(l_ret_check); - debug_if(s_debug_more, L_DEBUG, "dap_chain_ledger_tx_add_check() tx not passed the check: %s", - l_err_str); - DAP_DELETE(l_err_str); - return l_ret_check; - } + int l_ret_check = dap_chain_ledger_tx_cache_check(a_ledger, a_tx, a_datum_hash, + false, NULL, NULL, NULL); if(s_debug_more) { char l_tx_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; dap_chain_hash_fast_to_str(a_datum_hash, l_tx_hash_str, sizeof(l_tx_hash_str)); - log_it ( L_INFO, "dap_chain_ledger_tx_add_check() check passed for tx %s", l_tx_hash_str); + if (l_ret_check) + log_it(L_NOTICE, "Ledger TX adding check not passed for TX %s: error %s", + l_tx_hash_str, dap_chain_ledger_tx_check_err_str(l_ret_check)); + else + log_it(L_INFO, "Ledger TX adding check passed for TX %s", l_tx_hash_str); } - return DAP_CHAIN_LEDGER_TX_CHECK_OK; + + return l_ret_check; } /** @@ -4133,9 +4295,8 @@ void dap_chain_ledger_set_tps_start_time(dap_ledger_t *a_ledger) */ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, bool a_from_threshold, bool a_safe_call) { - if(!a_tx){ - if(s_debug_more) - log_it(L_ERROR, "NULL tx detected"); + if(!a_tx) { + debug_if(s_debug_more, L_ERROR, "NULL tx detected"); return -1; } int l_ret = 0; @@ -4165,7 +4326,7 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d l_item_tmp = NULL; if( (l_ret_check = dap_chain_ledger_tx_cache_check(a_ledger, a_tx, a_tx_hash, a_from_threshold, &l_list_bound_items, &l_list_tx_out, - &l_main_token_ticker)) < 0) { + &l_main_token_ticker))) { if (l_ret_check == DAP_CHAIN_CS_VERIFY_CODE_TX_NO_PREVIOUS || l_ret_check == DAP_CHAIN_CS_VERIFY_CODE_TX_NO_EMISSION) { if (!l_from_threshold) { @@ -4181,8 +4342,17 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d s_threshold_txs_max); } else { l_item_tmp = DAP_NEW_Z(dap_chain_ledger_tx_item_t); + if ( !l_item_tmp ) { + log_it(L_ERROR, "Memory allocation error in s_tx_add"); + return -1; + } l_item_tmp->tx_hash_fast = *a_tx_hash; l_item_tmp->tx = DAP_DUP_SIZE(a_tx, dap_chain_datum_tx_get_size(a_tx)); + if ( !l_item_tmp->tx ) { + DAP_DELETE(l_item_tmp); + log_it(L_ERROR, "Memory allocation error in s_tx_add"); + return -1; + } l_item_tmp->ts_added = dap_nanotime_now(); HASH_ADD_BYHASHVALUE(hh, l_ledger_pvt->threshold_txs, tx_hash_fast, sizeof(dap_chain_hash_fast_t), l_hash_value, l_item_tmp); if(s_debug_more) @@ -4192,12 +4362,8 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d pthread_rwlock_unlock(&l_ledger_pvt->threshold_txs_rwlock); } } else { - if(s_debug_more) { - char *l_ret_err_str = dap_chain_ledger_tx_check_err_str(l_ret_check); - log_it (L_WARNING, "dap_chain_ledger_tx_add() tx %s not passed the check: %s ", l_tx_hash_str, - l_ret_err_str); - DAP_DELETE(l_ret_err_str); - } + debug_if(s_debug_more, L_WARNING, "dap_chain_ledger_tx_add() tx %s not passed the check: %s ", l_tx_hash_str, + dap_chain_ledger_tx_check_err_str(l_ret_check)); } return l_ret_check; } @@ -4210,6 +4376,14 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d size_t l_outs_used = dap_list_length(l_list_bound_items); size_t l_cache_size = sizeof(dap_store_obj_t) * (l_outs_used + 1); dap_store_obj_t *l_cache_used_outs = DAP_NEW_Z_SIZE(dap_store_obj_t, l_cache_size); + if ( !l_cache_used_outs ) { + if (l_item_tmp->tx) + DAP_DELETE(l_item_tmp->tx); + if (l_item_tmp) + DAP_DELETE(l_item_tmp); + log_it(L_ERROR, "Memory allocation error in s_tx_add"); + return -1; + } char *l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_TXS_STR); const char *l_cur_token_ticker = NULL; @@ -4445,6 +4619,11 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d s_balance_cache_update(a_ledger, wallet_balance); } else { wallet_balance = DAP_NEW_Z(dap_ledger_wallet_balance_t); + if (!wallet_balance) { + log_it(L_ERROR, "Memoru allocation error in s_load_cache_gdb_loaded_txs_callback"); + l_ret = -1; + goto FIN; + } wallet_balance->key = l_wallet_balance_key; strcpy(wallet_balance->token_ticker, l_cur_token_ticker); SUM_256_256(wallet_balance->balance, l_value, &wallet_balance->balance); @@ -4462,6 +4641,11 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d // add transaction to the cache list dap_chain_ledger_tx_item_t *l_tx_item = DAP_NEW_Z(dap_chain_ledger_tx_item_t); + if ( !l_tx_item ) { + log_it(L_ERROR, "Memory allocation error in s_load_cache_gdb_loaded_txs_callback"); + l_ret = -1; + goto FIN; + } l_tx_item->tx_hash_fast = *a_tx_hash; size_t l_tx_size = dap_chain_datum_tx_get_size(a_tx); l_tx_item->tx = DAP_DUP_SIZE(a_tx, l_tx_size); @@ -4549,7 +4733,7 @@ int dap_chain_ledger_tx_load(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, HASH_FIND_BYHASHVALUE(hh, PVT(a_ledger)->ledger_items, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_hash_value, l_tx_item); if (l_tx_item) { pthread_rwlock_unlock(&PVT(a_ledger)->ledger_rwlock); - return 1; + return DAP_CHAIN_LEDGER_TX_ALREADY_CACHED; } HASH_FIND_BYHASHVALUE(hh, PVT(a_ledger)->threshold_txs, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_hash_value, l_tx_item); if (l_tx_item) { @@ -4560,7 +4744,7 @@ int dap_chain_ledger_tx_load(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, HASH_FIND_BYHASHVALUE(hh, PVT(a_ledger)->spent_items, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_hash_value, l_tx_spent_item); pthread_rwlock_unlock(&PVT(a_ledger)->ledger_rwlock); if (l_tx_spent_item) - return 1; + return DAP_CHAIN_LEDGER_TX_CACHE_CHECK_OUT_ITEM_ALREADY_USED; } return dap_chain_ledger_tx_add(a_ledger, a_tx, a_tx_hash, false); } @@ -4596,6 +4780,15 @@ int dap_chain_ledger_tx_remove(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_ HASH_FIND_BYHASHVALUE(hh, l_ledger_pvt->spent_items, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_hash_value, l_item_used); if (!l_item_used) { // Add it to spent items l_item_used = DAP_NEW_Z(dap_chain_ledger_tx_spent_item_t); + if ( !l_item_used ) { + if (l_item_tmp->tx) + DAP_DELETE(l_item_tmp->tx); + if (l_item_tmp) + DAP_DELETE(l_item_tmp); + pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock); + log_it(L_ERROR, "Memory allocation error in dap_chain_ledger_tx_remove"); + return -1; + } l_item_used->tx_hash_fast = *a_tx_hash; l_item_used->cache_data.spent_time = a_spent_time; strncpy(l_item_used->cache_data.token_ticker, l_item_tmp->cache_data.token_ticker, DAP_CHAIN_TICKER_SIZE_MAX); @@ -5270,6 +5463,12 @@ dap_list_t *dap_chain_ledger_get_list_tx_outs_with_val(dap_ledger_t *a_ledger, c // Check whether used 'out' items if (!dap_chain_ledger_tx_hash_is_used_out_item (a_ledger, &l_tx_cur_hash, l_out_idx_tmp)) { dap_chain_tx_used_out_item_t *l_item = DAP_NEW_Z(dap_chain_tx_used_out_item_t); + if ( !l_item ) { + if (l_list_used_out) + dap_list_free_full(l_list_used_out, NULL); + dap_list_free(l_list_out_items); + return NULL; + } l_item->tx_hash_fast = l_tx_cur_hash; l_item->num_idx_out = l_out_idx_tmp; l_item->value = l_value; @@ -5296,7 +5495,7 @@ dap_list_t *dap_chain_ledger_get_list_tx_outs_with_val(dap_ledger_t *a_ledger, c return l_list_used_out; } -// Add new verificator callback with associated subtype. Returns 1 if callback replaced, overwise returns 0 +// Add new verificator callback with associated subtype. Returns 1 if callback replaced, -1 error, overwise returns 0 int dap_chain_ledger_verificator_add(dap_chain_tx_out_cond_subtype_t a_subtype, dap_chain_ledger_verificator_callback_t a_callback, dap_chain_ledger_updater_callback_t a_callback_added) { dap_chain_ledger_verificator_t *l_new_verificator; @@ -5309,6 +5508,10 @@ int dap_chain_ledger_verificator_add(dap_chain_tx_out_cond_subtype_t a_subtype, return 1; } l_new_verificator = DAP_NEW(dap_chain_ledger_verificator_t); + if ( !l_new_verificator ) { + log_it(L_ERROR, "Memory allocation error in dap_chain_ledger_verificator_add"); + return -1; + } l_new_verificator->subtype = (int)a_subtype; l_new_verificator->callback = a_callback; l_new_verificator->callback_added = a_callback_added; @@ -5404,6 +5607,12 @@ dap_list_t *dap_chain_ledger_get_list_tx_cond_outs_with_val(dap_ledger_t *a_ledg } if (!IS_ZERO_256(l_value)) { dap_chain_tx_used_out_item_t *l_item = DAP_NEW(dap_chain_tx_used_out_item_t); + if ( !l_item ) { + if (l_list_used_out) + dap_list_free_full(l_list_used_out, free); + dap_list_free(l_list_out_cond_items); + return NULL; + } l_item->tx_hash_fast = l_tx_cur_hash; l_item->num_idx_out = l_out_idx_tmp; l_item->value = l_value; diff --git a/modules/chain/dap_chain_pvt.c b/modules/chain/dap_chain_pvt.c index 6c432762c29bc225d4cfc0c4bff5ac4ceced2677..010a4ab8429bd8d24c53e579c82ed657d91b88d9 100644 --- a/modules/chain/dap_chain_pvt.c +++ b/modules/chain/dap_chain_pvt.c @@ -37,6 +37,10 @@ void dap_chain_add_mempool_notify_callback(dap_chain_t *a_chain, dap_store_obj_callback_notify_t a_callback, void *a_cb_arg) { dap_chain_gdb_notifier_t *l_notifier = DAP_NEW(dap_chain_gdb_notifier_t); + if (!l_notifier) { + log_it(L_ERROR, "Memory allocation error in dap_chain_add_mempool_notify_callback"); + return; + } l_notifier->callback = a_callback; l_notifier->cb_arg = a_cb_arg; DAP_CHAIN_PVT(a_chain)->mempool_notifires = dap_list_append(DAP_CHAIN_PVT(a_chain)->mempool_notifires, l_notifier); diff --git a/modules/chain/dap_chain_tx.c b/modules/chain/dap_chain_tx.c index b5d3441d6d24add54e3c744f70ec604c3f0ae851..78738e78394ec48b109c9288a2d07f2f1f05c9fa 100644 --- a/modules/chain/dap_chain_tx.c +++ b/modules/chain/dap_chain_tx.c @@ -36,6 +36,10 @@ dap_chain_tx_t * dap_chain_tx_wrap_packed(dap_chain_datum_tx_t * a_tx_packed) { dap_chain_tx_t * l_tx = DAP_NEW_Z(dap_chain_tx_t); + if (!l_tx) { + log_it(L_ERROR, "Memory allocation error in dap_chain_tx_wrap_packed"); + return NULL; + } dap_hash_fast(a_tx_packed, dap_chain_datum_tx_get_size(a_tx_packed), &l_tx->hash); l_tx->datum_tx = a_tx_packed; return l_tx; diff --git a/modules/chain/include/dap_chain.h b/modules/chain/include/dap_chain.h index d2f44e3764bddb58263b9a3d12261086e5ac2b85..fda6fe0e595c9170ece404708127e406104b3b21 100644 --- a/modules/chain/include/dap_chain.h +++ b/modules/chain/include/dap_chain.h @@ -100,7 +100,7 @@ typedef dap_time_t (*dap_chain_callback_atom_get_timestamp_t)(dap_chain_atom_ptr typedef dap_chain_atom_ptr_t (*dap_chain_callback_atom_iter_find_by_hash_t)(dap_chain_atom_iter_t * ,dap_chain_hash_fast_t *,size_t*); typedef dap_chain_datum_t * (*dap_chain_callback_datum_find_by_hash_t)(dap_chain_t *, dap_chain_hash_fast_t *, dap_chain_hash_fast_t *, int *); -typedef dap_chain_atom_ptr_t (*dap_chain_callback_block_find_by_hash_t)(dap_chain_t * ,dap_chain_hash_fast_t *); +typedef dap_chain_atom_ptr_t (*dap_chain_callback_block_find_by_hash_t)(dap_chain_t * ,dap_chain_hash_fast_t *, size_t *); typedef dap_chain_atom_ptr_t * (*dap_chain_callback_atom_iter_get_atoms_t)(dap_chain_atom_iter_t * ,size_t* ,size_t**); typedef size_t (*dap_chain_callback_add_datums_t)(dap_chain_t * , dap_chain_datum_t **, size_t ); diff --git a/modules/chain/include/dap_chain_ledger.h b/modules/chain/include/dap_chain_ledger.h index 14297dfd44595f6dabbea39ea0e0f187a0b955bb..77744f24bba8dd230df79333c693ee89c2f799bc 100644 --- a/modules/chain/include/dap_chain_ledger.h +++ b/modules/chain/include/dap_chain_ledger.h @@ -47,52 +47,67 @@ typedef struct dap_ledger { */ typedef enum dap_chain_ledger_tx_check{ DAP_CHAIN_LEDGER_TX_CHECK_OK = 0, - DAP_CHAIN_LEDGER_TX_CHECK_ERROR_IS_NULL_TX = -200, - DAP_CHAIN_LEDGER_TX_CHECK_ERROR_INVALID_SIZE_TX = -202, - //DAP_CHAIN_LEDGER_TX_CACHE_CHECK_OK = 0, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_INVALID_INPUT_DATA = -1, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_INVALID_SIGN_TX = -2, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TX_NO_VALID_TNPUTS_FOUND = -22, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NOT_FOUND_TOKEN = -23, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TOKEN_NOT_VALID_STAKE_LOCK = -31, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NO_OUT_COND_STAKE_LOCK_FROM_IN_EMS = -32, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_MULTIPLICATION_OVERFLOW_EMISSION_LOCKED_EMISSION_RATE = -26, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NO_OUT_EXT_FOR_GIRDLED_IN_EMS = -36, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NOT_FIND_OUT_NOR_OUT_EXT_BASE_TX_IN_EMS = -24, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TOKEN_CURRENT_SUPPLY_LOWER_EMISSION_VALUE = -30, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_VALUE_NOT_THATS_EXPECTED_IN_EMS = -34, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NOT_FOUND_TICKER_FOR_STAKE_LOCK = -33, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TICKER_DIFFERENT_EXPECTED = -35, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NOT_USED_OUT_ITEM = -6, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NOT_FIND_PREV_OUT_TX = -8, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_HASH_PKEY_TX_NOT_COMPARE_HASH_PKEY_OUT_ADDR_PREV_TX = -9, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREVIOUS_TX_OUTPUT_ALREADY_USED_IN_CURRENT_TX = -7, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_VERIF_CHECK_NO_VALIDATOR_COND_OUTPUT = -13, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_VERIF_CHECK_FAIL = -14, - DAP_CHAIN_LEDGET_TX_CACHE_CHECK_NO_FOUND_TOKEN_TICKER = -15, - DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PERMISSION_FAILED = -20 -}dap_chain_ledger_tx_check_t; + DAP_CHAIN_LEDGER_TX_CHECK_NULL_TX, + DAP_CHAIN_LEDGER_TX_CHECK_INVALID_TX_SIZE, + DAP_CHAIN_LEDGER_TX_ALREADY_CACHED, + DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NULL_TX, + DAP_CHAIN_LEDGER_TX_CACHE_CHECK_INVALID_TX_SIGN, + DAP_CHAIN_LEDGER_TX_CACHE_IN_EMS_ALREADY_USED, + DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_IN_EMS_ALREADY_USED, + DAP_CHAIN_LEDGER_TX_CACHE_CHECK_EMISSION_NOT_FOUND, + DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TX_NO_VALID_INPUTS, + DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TICKER_NOT_FOUND, + DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_INVALID_TOKEN, + DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_NO_OUT_COND_FOR_IN_EMS, + DAP_CHAIN_LEDGER_TX_CACHE_MULT256_OVERFLOW_EMS_LOCKED_X_RATE, + DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NO_OUT_EXT_FOR_GIRDLED_IN_EMS, + DAP_CHAIN_LEDGER_TX_CACHE_NO_OUT_ITEMS_FOR_BASE_TX, + DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TOKEN_EMS_VALUE_EXEEDS_CUR_SUPPLY, + DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_UNEXPECTED_VALUE, + DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_TICKER_NOT_FOUND, + DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_OTHER_TICKER_EXPECTED, + DAP_CHAIN_LEDGER_TX_CACHE_CHECK_OUT_ITEM_ALREADY_USED, + DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TX_NOT_FOUND, + DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_OUT_ITEM_NOT_FOUND, + DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PKEY_HASHES_DONT_MATCH, + DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX, + DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NO_VERIFICATOR_SET, + DAP_CHAIN_LEDGER_TX_CACHE_VERIFICATOR_CHECK_FAILURE, + DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TICKER_NOT_FOUND, + DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TOKEN_NOT_FOUND, + DAP_CHAIN_LEDGER_PERMISSION_CHECK_FAILED, + /* add custom codes here */ + + DAP_CHAIN_LEDGER_TX_CHECK_UNKNOWN /* MAX */ +} dap_chain_ledger_tx_check_t; typedef enum dap_chain_ledger_emission_err{ DAP_CHAIN_LEDGER_EMISSION_ADD_OK = 0, - DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_ERROR_EMISSION_NULL_OR_IS_EMISSION_SIZE_ZERO = -100, - DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_CAN_NOT_ADDED_EMISSION_ALREADY_IN_CACHE = -1, - DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_EMISSION_OVERFULLED = -2, - DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_VALUE_MORE_THAN_CURRENT_SUPPLY = -4, - DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_VALID_SIGNS_NOT_ENOUGH = -3, - DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN = -5, - DAP_CHAIN_LEDGER_EMISSION_ADD_TSD_CHECK_FAILED = -144 -}dap_chain_ledger_emission_err_code_t; + DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_EMS_IS_NULL, + DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_EMS_ALREADY_CACHED, + DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_OVERFLOW, + DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_VALUE_EXEEDS_CURRENT_SUPPLY, + DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_NOT_ENOUGH_VALID_SIGNS, + DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN, + DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_ZERO_VALUE, + DAP_CHAIN_LEDGER_EMISSION_ADD_TSD_CHECK_FAILED, + /* add custom codes here */ + DAP_CHAIN_LEDGER_EMISSION_ADD_MEMORY_PROBLEM, + DAP_CHAIN_LEDGER_EMISSION_ADD_UNKNOWN /* MAX */ +} dap_chain_ledger_emission_err_code_t; typedef enum dap_chain_ledger_token_decl_add_err{ DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_OK = 0, - DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_LEDGER_IS_NULL = -1, - DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_DECL_DUPLICATE = -3, - DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_CHECK = -2, - DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_ABSENT_TOKEN = -6, - DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_NOT_ENOUGH_VALID_SIGN = -5, - DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_UNIQUE_SIGNS_LESS_TOTAL_SIGNS = -4 -}dap_chain_ledger_token_decl_add_err_t; + DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_LEDGER_IS_NULL, + DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_DECL_DUPLICATE, + DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_CHECK, + DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_ABSENT_TOKEN, + DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_NOT_ENOUGH_VALID_SIGN, + DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOTAL_SIGNS_EXCEED_UNIQUE_SIGNS, + /* add custom codes here */ + + DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_UNKNOWN /* MAX */ +} dap_chain_ledger_token_decl_add_err_t; typedef bool (*dap_chain_ledger_verificator_callback_t)(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_t *a_tx_out_cond, dap_chain_datum_tx_t *a_tx_in, bool a_owner); typedef void (*dap_chain_ledger_updater_callback_t)(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_tx_out_cond_t *a_prev_cond); @@ -115,9 +130,9 @@ typedef struct dap_chain_net dap_chain_net_t; #define DAP_CHAIN_LEDGER_CACHE_ENABLED 0x0200 // Error code for no previous transaction (for stay in mempool) -#define DAP_CHAIN_CS_VERIFY_CODE_TX_NO_PREVIOUS -1111 +#define DAP_CHAIN_CS_VERIFY_CODE_TX_NO_PREVIOUS DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TX_NOT_FOUND // Error code for no emission for a transaction (for stay in mempoold) -#define DAP_CHAIN_CS_VERIFY_CODE_TX_NO_EMISSION -1112 +#define DAP_CHAIN_CS_VERIFY_CODE_TX_NO_EMISSION DAP_CHAIN_LEDGER_TX_CACHE_CHECK_EMISSION_NOT_FOUND // Error code for no decree for anchor (for stay in mempool) #define DAP_CHAIN_CS_VERIFY_CODE_NO_DECREE -1113 @@ -131,7 +146,7 @@ typedef struct dap_chain_net dap_chain_net_t; int dap_chain_ledger_init(); void dap_chain_ledger_deinit(); -dap_ledger_t *dap_chain_ledger_create(uint16_t a_flags, char *a_net_name, const char *a_net_native_ticker); +dap_ledger_t *dap_chain_ledger_create(uint16_t a_flags, char *a_net_name, const char *a_net_native_ticker, dap_list_t *a_poa_certs); void dap_chain_ledger_set_fee(dap_ledger_t *a_ledger, uint256_t a_fee, dap_chain_addr_t a_fee_addr); @@ -173,7 +188,7 @@ int dap_chain_ledger_tx_load(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, int dap_chain_ledger_tx_add_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, size_t a_datum_size, dap_hash_fast_t *a_datum_hash); -char* dap_chain_ledger_tx_check_err_str(dap_chain_ledger_tx_check_t a_code); +char* dap_chain_ledger_tx_check_err_str(int a_code); /** * Print list transaction from ledger @@ -217,7 +232,7 @@ dap_list_t * dap_chain_ledger_token_auth_pkeys_hashes(dap_ledger_t *a_ledger, co int dap_chain_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size, dap_hash_fast_t *a_emission_hash, bool a_from_threshold); int dap_chain_ledger_token_emission_load(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size, dap_hash_fast_t *a_token_emission_hash); -char *dap_chain_ledger_token_emission_err_code_to_str(dap_chain_ledger_emission_err_code_t a_code); +char *dap_chain_ledger_token_emission_err_code_to_str(int a_code); // Check if it addable int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size, dap_chain_hash_fast_t *a_emission_hash); @@ -236,6 +251,8 @@ void dap_chain_ledger_addr_get_token_ticker_all_depricated(dap_ledger_t *a_ledge void dap_chain_ledger_addr_get_token_ticker_all(dap_ledger_t *a_ledger, dap_chain_addr_t * a_addr, char *** a_tickers, size_t * a_tickers_size); +bool dap_chain_ledger_tx_poa_signed(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx); + // Checking a new transaction before adding to the cache int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, bool a_from_threshold, dap_list_t **a_list_bound_items, dap_list_t **a_list_tx_out, char **a_main_ticker); diff --git a/modules/chain/tests/dap_chain_ledger_tests.c b/modules/chain/tests/dap_chain_ledger_tests.c index da64d64ce39b8e4ba83c2f4351374a2481b981f4..609408f87ae3650b825b0a9716aa83d9d30b1944 100644 --- a/modules/chain/tests/dap_chain_ledger_tests.c +++ b/modules/chain/tests/dap_chain_ledger_tests.c @@ -369,7 +369,7 @@ void dap_chain_ledger_test_run(void){ dap_print_module_name("dap_chain_ledger"); uint16_t l_flags = 0; l_flags |= DAP_CHAIN_LEDGER_CHECK_TOKEN_EMISSION; - dap_ledger_t *l_ledger = dap_chain_ledger_create(l_flags, "Snet", s_token_ticker); + dap_ledger_t *l_ledger = dap_chain_ledger_create(l_flags, "Snet", s_token_ticker, NULL); char *l_seed_ph = "H58i9GJKbn91238937^#$t6cjdf"; size_t l_seed_ph_size = strlen(l_seed_ph); dap_cert_t *l_cert = dap_cert_generate_mem_with_seed("testCert", DAP_ENC_KEY_TYPE_SIG_PICNIC, l_seed_ph, l_seed_ph_size); diff --git a/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c index a036d7a3a6b4750b2db25bc30f32cfe5ceaecbc3..1e330ae02de8bbcec498f6bd9aa1ff91669bb01c 100644 --- a/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c +++ b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c @@ -30,15 +30,15 @@ along with any CellFrame SDK based project. If not, see <http://www.gnu.org/lic #include "dap_hash.h" #include "rand/dap_rand.h" -#include "dap_chain.h" -#include "dap_chain_datum_tx.h" -#include "dap_chain_datum_tx_in.h" -#include "dap_chain_datum_tx_in_cond.h" -#include "dap_chain_datum_tx_out.h" -#include "dap_chain_datum_tx_out_cond.h" -#include "dap_chain_datum_tx_receipt.h" -#include "dap_chain_mempool.h" -#include "dap_common.h" +//#include "dap_chain.h" +//#include "dap_chain_datum_tx.h" +//#include "dap_chain_datum_tx_in.h" +//#include "dap_chain_datum_tx_in_cond.h" +//#include "dap_chain_datum_tx_out.h" +//#include "dap_chain_datum_tx_out_cond.h" +//#include "dap_chain_datum_tx_receipt.h" +//#include "dap_chain_mempool.h" +//#include "dap_common.h" #include "dap_chain_net_srv.h" #include "dap_chain_net_srv_stream_session.h" @@ -54,6 +54,11 @@ along with any CellFrame SDK based project. If not, see <http://www.gnu.org/lic #define LOG_TAG "dap_stream_ch_chain_net_srv" +typedef struct usages_in_grace{ + dap_hash_fast_t tx_cond_hash; + dap_chain_net_srv_grace_t *grace; + UT_hash_handle hh; +} usages_in_grace_t; uint8_t dap_stream_ch_chain_net_srv_get_id() { @@ -65,6 +70,62 @@ static void s_stream_ch_delete(dap_stream_ch_t* ch , void* arg); static void s_stream_ch_packet_in(dap_stream_ch_t* ch , void* arg); static void s_stream_ch_packet_out(dap_stream_ch_t* ch , void* arg); +static bool s_unban_client(dap_chain_net_srv_banlist_item_t *a_item); + +static void s_service_start(dap_stream_ch_t* a_ch , dap_stream_ch_chain_net_srv_pkt_request_t * a_request, size_t a_request_size); +static void s_grace_period_start(dap_chain_net_srv_grace_t *a_grace); +static bool s_grace_period_finish(usages_in_grace_t *a_grace); + +static inline void s_grace_error(dap_chain_net_srv_grace_t *a_grace, dap_stream_ch_chain_net_srv_pkt_error_t a_err){ + dap_stream_ch_t * l_ch = dap_stream_ch_find_by_uuid_unsafe(a_grace->stream_worker, a_grace->ch_uuid); + dap_chain_net_srv_stream_session_t *l_srv_session = l_ch && l_ch->stream && l_ch->stream->session ? + (dap_chain_net_srv_stream_session_t *)l_ch->stream->session->_inheritor : NULL; + + a_grace->usage->is_grace = false; + if (a_grace->usage->receipt_next){ // If not first grace-period + log_it( L_WARNING, "Next receipt is rejected. Waiting until current limits is over."); + DAP_DEL_Z(a_grace->usage->receipt_next); + memset(&a_grace->usage->tx_cond_hash, 0, sizeof(a_grace->usage->tx_cond_hash)); + DAP_DELETE(a_grace->request); + DAP_DELETE(a_grace); + return; + } + + if (a_err.code) { + if(l_ch) + dap_stream_ch_pkt_write_unsafe(l_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &a_err, sizeof (a_err)); + if (a_grace->usage->service && a_grace->usage->service->callbacks.response_error) + a_grace->usage->service->callbacks.response_error(a_grace->usage->service, 0, NULL, &a_err, sizeof(a_err)); + } + + if (a_grace->usage) { // add client pkey hash to banlist + a_grace->usage->is_active = false; + if (a_grace->usage->service) { + dap_chain_net_srv_banlist_item_t *l_item = NULL; + pthread_mutex_lock(&a_grace->usage->service->banlist_mutex); + HASH_FIND(hh, a_grace->usage->service->ban_list, &a_grace->usage->client_pkey_hash, sizeof(dap_chain_hash_fast_t), l_item); + if (l_item) + pthread_mutex_unlock(&a_grace->usage->service->banlist_mutex); + else { + l_item = DAP_NEW_Z(dap_chain_net_srv_banlist_item_t); + l_item->client_pkey_hash = a_grace->usage->client_pkey_hash; + l_item->ht_mutex = &a_grace->usage->service->banlist_mutex; + l_item->ht_head = &a_grace->usage->service->ban_list; + HASH_ADD(hh, a_grace->usage->service->ban_list, client_pkey_hash, sizeof(dap_chain_hash_fast_t), l_item); + pthread_mutex_unlock(&a_grace->usage->service->banlist_mutex); + dap_timerfd_start(a_grace->usage->service->grace_period * 1000, (dap_timerfd_callback_t)s_unban_client, l_item); + } + } + + } else if (l_srv_session->usage_active) + dap_chain_net_srv_usage_delete(l_srv_session); + DAP_DELETE(a_grace->request); + DAP_DELETE(a_grace); +} + +// TODO: move this to net_srv +static usages_in_grace_t * s_grace_table = NULL; +static pthread_mutex_t s_ht_grace_table_mutex; /** * @brief dap_stream_ch_chain_net_init * @return @@ -73,6 +134,7 @@ int dap_stream_ch_chain_net_srv_init(void) { log_it(L_NOTICE,"Chain network services channel initialized"); dap_stream_ch_proc_add(dap_stream_ch_chain_net_srv_get_id(),s_stream_ch_new,s_stream_ch_delete,s_stream_ch_packet_in,s_stream_ch_packet_out); + pthread_mutex_init(&s_ht_grace_table_mutex, NULL); return 0; } @@ -105,7 +167,6 @@ void s_stream_ch_new(dap_stream_ch_t* a_ch , void* arg) log_it(L_ERROR, "Session inheritor is already present!"); dap_chain_net_srv_call_opened_all( a_ch); - } @@ -120,6 +181,8 @@ void s_stream_ch_delete(dap_stream_ch_t* a_ch , void* a_arg) (void) a_arg; log_it(L_DEBUG, "Stream ch chain net srv delete"); dap_chain_net_srv_call_closed_all( a_ch); + if (a_ch->stream->session && a_ch->stream->session->_inheritor) + dap_chain_net_srv_stream_session_delete( a_ch->stream->session ); DAP_DEL_Z(a_ch->internal); } @@ -132,29 +195,41 @@ static bool s_unban_client(dap_chain_net_srv_banlist_item_t *a_item) return false; } -static bool s_grace_period_control(dap_chain_net_srv_grace_t *a_grace) +void dap_stream_ch_chain_net_srv_tx_cond_added_cb(void *a_arg, dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx) { - assert(a_grace); + UNUSED(a_ledger); + UNUSED(a_arg); + // TODO: 1. Get net_srv by srv_uid from tx_cond + // 2. Get usages in grace HT from service + usages_in_grace_t *l_item = NULL; + dap_hash_fast_t tx_cond_hash = {}; + dap_hash_fast((void*)a_tx, dap_chain_datum_tx_get_size(a_tx), &tx_cond_hash); + pthread_mutex_lock(&s_ht_grace_table_mutex); + HASH_FIND(hh, s_grace_table, &tx_cond_hash, sizeof(dap_hash_fast_t), l_item); + if (l_item){ + log_it(L_INFO, "Found tx in ledger by notify. Finish grace."); + // Stop timer + dap_timerfd_delete_mt(l_item->grace->stream_worker->worker, l_item->grace->timer_es_uuid); + // finish grace + s_grace_period_finish(l_item); + } + pthread_mutex_unlock(&s_ht_grace_table_mutex); +} + +static void s_service_start(dap_stream_ch_t* a_ch , dap_stream_ch_chain_net_srv_pkt_request_t * a_request, size_t a_request_size) +{ + assert(a_ch); dap_stream_ch_chain_net_srv_pkt_error_t l_err; memset(&l_err, 0, sizeof(l_err)); dap_chain_net_srv_t * l_srv = NULL; - dap_chain_net_srv_usage_t *l_usage = NULL; - dap_stream_ch_t *l_ch = dap_stream_ch_find_by_uuid_unsafe(a_grace->stream_worker, a_grace->ch_uuid); - - if (!l_ch) - goto free_exit; - dap_chain_net_srv_stream_session_t *l_srv_session = l_ch && l_ch->stream && l_ch->stream->session ? - (dap_chain_net_srv_stream_session_t *)l_ch->stream->session->_inheritor : NULL; - if (!l_srv_session) - goto free_exit; - - dap_stream_ch_chain_net_srv_pkt_request_t *l_request = a_grace->request; - l_srv = dap_chain_net_srv_get( l_request->hdr.srv_uid ); - dap_chain_net_t * l_net = dap_chain_net_by_id( l_request->hdr.net_id ); + dap_chain_net_srv_stream_session_t *l_srv_session = a_ch->stream && a_ch->stream->session ? + (dap_chain_net_srv_stream_session_t *)a_ch->stream->session->_inheritor : NULL; + l_srv = dap_chain_net_srv_get( a_request->hdr.srv_uid ); + dap_chain_net_t * l_net = dap_chain_net_by_id( a_request->hdr.net_id ); - l_err.net_id.uint64 = l_request->hdr.net_id.uint64; - l_err.srv_uid.uint64 = l_request->hdr.srv_uid.uint64; + l_err.net_id.uint64 = a_request->hdr.net_id.uint64; + l_err.srv_uid.uint64 = a_request->hdr.srv_uid.uint64; if ( ! l_net ) // Network not found l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_NETWORK_NOT_FOUND; @@ -162,83 +237,149 @@ static bool s_grace_period_control(dap_chain_net_srv_grace_t *a_grace) if ( ! l_srv ) // Service not found l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_SERVICE_NOT_FOUND; - if ( l_err.code ){ - goto free_exit; + if ( l_err.code || !l_srv_session){ + if(a_ch) + dap_stream_ch_pkt_write_unsafe(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof (l_err)); + if (l_srv && l_srv->callbacks.response_error) + l_srv->callbacks.response_error(l_srv, 0, NULL, &l_err, sizeof(l_err)); + return; } - dap_ledger_t * l_ledger =l_net->pub.ledger; + dap_chain_net_srv_usage_t *l_usage = NULL; + l_usage = dap_chain_net_srv_usage_add(l_srv_session, l_net, l_srv); + if ( !l_usage ){ // Usage can't add + log_it( L_WARNING, "Can't add usage"); + l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_CANT_ADD_USAGE; + if(a_ch) + dap_stream_ch_pkt_write_unsafe(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof (l_err)); + if (l_srv && l_srv->callbacks.response_error) + l_srv->callbacks.response_error(l_srv, 0, NULL, &l_err, sizeof(l_err)); + return; + } + + l_err.usage_id = l_usage->id; + // Create one client + l_usage->client = DAP_NEW_Z( dap_chain_net_srv_client_remote_t); + l_usage->client->stream_worker = a_ch->stream_worker; + l_usage->client->ch = a_ch; + l_usage->client->session_id = a_ch->stream->session->id; + l_usage->client->ts_created = time(NULL); + l_usage->tx_cond_hash = a_request->hdr.tx_cond; + l_usage->ts_created = time(NULL); + l_usage->net = l_net; + l_usage->service = l_srv; + + + dap_chain_net_srv_grace_t *l_grace = DAP_NEW_Z(dap_chain_net_srv_grace_t); + l_grace->request = DAP_NEW_Z_SIZE(dap_stream_ch_chain_net_srv_pkt_request_t, a_request_size); + memcpy(l_grace->request, a_request, a_request_size); + l_grace->request_size = a_request_size; + l_grace->ch_uuid = a_ch->uuid; + l_grace->stream_worker = a_ch->stream_worker; + l_grace->usage = l_usage; + + if (l_srv->pricelist){ + // not free service + s_grace_period_start(l_grace); + } else { + // Start service for free + log_it( L_INFO, "Service provide for free"); + l_grace->usage->is_free = true; + size_t l_success_size = sizeof (dap_stream_ch_chain_net_srv_pkt_success_hdr_t ); + dap_stream_ch_chain_net_srv_pkt_success_t *l_success = DAP_NEW_Z_SIZE(dap_stream_ch_chain_net_srv_pkt_success_t, + l_success_size); + l_success->hdr.usage_id = l_usage->id; + l_success->hdr.net_id.uint64 = l_usage->net->pub.id.uint64; + l_success->hdr.srv_uid.uint64 = l_usage->service->uid.uint64; + dap_stream_ch_pkt_write_unsafe(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_SUCCESS, l_success, l_success_size); + if (l_usage->service->callbacks.response_success) + l_usage->service->callbacks.response_success(l_usage->service, l_usage->id, l_usage->client, NULL, 0); + DAP_DELETE(l_success); + } + return; +} + +static void s_grace_period_start(dap_chain_net_srv_grace_t *a_grace) +{ + assert(a_grace); + dap_stream_ch_chain_net_srv_pkt_error_t l_err; + memset(&l_err, 0, sizeof(l_err)); + dap_stream_ch_t *l_ch = dap_stream_ch_find_by_uuid_unsafe(a_grace->stream_worker, a_grace->ch_uuid); + + if (!l_ch){ + s_grace_error(a_grace, l_err); + return; + } + + dap_chain_net_t * l_net = a_grace->usage->net; + + l_err.net_id.uint64 = l_net->pub.id.uint64; + l_err.srv_uid.uint64 = a_grace->usage->service->uid.uint64; + + dap_ledger_t * l_ledger = l_net->pub.ledger; dap_chain_datum_tx_t * l_tx = NULL; dap_chain_tx_out_cond_t * l_tx_out_cond = NULL; - bool l_grace_start = false; - if (l_srv->pricelist ){ // Is present pricelist, not free service + dap_chain_net_srv_price_t * l_price = NULL; + if ( !l_ledger ){ // No ledger + log_it( L_WARNING, "No Ledger"); + l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_NETWORK_NO_LEDGER ; + s_grace_error(a_grace, l_err); + return; + } - if ( !l_ledger ){ // No ledger - log_it( L_WARNING, "No Ledger"); - l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_NETWORK_NO_LEDGER ; - goto free_exit; - } + l_tx = a_grace->usage->is_waiting_new_tx_cond ? NULL : dap_chain_ledger_tx_find_by_hash(l_ledger, &a_grace->usage->tx_cond_hash); + if ( ! l_tx ){ // No tx cond transaction, start grace-period + a_grace->usage->is_grace = true; - l_tx = dap_chain_ledger_tx_find_by_hash( l_ledger,& l_request->hdr.tx_cond ); - if ( ! l_tx ){ // No tx cond transaction - if (a_grace->usage) { // marker for reentry to function - log_it( L_WARNING, "No tx cond transaction"); - l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NOT_FOUND ; - goto free_exit; - } else - l_grace_start = true; - } - if (!l_grace_start) { - int l_tx_out_cond_size =0; - l_tx_out_cond = (dap_chain_tx_out_cond_t *) - dap_chain_datum_tx_item_get(l_tx, NULL, TX_ITEM_TYPE_OUT_COND, &l_tx_out_cond_size ); + l_price = DAP_NEW_Z(dap_chain_net_srv_price_t); + memcpy(l_price, a_grace->usage->service->pricelist, sizeof(*l_price)); - if ( ! l_tx_out_cond ) { // No conditioned output - log_it( L_WARNING, "No conditioned output"); - l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NO_COND_OUT ; - goto free_exit; - } + a_grace->usage->price = l_price; - // Check cond output if it equesl or not to request - if (!dap_chain_net_srv_uid_compare(l_tx_out_cond->header.srv_uid, l_request->hdr.srv_uid)) { - log_it( L_WARNING, "Wrong service uid in request, tx expect to close its output with 0x%016"DAP_UINT64_FORMAT_X, - l_tx_out_cond->header.srv_uid.uint64 ); - l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_WRONG_SRV_UID ; - goto free_exit; - } + if (!a_grace->usage->receipt){ + a_grace->usage->receipt = dap_chain_net_srv_issue_receipt(a_grace->usage->service, a_grace->usage->price, NULL, 0); + dap_stream_ch_pkt_write_unsafe(l_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_REQUEST, + a_grace->usage->receipt, a_grace->usage->receipt->size); } - } - if (!a_grace->usage) { - l_usage = dap_chain_net_srv_usage_add(l_srv_session, l_net, l_srv); - if ( !l_usage ){ // Usage can't add - log_it( L_WARNING, "Can't add usage"); - l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_CANT_ADD_USAGE; - goto free_exit; + usages_in_grace_t *l_item = DAP_NEW_Z_SIZE(usages_in_grace_t, sizeof(usages_in_grace_t)); + l_item->grace = a_grace; + l_item->tx_cond_hash = a_grace->usage->tx_cond_hash; + + pthread_mutex_lock(&s_ht_grace_table_mutex); + HASH_ADD(hh, s_grace_table, tx_cond_hash, sizeof(dap_hash_fast_t), l_item); + pthread_mutex_unlock(&s_ht_grace_table_mutex); + a_grace->timer_es_uuid = dap_timerfd_start_on_worker(a_grace->stream_worker->worker, a_grace->usage->service->grace_period * 1000, + (dap_timerfd_callback_t)s_grace_period_finish, l_item)->esocket_uuid; + + + } else { // Start srvice in normal pay mode + a_grace->usage->tx_cond = l_tx; + + l_tx_out_cond = dap_chain_datum_tx_out_cond_get(l_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, NULL ); + + if ( ! l_tx_out_cond ) { // No conditioned output + log_it( L_WARNING, "No conditioned output"); + l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NO_COND_OUT ; + s_grace_error(a_grace, l_err); + return; } - l_err.usage_id = l_usage->id; + // Check cond output if it equesl or not to request + if (!dap_chain_net_srv_uid_compare(l_tx_out_cond->header.srv_uid, a_grace->usage->service->uid)) { + log_it( L_WARNING, "Wrong service uid in request, tx expect to close its output with 0x%016"DAP_UINT64_FORMAT_X, + l_tx_out_cond->header.srv_uid.uint64 ); + l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_WRONG_SRV_UID ; + s_grace_error(a_grace, l_err); + return; + } - // Create one client - l_usage->client = DAP_NEW_Z( dap_chain_net_srv_client_remote_t); - l_usage->client->stream_worker = l_ch->stream_worker; - l_usage->client->ch = l_ch; - l_usage->client->session_id = l_ch->stream->session->id; - l_usage->client->ts_created = time(NULL); - l_usage->tx_cond = l_tx; - l_usage->tx_cond_hash = l_request->hdr.tx_cond; - l_usage->ts_created = time(NULL); - } else { - l_usage = a_grace->usage; - l_usage->tx_cond = l_tx; - } - dap_chain_net_srv_price_t * l_price = NULL; - const char * l_ticker = NULL; - if (l_srv->pricelist && !l_grace_start) { - l_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, &l_request->hdr.tx_cond ); - dap_stpcpy(l_usage->token_ticker, l_ticker); + const char * l_ticker = NULL; + l_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, &a_grace->usage->tx_cond_hash); + dap_stpcpy(a_grace->usage->token_ticker, l_ticker); dap_chain_net_srv_price_t *l_price_tmp; - DL_FOREACH(l_srv->pricelist, l_price_tmp) { - if (l_price_tmp->net->pub.id.uint64 == l_request->hdr.net_id.uint64 + DL_FOREACH(a_grace->usage->service->pricelist, l_price_tmp) { + if (l_price_tmp && l_price_tmp->net->pub.id.uint64 == a_grace->usage->net->pub.id.uint64 && dap_strcmp(l_price_tmp->token, l_ticker) == 0 && l_price_tmp->units_uid.enm == l_tx_out_cond->subtype.srv_pay.unit.enm )//&& (l_price_tmp->value_datoshi/l_price_tmp->units) < l_tx_out_cond->subtype.srv_pay.header.unit_price_max_datoshi) @@ -251,102 +392,231 @@ static bool s_grace_period_control(dap_chain_net_srv_grace_t *a_grace) log_it( L_WARNING, "Request can't be processed because no acceptable price in pricelist for token %s in network %s", l_ticker, l_net->pub.name ); l_err.code =DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NOT_ACCEPT_TOKEN; - goto free_exit; + s_grace_error(a_grace, l_err); + return; + } + a_grace->usage->price = l_price; + int ret; + if ((ret = a_grace->usage->service->callbacks.requested(a_grace->usage->service, a_grace->usage->id, a_grace->usage->client, a_grace->request, a_grace->request_size)) != 0) { + log_it( L_WARNING, "Request canceled by service callback, return code %d", ret); + l_err.code = (uint32_t) ret ; + s_grace_error(a_grace, l_err); + return; } - } - int ret; - if ((ret = l_srv->callbacks.requested(l_srv, l_usage->id, l_usage->client, l_request, a_grace->request_size)) != 0) { - log_it( L_WARNING, "Request canceled by service callback, return code %d", ret); - l_err.code = (uint32_t) ret ; - goto free_exit; - } - if ( l_srv->pricelist) { - if (l_price || l_grace_start) { - if (l_price) { - if (a_grace->usage) { - DAP_DELETE(l_usage->price); - } - } else { - l_price = DAP_NEW_Z(dap_chain_net_srv_price_t); - memcpy(l_price, l_srv->pricelist, sizeof(*l_price)); - l_price->value_datoshi = uint256_0; - } - l_usage->price = l_price; - if (l_usage->receipt_next){ - DAP_DEL_Z(l_usage->receipt_next); - l_usage->receipt_next = dap_chain_net_srv_issue_receipt(l_usage->service, l_usage->price, NULL, 0); - }else{ - dap_chain_net_srv_price_t l_b_price = *l_usage->price; - if (l_grace_start || a_grace->usage){ - l_b_price.units *= 2; - MULT_256_256(l_b_price.value_datoshi, GET_256_FROM_64((uint64_t)2), &l_b_price.value_datoshi); - } - l_usage->receipt = dap_chain_net_srv_issue_receipt(l_usage->service, &l_b_price, NULL, 0); - dap_stream_ch_pkt_write_unsafe(l_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_REQUEST, - l_usage->receipt, l_usage->receipt->size); - } + if (a_grace->usage->receipt_next){ + DAP_DEL_Z(a_grace->usage->receipt_next); + a_grace->usage->receipt_next = dap_chain_net_srv_issue_receipt(a_grace->usage->service, a_grace->usage->price, NULL, 0); }else{ - l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_PRICE_NOT_FOUND ; - goto free_exit; + a_grace->usage->receipt = dap_chain_net_srv_issue_receipt(a_grace->usage->service, a_grace->usage->price, NULL, 0); + dap_stream_ch_pkt_write_unsafe(l_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_REQUEST, + a_grace->usage->receipt, a_grace->usage->receipt->size); } - // If we a here we passed all the checks, wow, now if we're not for free we request the signature. - } else{ - log_it( L_INFO, "Service provide for free"); - l_usage->is_free = true; - size_t l_success_size = sizeof (dap_stream_ch_chain_net_srv_pkt_success_hdr_t ); - dap_stream_ch_chain_net_srv_pkt_success_t *l_success = DAP_NEW_Z_SIZE(dap_stream_ch_chain_net_srv_pkt_success_t, - l_success_size); - l_success->hdr.usage_id = l_usage->id; - l_success->hdr.net_id.uint64 = l_usage->net->pub.id.uint64; - l_success->hdr.srv_uid.uint64 = l_usage->service->uid.uint64; - dap_stream_ch_pkt_write_unsafe(l_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_SUCCESS, l_success, l_success_size); - if (l_usage->service->callbacks.response_success) - l_usage->service->callbacks.response_success(l_usage->service, l_usage->id, l_usage->client, NULL, 0); - DAP_DELETE(l_success); - } - if (l_grace_start) { - l_usage->is_grace = true; - a_grace->usage = l_usage; - dap_timerfd_start_on_worker(a_grace->stream_worker->worker, l_srv->grace_period * 1000, - (dap_timerfd_callback_t)s_grace_period_control, a_grace); - return false; - } else { DAP_DELETE(a_grace->request); DAP_DELETE(a_grace); - l_usage->is_grace = false; + + } +} + +static bool s_grace_period_finish(usages_in_grace_t *a_grace_item) +{ + assert(a_grace_item); + dap_stream_ch_chain_net_srv_pkt_error_t l_err; + memset(&l_err, 0, sizeof(l_err)); + dap_chain_net_srv_grace_t *l_grace = a_grace_item->grace; + + dap_stream_ch_t *l_ch = dap_stream_ch_find_by_uuid_unsafe(l_grace->stream_worker, l_grace->ch_uuid); + + if (l_grace->usage->price && !l_grace->usage->receipt_next){ // if first grace delete price and set actual + DAP_DEL_Z(l_grace->usage->price); + } + + if (!l_ch){ + s_grace_error(l_grace, l_err); + HASH_DEL(s_grace_table, a_grace_item); + DAP_DEL_Z(a_grace_item); return false; } -free_exit: - if (l_err.code) { - if(l_ch) - dap_stream_ch_pkt_write_unsafe(l_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof (l_err)); - if (l_srv && l_srv->callbacks.response_error) - l_srv->callbacks.response_error(l_srv, 0, NULL, &l_err, sizeof(l_err)); + + if (l_grace->usage->is_waiting_new_tx_cond){ + log_it(L_INFO, "No new tx cond!"); + s_grace_error(l_grace, l_err); + l_grace->usage->is_waiting_new_tx_cond = false; + HASH_DEL(s_grace_table, a_grace_item); + DAP_DEL_Z(a_grace_item); + return false; } - if (a_grace->usage) { // add client pkey hash to banlist - a_grace->usage->is_active = false; - if (l_srv) { - dap_chain_net_srv_banlist_item_t *l_item = NULL; - pthread_mutex_lock(&l_srv->banlist_mutex); - HASH_FIND(hh, l_srv->ban_list, &a_grace->usage->client_pkey_hash, sizeof(dap_chain_hash_fast_t), l_item); - if (l_item) - pthread_mutex_unlock(&l_srv->banlist_mutex); - else { - l_item = DAP_NEW_Z(dap_chain_net_srv_banlist_item_t); - l_item->client_pkey_hash = a_grace->usage->client_pkey_hash; - l_item->ht_mutex = &l_srv->banlist_mutex; - l_item->ht_head = &l_srv->ban_list; - HASH_ADD(hh, l_srv->ban_list, client_pkey_hash, sizeof(dap_chain_hash_fast_t), l_item); - pthread_mutex_unlock(&l_srv->banlist_mutex); - dap_timerfd_start(l_srv->grace_period * 1000, (dap_timerfd_callback_t)s_unban_client, l_item); + + dap_chain_net_t * l_net = l_grace->usage->net; + + l_err.net_id.uint64 = l_net->pub.id.uint64; + l_err.srv_uid.uint64 = l_grace->usage->service->uid.uint64; + + dap_ledger_t * l_ledger = l_net->pub.ledger; + dap_chain_datum_tx_t * l_tx = NULL; + dap_chain_tx_out_cond_t * l_tx_out_cond = NULL; + + if ( !l_ledger ){ // No ledger + log_it( L_WARNING, "No Ledger"); + l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_NETWORK_NO_LEDGER ; + s_grace_error(l_grace, l_err); + HASH_DEL(s_grace_table, a_grace_item); + DAP_DEL_Z(a_grace_item); + return false; + } + log_it(L_INFO, "Grace period is over! Check tx in ledger."); + l_tx = dap_chain_ledger_tx_find_by_hash(l_ledger, &l_grace->usage->tx_cond_hash); + if ( ! l_tx ){ // No tx cond transaction, start grace-period + log_it( L_WARNING, "No tx cond transaction"); + l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NOT_FOUND ; + s_grace_error(l_grace, l_err); + HASH_DEL(s_grace_table, a_grace_item); + DAP_DEL_Z(a_grace_item); + return false; + } else { // Start srvice in normal pay mode + log_it(L_INFO, "Tx is found in ledger."); + l_grace->usage->tx_cond = l_tx; + + l_tx_out_cond = dap_chain_datum_tx_out_cond_get(l_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, NULL ); + + if ( ! l_tx_out_cond ) { // No conditioned output + log_it( L_WARNING, "No conditioned output"); + l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NO_COND_OUT ; + s_grace_error(l_grace, l_err); + HASH_DEL(s_grace_table, a_grace_item); + DAP_DEL_Z(a_grace_item); + return false; + } + + // Check cond output if it equesl or not to request + if (!dap_chain_net_srv_uid_compare(l_tx_out_cond->header.srv_uid, l_grace->usage->service->uid)) { + log_it( L_WARNING, "Wrong service uid in request, tx expect to close its output with 0x%016"DAP_UINT64_FORMAT_X, + l_tx_out_cond->header.srv_uid.uint64 ); + l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_WRONG_SRV_UID ; + s_grace_error(l_grace, l_err); + HASH_DEL(s_grace_table, a_grace_item); + DAP_DEL_Z(a_grace_item); + return false; + } + + dap_chain_net_srv_price_t * l_price = NULL; + const char * l_ticker = NULL; + l_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, &l_grace->usage->tx_cond_hash); + dap_stpcpy(l_grace->usage->token_ticker, l_ticker); + + dap_chain_net_srv_price_t *l_price_tmp; + DL_FOREACH(l_grace->usage->service->pricelist, l_price_tmp) { + if (l_price_tmp && l_price_tmp->net->pub.id.uint64 == l_grace->usage->net->pub.id.uint64 + && dap_strcmp(l_price_tmp->token, l_ticker) == 0 + && l_price_tmp->units_uid.enm == l_tx_out_cond->subtype.srv_pay.unit.enm + )//&& (l_price_tmp->value_datoshi/l_price_tmp->units) < l_tx_out_cond->subtype.srv_pay.header.unit_price_max_datoshi) + { + l_price = l_price_tmp; + break; + } + } + if ( !l_price ) { + log_it( L_WARNING, "Request can't be processed because no acceptable price in pricelist for token %s in network %s", + l_ticker, l_net->pub.name ); + l_err.code =DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NOT_ACCEPT_TOKEN; + s_grace_error(l_grace, l_err); + HASH_DEL(s_grace_table, a_grace_item); + DAP_DEL_Z(a_grace_item); + return false; + } + + l_grace->usage->price = l_price; + + int ret; + if ((ret = l_grace->usage->service->callbacks.requested(l_grace->usage->service, l_grace->usage->id, l_grace->usage->client, l_grace->request, l_grace->request_size)) != 0) { + log_it( L_WARNING, "Request canceled by service callback, return code %d", ret); + l_err.code = (uint32_t) ret ; + s_grace_error(l_grace, l_err); + HASH_DEL(s_grace_table, a_grace_item); + DAP_DEL_Z(a_grace_item); + return false; + } + + // make receipt or tx + char *l_receipt_hash_str; + dap_chain_datum_tx_receipt_t *l_receipt = NULL; + if (l_grace->usage->receipt_next){ + l_receipt = l_grace->usage->receipt_next; + } else if (l_grace->usage->receipt){ + l_receipt = l_grace->usage->receipt; + } else { + // Send error??? + } + size_t l_receipt_size = l_receipt->size; + + // get a second signature - from the client (first sign in server, second sign in client) + dap_sign_t * l_receipt_sign = dap_chain_datum_tx_receipt_sign_get( l_receipt, l_receipt_size, 1); + if ( ! l_receipt_sign ){ + log_it(L_WARNING, "Tx already in chain, but receipt is not signed by client. Finish grace and wait receipt sign responce."); + s_grace_error(l_grace, l_err); + HASH_DEL(s_grace_table, a_grace_item); + DAP_DEL_Z(a_grace_item); + return false; + } + dap_get_data_hash_str_static(l_receipt, l_receipt_size, l_receipt_hash_str); + dap_global_db_set("local.receipts", l_receipt_hash_str, l_receipt, l_receipt_size, false, NULL, NULL); + // Form input transaction + char *l_hash_str = dap_hash_fast_to_str_new(&l_grace->usage->tx_cond_hash); + log_it(L_NOTICE, "Trying create input tx cond from tx %s with active receipt", l_hash_str); + DAP_DEL_Z(l_hash_str); + dap_chain_addr_t *l_wallet_addr = dap_chain_wallet_get_addr(l_grace->usage->price->wallet, l_grace->usage->net->pub.id); + int ret_status = 0; + char *l_tx_in_hash_str = dap_chain_mempool_tx_create_cond_input(l_grace->usage->net, &l_grace->usage->tx_cond_hash, l_wallet_addr, + dap_chain_wallet_get_key(l_grace->usage->price->wallet, 0), + l_receipt, "hex", &ret_status); + DAP_DEL_Z(l_wallet_addr); + if (!ret_status) { + dap_chain_hash_fast_from_str(l_tx_in_hash_str, &l_grace->usage->tx_cond_hash); + log_it(L_NOTICE, "Formed tx %s for input with active receipt", l_tx_in_hash_str); + DAP_DELETE(l_tx_in_hash_str); + + }else{ + if(ret_status == DAP_CHAIN_MEMPOOl_RET_STATUS_NOT_ENOUGH){ +// memset(&l_grace->usage->tx_cond_hash, 0, sizeof(l_grace->usage->tx_cond_hash)); +// DAP_DEL_Z(l_grace->usage->receipt_next); + log_it(L_ERROR, "Tx cond have not enough funds"); + dap_chain_net_srv_grace_t* l_grace_new = DAP_NEW_Z(dap_chain_net_srv_grace_t); + // Parse the request + l_grace_new->request = DAP_NEW_Z_SIZE(dap_stream_ch_chain_net_srv_pkt_request_t, sizeof(dap_stream_ch_chain_net_srv_pkt_request_t)); + l_grace_new->request->hdr.net_id = a_grace_item->grace->usage->net->pub.id; + memcpy(l_grace_new->request->hdr.token, a_grace_item->grace->usage->token_ticker, strlen(a_grace_item->grace->usage->token_ticker)); + l_grace_new->request->hdr.srv_uid = a_grace_item->grace->usage->service->uid; + l_grace_new->request->hdr.tx_cond = a_grace_item->grace->usage->tx_cond_hash; + l_grace_new->request_size = sizeof(dap_stream_ch_chain_net_srv_pkt_request_t); + l_grace_new->ch_uuid = a_grace_item->grace->usage->client->ch->uuid; + l_grace_new->stream_worker = a_grace_item->grace->usage->client->ch->stream_worker; + l_grace_new->usage = a_grace_item->grace->usage; + l_grace_new->usage->is_waiting_new_tx_cond = true; + s_grace_period_start(l_grace_new); + + l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NOT_ENOUGH; + dap_stream_ch_pkt_write_unsafe(l_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof (l_err)); + + }else{ + log_it(L_ERROR, "Can't create input tx cond transaction!"); + memset(&l_grace->usage->tx_cond_hash, 0, sizeof(l_grace->usage->tx_cond_hash)); + if (l_grace->usage->receipt_next){ + DAP_DEL_Z(l_grace->usage->receipt_next); + } else if (l_grace->usage->receipt){ + DAP_DEL_Z(l_grace->usage->receipt); + } + l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_SERVICE_NOT_FOUND; + dap_stream_ch_pkt_write_unsafe(l_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof (l_err)); + if (l_grace->usage->service->callbacks.response_error) + l_grace->usage->service->callbacks.response_error(l_grace->usage->service,l_grace->usage->id, l_grace->usage->client,&l_err,sizeof (l_err)); } } } - else if (l_usage) - dap_chain_net_srv_usage_delete(l_srv_session, l_usage); - DAP_DELETE(a_grace->request); - DAP_DELETE(a_grace); + l_grace->usage->is_grace = false; + DAP_DELETE(a_grace_item->grace->request); + DAP_DEL_Z(a_grace_item->grace); + HASH_DEL(s_grace_table, a_grace_item); + DAP_DEL_Z(a_grace_item); return false; } @@ -434,26 +704,27 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg) log_it( L_WARNING, "Wrong request size, less than minimum"); break; } - dap_chain_net_srv_grace_t *l_grace = DAP_NEW_Z(dap_chain_net_srv_grace_t); - // Parse the request - l_grace->request = DAP_NEW_Z_SIZE(dap_stream_ch_chain_net_srv_pkt_request_t, l_ch_pkt->hdr.data_size); - memcpy(l_grace->request, l_ch_pkt->data, l_ch_pkt->hdr.data_size); - l_ch_chain_net_srv->srv_uid.uint64 = l_grace->request->hdr.srv_uid.uint64; - l_grace->request_size = l_ch_pkt->hdr.data_size; - l_grace->ch_uuid = a_ch->uuid; - l_grace->stream_worker = a_ch->stream_worker; - s_grace_period_control(l_grace); + dap_stream_ch_chain_net_srv_pkt_request_t *l_request = DAP_NEW_Z_SIZE(dap_stream_ch_chain_net_srv_pkt_request_t, l_ch_pkt->hdr.data_size); + memcpy(l_request, l_ch_pkt->data, l_ch_pkt->hdr.data_size); + l_ch_chain_net_srv->srv_uid.uint64 = l_request->hdr.srv_uid.uint64; + s_service_start(a_ch, l_request, l_ch_pkt->hdr.data_size); } break; /* DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_REQUEST */ case DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_RESPONSE: { // Check receipt sign and make tx if success - if (l_ch_pkt->hdr.data_size < sizeof(dap_chain_receipt_info_t)) { + dap_chain_net_srv_usage_t * l_usage = l_srv_session->usage_active; + if (l_ch_pkt->hdr.data_size < sizeof(dap_chain_receipt_info_t)) { log_it(L_ERROR, "Wrong sign response size, %u when expected at least %zu with smth", l_ch_pkt->hdr.data_size, sizeof(dap_chain_receipt_info_t)); + if ( l_usage->receipt_next ){ // If we have receipt next + DAP_DEL_Z(l_usage->receipt_next); + }else if (l_usage->receipt ){ // If we sign first receipt + DAP_DEL_Z(l_usage->receipt); + } break; } dap_chain_datum_tx_receipt_t * l_receipt = (dap_chain_datum_tx_receipt_t *) l_ch_pkt->data; size_t l_receipt_size = l_ch_pkt->hdr.data_size; - dap_chain_net_srv_usage_t * l_usage = l_srv_session->usage_active; + bool l_is_found = false; if ( l_usage->receipt_next ){ // If we have receipt next if ( memcmp(&l_usage->receipt_next->receipt_info, &l_receipt->receipt_info,sizeof (l_receipt->receipt_info) )==0 ){ @@ -488,9 +759,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg) &l_err, sizeof (l_err) ); break; } - int l_tx_out_cond_size =0; - l_tx_out_cond = (dap_chain_tx_out_cond_t *)dap_chain_datum_tx_item_get(l_usage->tx_cond, NULL, - TX_ITEM_TYPE_OUT_COND, &l_tx_out_cond_size ); + l_tx_out_cond = dap_chain_datum_tx_out_cond_get(l_usage->tx_cond, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, NULL ); if ( ! l_tx_out_cond ){ // No conditioned output l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NO_COND_OUT ; dap_stream_ch_pkt_write_unsafe( a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof (l_err) ); @@ -519,6 +788,19 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg) HASH_FIND(hh, l_srv->ban_list, &l_usage->client_pkey_hash, sizeof(dap_chain_hash_fast_t), l_item); pthread_mutex_unlock(&l_srv->banlist_mutex); if (l_item) { // client banned + log_it(L_INFO, "Client pkey is banned!"); + usages_in_grace_t *l_grace_item = NULL; + pthread_mutex_lock(&s_ht_grace_table_mutex); + HASH_FIND(hh, s_grace_table, &l_usage->tx_cond_hash, sizeof(dap_hash_fast_t), l_grace_item); + if (l_grace_item){ + // Stop timer + dap_timerfd_delete_mt(l_grace_item->grace->stream_worker->worker, l_grace_item->grace->timer_es_uuid); + // finish grace + HASH_DEL(s_grace_table, l_grace_item); + DAP_DEL_Z(l_grace_item); + + } + pthread_mutex_unlock(&s_ht_grace_table_mutex); l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_RECEIPT_BANNED_PKEY_HASH ; dap_stream_ch_pkt_write_unsafe(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof(l_err)); if (l_usage->service->callbacks.response_error) @@ -538,13 +820,13 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg) // Update actual receipt bool l_is_first_sign = false; if (! l_usage->receipt_next && l_usage->receipt){ - DAP_DELETE(l_usage->receipt); + DAP_DEL_Z(l_usage->receipt); l_usage->receipt = DAP_NEW_SIZE(dap_chain_datum_tx_receipt_t,l_receipt_size); l_is_first_sign = true; l_usage->is_active = true; memcpy( l_usage->receipt, l_receipt, l_receipt_size); } else if (l_usage->receipt_next ){ - DAP_DELETE(l_usage->receipt_next); + DAP_DEL_Z(l_usage->receipt_next); l_usage->receipt_next = DAP_NEW_SIZE(dap_chain_datum_tx_receipt_t,l_receipt_size); l_usage->is_active = true; memcpy( l_usage->receipt_next, l_receipt, l_receipt_size); @@ -579,26 +861,41 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg) l_grace = DAP_NEW_Z(dap_chain_net_srv_grace_t); UNUSED(l_grace); // Parse the request -// l_grace->request = DAP_NEW_Z_SIZE(dap_stream_ch_chain_net_srv_pkt_request_t, sizeof(dap_stream_ch_chain_net_srv_pkt_request_t)); -// l_grace->request->hdr.net_id = l_usage->net->pub.id; -// memcpy(l_grace->request->hdr.token, l_usage->token_ticker, strlen(l_usage->token_ticker)); -// l_grace->request->hdr.srv_uid = l_usage->service->uid; -// l_grace->request->hdr.tx_cond = l_usage->tx_cond_hash; -// l_ch_chain_net_srv->srv_uid.uint64 = l_grace->request->hdr.srv_uid.uint64; -// l_grace->request_size = l_ch_pkt->hdr.data_size; -// l_grace->ch_uuid = a_ch->uuid; -// l_grace->stream_worker = a_ch->stream_worker; -// s_grace_period_control(l_grace); + l_grace->request = DAP_NEW_Z_SIZE(dap_stream_ch_chain_net_srv_pkt_request_t, sizeof(dap_stream_ch_chain_net_srv_pkt_request_t)); + l_grace->request->hdr.net_id = l_usage->net->pub.id; + memcpy(l_grace->request->hdr.token, l_usage->token_ticker, strlen(l_usage->token_ticker)); + l_grace->request->hdr.srv_uid = l_usage->service->uid; + l_grace->request->hdr.tx_cond = l_usage->tx_cond_hash; + l_ch_chain_net_srv->srv_uid.uint64 = l_grace->request->hdr.srv_uid.uint64; + l_grace->request_size = l_ch_pkt->hdr.data_size; + l_grace->ch_uuid = a_ch->uuid; + l_grace->stream_worker = a_ch->stream_worker; + l_grace->usage = l_usage; + s_grace_period_start(l_grace); + DAP_DELETE(l_tx_in_hash_str); break; case DAP_CHAIN_MEMPOOl_RET_STATUS_NOT_ENOUGH: // TODO send new tx cond request - memset(&l_usage->tx_cond_hash, 0, sizeof(l_usage->tx_cond_hash)); - DAP_DEL_Z(l_usage->receipt_next); log_it(L_ERROR, "Tx cond have not enough funds"); + l_usage->is_waiting_new_tx_cond = true; + l_grace = DAP_NEW_Z(dap_chain_net_srv_grace_t); + // Parse the request + l_grace->request = DAP_NEW_Z_SIZE(dap_stream_ch_chain_net_srv_pkt_request_t, sizeof(dap_stream_ch_chain_net_srv_pkt_request_t)); + l_grace->request->hdr.net_id = l_usage->net->pub.id; + memcpy(l_grace->request->hdr.token, l_usage->token_ticker, strlen(l_usage->token_ticker)); + l_grace->request->hdr.srv_uid = l_usage->service->uid; + l_grace->request->hdr.tx_cond = l_usage->tx_cond_hash; + l_ch_chain_net_srv->srv_uid.uint64 = l_grace->request->hdr.srv_uid.uint64; + l_grace->request_size = l_ch_pkt->hdr.data_size; + l_grace->ch_uuid = a_ch->uuid; + l_grace->stream_worker = a_ch->stream_worker; + l_grace->usage = l_usage; + s_grace_period_start(l_grace); l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NOT_ENOUGH; dap_stream_ch_pkt_write_unsafe(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof (l_err)); -// if (l_usage->service->callbacks.response_error) -// l_usage->service->callbacks.response_error(l_usage->service,l_usage->id, l_usage->client,&l_err,sizeof (l_err)); + if (l_usage->service->callbacks.response_error) + l_usage->service->callbacks.response_error(l_usage->service,l_usage->id, l_usage->client,&l_err,sizeof (l_err)); + DAP_DELETE(l_tx_in_hash_str); break; case DAP_CHAIN_MEMPOOL_RET_STATUS_BAD_ARGUMENTS: case DAP_CHAIN_MEMPOOl_RET_STATUS_WRONG_ADDR: @@ -614,16 +911,17 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg) dap_stream_ch_pkt_write_unsafe(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof (l_err)); if (l_usage->service->callbacks.response_error) l_usage->service->callbacks.response_error(l_usage->service,l_usage->id, l_usage->client,&l_err,sizeof (l_err)); + DAP_DELETE(l_tx_in_hash_str); break; } - - - break; + if (!l_usage->is_grace) + break; } l_success_size = sizeof(dap_stream_ch_chain_net_srv_pkt_success_hdr_t) + DAP_CHAIN_HASH_FAST_STR_SIZE;//sizeof(dap_chain_hash_fast_t); } else { l_success_size = sizeof(dap_stream_ch_chain_net_srv_pkt_success_hdr_t); } + dap_stream_ch_chain_net_srv_pkt_success_t *l_success = DAP_NEW_STACK_SIZE(dap_stream_ch_chain_net_srv_pkt_success_t, l_success_size); memset(&l_success->hdr, 0, sizeof(l_success->hdr)); @@ -634,8 +932,9 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg) if (l_usage->is_grace){ char *l_hash_str = dap_hash_fast_to_str_new(&l_usage->tx_cond_hash); - log_it(L_NOTICE, "Receipt is OK, but transaction %s can't be found. Start the grace period for %d seconds", l_hash_str, - l_srv->grace_period); + log_it(L_NOTICE, "Receipt is OK, but tx transaction %s %s. Start the grace period for %d seconds", l_hash_str, + l_usage->is_waiting_new_tx_cond ? "have no enough funds. New tx cond requested": "can't be found", + l_srv->grace_period); DAP_DEL_Z(l_hash_str); }else { char *l_hash_str = dap_hash_fast_to_str_new(&l_usage->tx_cond_hash); @@ -708,10 +1007,56 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg) dap_chain_net_srv_usage_t * l_usage = NULL; l_usage = l_srv_session->usage_active; dap_stream_ch_chain_net_srv_pkt_request_t* l_responce = (dap_stream_ch_chain_net_srv_pkt_request_t*)l_ch_pkt->data; - l_usage->tx_cond_hash = l_responce->hdr.tx_cond; - char *l_tx_in_hash_str = dap_chain_hash_fast_to_str_new(&l_usage->tx_cond_hash); + + char *l_tx_in_hash_str = dap_chain_hash_fast_to_str_new(&l_responce->hdr.tx_cond); log_it(L_NOTICE, "Received new tx cond %s", l_tx_in_hash_str); DAP_DELETE(l_tx_in_hash_str); + + if(!l_usage->is_waiting_new_tx_cond || !l_usage->is_grace) + break; + + l_usage->is_waiting_new_tx_cond = false; + dap_stream_ch_chain_net_srv_pkt_error_t l_err = { }; + usages_in_grace_t *l_curr_grace_item = NULL; + pthread_mutex_lock(&s_ht_grace_table_mutex); + HASH_FIND(hh, s_grace_table, &l_usage->tx_cond_hash, sizeof(dap_hash_fast_t), l_curr_grace_item); + pthread_mutex_unlock(&s_ht_grace_table_mutex); + + if (dap_hash_fast_is_blank(&l_responce->hdr.tx_cond)){ //if new tx cond creation failed tx_cond in responce will be blank + if (l_curr_grace_item){ + HASH_DEL(s_grace_table, l_curr_grace_item); + dap_timerfd_delete_mt(l_curr_grace_item->grace->stream_worker->worker, l_curr_grace_item->grace->timer_es_uuid); + s_grace_error(l_curr_grace_item->grace, l_err); + DAP_DEL_Z(l_curr_grace_item); + } + break; + } + + dap_chain_datum_tx_t *l_tx = dap_chain_ledger_tx_find_by_hash(l_usage->net->pub.ledger, &l_responce->hdr.tx_cond); + if (l_tx){ + // Replace + if (l_curr_grace_item){ + log_it(L_INFO, "Found tx in ledger by net tx responce handler. Finish waiting new tx grace period."); + // Stop timer + dap_timerfd_delete_mt(l_curr_grace_item->grace->stream_worker->worker, l_curr_grace_item->grace->timer_es_uuid); + // finish grace + l_usage->tx_cond_hash = l_responce->hdr.tx_cond; + l_curr_grace_item->grace->request->hdr.tx_cond = l_responce->hdr.tx_cond; + s_grace_period_finish(l_curr_grace_item); + } + }else{ + if (l_curr_grace_item){ + l_curr_grace_item->grace->usage->tx_cond_hash = l_responce->hdr.tx_cond; + l_curr_grace_item->grace->request->hdr.tx_cond = l_responce->hdr.tx_cond; + pthread_mutex_lock(&s_ht_grace_table_mutex); + HASH_DEL(s_grace_table, l_curr_grace_item); + l_curr_grace_item->tx_cond_hash = l_responce->hdr.tx_cond; + HASH_ADD(hh, s_grace_table, tx_cond_hash, sizeof(dap_hash_fast_t), l_curr_grace_item); + pthread_mutex_unlock(&s_ht_grace_table_mutex); + } + } + + size_t l_success_size = sizeof (dap_stream_ch_chain_net_srv_pkt_success_hdr_t ); dap_stream_ch_chain_net_srv_pkt_success_t *l_success = DAP_NEW_Z_SIZE(dap_stream_ch_chain_net_srv_pkt_success_t, l_success_size); diff --git a/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.h b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.h index 53490cc0c59594dc5215bceb4549146935108c6c..649a749c21f00447d3b8d18b9f27801043aa0b1c 100644 --- a/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.h +++ b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.h @@ -29,6 +29,16 @@ #include "dap_stream_ch_pkt.h" #include "dap_chain_common.h" +#include "dap_chain.h" +#include "dap_chain_datum_tx.h" +#include "dap_chain_datum_tx_in.h" +#include "dap_chain_datum_tx_in_cond.h" +#include "dap_chain_datum_tx_out.h" +#include "dap_chain_datum_tx_out_cond.h" +#include "dap_chain_datum_tx_receipt.h" +#include "dap_chain_mempool.h" +#include "dap_common.h" + typedef struct dap_stream_ch_chain_net_srv dap_stream_ch_chain_net_srv_t; typedef void (*dap_stream_ch_chain_net_srv_callback_packet_t)(dap_stream_ch_chain_net_srv_t *, uint8_t, @@ -46,3 +56,5 @@ typedef struct dap_stream_ch_chain_net_srv { uint8_t dap_stream_ch_chain_net_srv_get_id(); int dap_stream_ch_chain_net_srv_init(void); + +void dap_stream_ch_chain_net_srv_tx_cond_added_cb(void *a_arg, dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx); diff --git a/modules/channel/chain-net/dap_stream_ch_chain_net.c b/modules/channel/chain-net/dap_stream_ch_chain_net.c index 85ba2f81e1866c5072f607ad2e5b7a7a95dd2725..da1d49c44ec4be0d65da832d52821cd1d2f4f178 100644 --- a/modules/channel/chain-net/dap_stream_ch_chain_net.c +++ b/modules/channel/chain-net/dap_stream_ch_chain_net.c @@ -173,6 +173,11 @@ void s_stream_ch_new(dap_stream_ch_t* a_ch, void* a_arg) HASH_FIND_INT(s_chain_net_data, &a_ch->stream->session->id, l_sdata); if(l_sdata == NULL) { l_sdata = DAP_NEW_Z(dap_chain_net_session_data_t); + if (!l_sdata) { + log_it(L_ERROR, "Memory allocation error in s_stream_ch_new"); + pthread_mutex_unlock(&s_hash_mutex); + return; + } l_sdata->session_id = a_ch->stream->session->id; HASH_ADD_INT(s_chain_net_data, session_id, l_sdata); } diff --git a/modules/channel/chain-voting/dap_stream_ch_chain_voting.c b/modules/channel/chain-voting/dap_stream_ch_chain_voting.c index 5077f939c05e85147746d05df1c1b02b64d5f18a..a2b39e60f256b368a51e288693b72af953e88257 100644 --- a/modules/channel/chain-voting/dap_stream_ch_chain_voting.c +++ b/modules/channel/chain-voting/dap_stream_ch_chain_voting.c @@ -105,6 +105,10 @@ void dap_stream_ch_chain_voting_message_write(dap_chain_net_t *a_net, dap_chain_ l_node_client->client->always_reconnect = true; l_node_client_item = DAP_NEW_Z(struct voting_node_client_list); + if (!l_node_client_item) { + log_it(L_ERROR, "Memory allocation error in dap_stream_ch_chain_voting_message_write"); + return; + } l_node_client_item->node_addr = *a_remote_node_addr; l_node_client_item->node_info = l_node_info; l_node_client_item->node_client = l_node_client; diff --git a/modules/channel/chain/dap_stream_ch_chain.c b/modules/channel/chain/dap_stream_ch_chain.c index 9f1f329765bf1ad6f8d5ac9f2c5dc07b74e12afe..47f8fc81c08ebc55bf1c3e736bf593936384ea8b 100644 --- a/modules/channel/chain/dap_stream_ch_chain.c +++ b/modules/channel/chain/dap_stream_ch_chain.c @@ -645,40 +645,6 @@ static void s_gdb_sync_tsd_worker_callback(dap_worker_t *a_worker, void *a_arg) DAP_DELETE(l_sync_request); } -/** - * @brief - * - * @param net_id - * @param group_name - * @return dap_chain_t* - */ -dap_chain_t *dap_chain_get_chain_from_group_name(dap_chain_net_id_t a_net_id, const char *a_group_name) -{ - if (!a_group_name) { - log_it(L_ERROR, "GDB group name is NULL "); - return NULL; - } - dap_chain_net_t *l_net = dap_chain_net_by_id(a_net_id); - if (!l_net) - return NULL; - dap_chain_t *l_chain = NULL; - DL_FOREACH(l_net->pub.chains, l_chain) { - char *l_chain_group_name = dap_chain_net_get_gdb_group_from_chain_new(l_chain); - if (!strcmp(a_group_name, l_chain_group_name)) { - DAP_DELETE(l_chain_group_name); - return l_chain; - } - DAP_DELETE(l_chain_group_name); - } - return NULL; -} - -struct gdb_apply_args { - dap_store_obj_t *obj; - dap_nanotime_t limit_time; - struct sync_request *sync_request; -}; - /** * @brief s_gdb_in_pkt_proc_callback_get_ts_callback * @param a_global_db_context @@ -691,82 +657,7 @@ struct gdb_apply_args { * @param a_is_pinned * @param a_arg */ -static void s_gdb_in_pkt_proc_callback_apply(dap_global_db_context_t *a_global_db_context, void *a_arg) -{ - UNUSED(a_global_db_context); - struct gdb_apply_args *l_args = a_arg; - dap_store_obj_t *l_obj = l_args->obj; - struct sync_request *l_sync_request = l_args->sync_request; - // timestamp for exist obj - dap_nanotime_t l_timestamp_cur = 0; - // Record is pinned or not - bool l_is_pinned_cur = false; - if (dap_global_db_driver_is(l_obj->group, l_obj->key)) { - dap_store_obj_t *l_read_obj = dap_global_db_driver_read(l_obj->group, l_obj->key, NULL); - if (l_read_obj) { - l_timestamp_cur = l_read_obj->timestamp; - l_is_pinned_cur = l_read_obj->flags & RECORD_PINNED; - dap_store_obj_free_one(l_read_obj); - } - } - // Do not overwrite pinned records - if (l_is_pinned_cur) { - debug_if(s_debug_more, L_WARNING, "Can't %s record from group %s key %s - current record is pinned", - l_obj->type != DAP_DB$K_OPTYPE_DEL ? "remove" : "rewrite", l_obj->group, l_obj->key); - goto ret; - } - // Deleted time - dap_nanotime_t l_timestamp_del = dap_global_db_get_del_ts_unsafe(a_global_db_context, l_obj->group, l_obj->key); - // Limit time - dap_nanotime_t l_limit_time = l_args->limit_time; - //check whether to apply the received data into the database - bool l_apply = false; - // check the applied object newer that we have stored or erased - if (l_obj->timestamp > (uint64_t)l_timestamp_del && - l_obj->timestamp > (uint64_t)l_timestamp_cur && - (l_obj->type != DAP_DB$K_OPTYPE_DEL || l_obj->timestamp > l_limit_time)) { - l_apply = true; - } - if (s_debug_more){ - char l_ts_str[50]; - dap_time_to_str_rfc822(l_ts_str, sizeof(l_ts_str), dap_nanotime_to_sec(l_obj->timestamp)); - log_it(L_DEBUG, "Unpacked log history: type='%c' (0x%02hhX) group=\"%s\" key=\"%s\"" - " timestamp=\"%s\" value_len=%" DAP_UINT64_FORMAT_U, - (char )l_obj->type, (char)l_obj->type, l_obj->group, - l_obj->key, l_ts_str, l_obj->value_len); - } - if (!l_apply) { - if (s_debug_more) { - if (l_obj->timestamp <= (uint64_t)l_timestamp_cur) - log_it(L_WARNING, "New data not applied, because newly object exists"); - if (l_obj->timestamp <= (uint64_t)l_timestamp_del) - log_it(L_WARNING, "New data not applied, because newly object is deleted"); - if ((l_obj->type == DAP_DB$K_OPTYPE_DEL && l_obj->timestamp <= l_limit_time)) - log_it(L_WARNING, "New data not applied, because object is too old"); - } - goto ret; - } - - dap_chain_t *l_chain = dap_chain_get_chain_from_group_name(l_sync_request->request_hdr.net_id, l_obj->group); - if (l_chain && l_chain->callback_add_datums) { - log_it(L_WARNING, "New data goes to GDB chain"); - const void * restrict l_store_obj_value = l_obj->value; - l_chain->callback_add_datums(l_chain, - (dap_chain_datum_t** restrict) &l_store_obj_value, 1); - } else { - // save data to global_db - if (dap_global_db_set_raw(l_obj, 1, s_gdb_in_pkt_proc_set_raw_callback, l_sync_request) != 0) - log_it(L_ERROR, "Can't send save GlobalDB request"); - else // do not delete it here - l_sync_request = NULL; - } -ret: - dap_store_obj_free_one(l_obj); - DAP_DEL_Z(l_sync_request); - DAP_DELETE(l_args); - return; -} /** * @brief s_gdb_in_pkt_callback * @param a_thread @@ -815,7 +706,6 @@ static bool s_gdb_in_pkt_proc_callback(dap_proc_thread_t *a_thread, void *a_arg) uint32_t l_time_store_lim_hours = dap_config_get_item_uint32_default(g_config, "global_db", "time_store_limit", 72); dap_nanotime_t l_time_now = dap_nanotime_now(); dap_nanotime_t l_time_alowed = l_time_now + dap_nanotime_from_sec(3600 * 24); // to be sure the timestamp is invalid - dap_nanotime_t l_limit_time = l_time_store_lim_hours ? l_time_now - dap_nanotime_from_sec(l_time_store_lim_hours * 3600) : 0; for (size_t i = 0; i < l_data_obj_count; i++) { // obj to add dap_store_obj_t *l_obj = l_store_obj + i; @@ -857,11 +747,7 @@ static bool s_gdb_in_pkt_proc_callback(dap_proc_thread_t *a_thread, void *a_arg) l_last_group = l_obj->group; l_last_type = l_obj->type; */ - struct gdb_apply_args *l_apply_args = DAP_NEW(struct gdb_apply_args); - l_apply_args->obj = dap_store_obj_copy(l_obj, 1); - l_apply_args->limit_time = l_limit_time; - l_apply_args->sync_request = DAP_DUP(l_sync_request); - dap_global_db_context_exec(s_gdb_in_pkt_proc_callback_apply, l_apply_args); + dap_global_db_remote_apply_obj(l_obj, s_gdb_in_pkt_proc_set_raw_callback, DAP_DUP(l_sync_request)); } if (l_store_obj) dap_store_obj_free(l_store_obj, l_data_obj_count); @@ -899,8 +785,7 @@ static void s_gdb_in_pkt_proc_set_raw_callback(dap_global_db_context_t *a_global dap_worker_exec_callback_inter(a_global_db_context->queue_worker_callback_input[l_sync_req->worker->id], s_gdb_in_pkt_error_worker_callback, l_sync_req); }else{ - if (s_debug_more) - log_it(L_DEBUG, "Added new GLOBAL_DB synchronization record"); + debug_if(s_debug_more, L_DEBUG, "Added new GLOBAL_DB synchronization record"); DAP_DELETE(l_sync_req); } } @@ -915,6 +800,10 @@ struct sync_request *dap_stream_ch_chain_create_sync_request(dap_stream_ch_chain { dap_stream_ch_chain_t * l_ch_chain = DAP_STREAM_CH_CHAIN(a_ch); struct sync_request *l_sync_request = DAP_NEW_Z(struct sync_request); + if (!l_sync_request) { + log_it(L_ERROR, "Memory allocation error in dap_stream_ch_chain_create_sync_request"); + return NULL; + } *l_sync_request = (struct sync_request) { .worker = a_ch->stream_worker->worker, .ch_uuid = a_ch->uuid, @@ -964,6 +853,7 @@ static bool s_chain_timer_callback(void *a_arg) l_ch_chain->request_hdr.net_id.uint64, l_ch_chain->request_hdr.chain_id.uint64, l_ch_chain->request_hdr.cell_id.uint64, NULL, 0); l_ch_chain->sent_breaks = 0; + l_ch_chain->timer_shots = 0; } if (l_ch_chain->state == CHAIN_STATE_SYNC_GLOBAL_DB && l_ch_chain->sent_breaks >= 3 * DAP_SYNC_TICKS_PER_SECOND) { debug_if(s_debug_more, L_INFO, "Send one global_db TSD packet (rest=%zu/%zu items)", @@ -973,6 +863,7 @@ static bool s_chain_timer_callback(void *a_arg) l_ch_chain->request_hdr.net_id.uint64, l_ch_chain->request_hdr.chain_id.uint64, l_ch_chain->request_hdr.cell_id.uint64, NULL, 0); l_ch_chain->sent_breaks = 0; + l_ch_chain->timer_shots = 0; } return true; } @@ -1149,6 +1040,10 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) l_hash_item_hashv, l_hash_item); if (!l_hash_item) { l_hash_item = DAP_NEW_Z(dap_stream_ch_chain_hash_item_t); + if (!l_hash_item) { + log_it(L_ERROR, "Memory allocation error in s_stream_ch_packet_in"); + return; + } l_hash_item->hash = l_element->hash; l_hash_item->size = l_element->size; HASH_ADD_BYHASHVALUE(hh, l_ch_chain->remote_gdbs, hash, sizeof(l_hash_item->hash), @@ -1360,6 +1255,10 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) l_hash_item_hashv, l_hash_item); if( ! l_hash_item ){ l_hash_item = DAP_NEW_Z(dap_stream_ch_chain_hash_item_t); + if (!l_hash_item) { + log_it(L_ERROR, "Memory allocation error in s_stream_ch_packet_in"); + return; + } l_hash_item->hash = l_element->hash; l_hash_item->size = l_element->size; HASH_ADD_BYHASHVALUE(hh, l_ch_chain->remote_atoms, hash, sizeof(dap_hash_fast_t), @@ -1478,7 +1377,8 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) dap_chain_hash_fast_to_str(&l_atom_hash, l_atom_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE); log_it(L_INFO, "In: CHAIN pkt: atom hash %s (size %zd)", l_atom_hash_str, l_chain_pkt_data_size); } - dap_proc_queue_add_callback_inter(a_ch->stream_worker->worker->proc_queue_input, s_sync_in_chains_callback, l_sync_request); + if (dap_proc_queue_add_callback_inter(a_ch->stream_worker->worker->proc_queue_input, s_sync_in_chains_callback, l_sync_request)) + log_it(L_ERROR, "System queue overflow with atom trying atom add. All following atoms will be rejected!"); } else { log_it(L_WARNING, "Empty chain packet"); s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, @@ -1786,11 +1686,15 @@ void s_stream_ch_packet_out(dap_stream_ch_t *a_ch, void *a_arg) l_skip_count++; } else { l_hash_item = DAP_NEW_Z(dap_stream_ch_chain_hash_item_t); + if (!l_hash_item) { + log_it(L_ERROR, "Memory allocation error in s_stream_ch_packet_out"); + return; + } l_hash_item->hash = l_obj->hash; l_hash_item->size = l_obj->pkt->data_size; HASH_ADD_BYHASHVALUE(hh, l_ch_chain->remote_gdbs, hash, sizeof(dap_chain_hash_fast_t), l_hash_item_hashv, l_hash_item); - l_pkt = dap_store_packet_multiple(l_pkt, l_obj->pkt); + l_pkt = dap_global_db_pkt_pack(l_pkt, l_obj->pkt); l_ch_chain->stats_request_gdb_processed++; l_pkt_size = sizeof(dap_global_db_pkt_t) + l_pkt->data_size; } @@ -1886,6 +1790,10 @@ void s_stream_ch_packet_out(dap_stream_ch_t *a_ch, void *a_arg) }*/ }else{ l_hash_item = DAP_NEW_Z(dap_stream_ch_chain_hash_item_t); + if (!l_hash_item) { + log_it(L_ERROR, "Memory allocation error in s_stream_ch_packet_out"); + return; + } l_hash_item->hash = *l_ch_chain->request_atom_iter->cur_hash; if(s_debug_more){ char l_atom_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; diff --git a/modules/channel/chain/include/dap_stream_ch_chain.h b/modules/channel/chain/include/dap_stream_ch_chain.h index 6a0d136033c448499d9ae2cfdc0dfaedf731d834..b0542a834c6a4d7433f062182134795bd45dd8d5 100644 --- a/modules/channel/chain/include/dap_stream_ch_chain.h +++ b/modules/channel/chain/include/dap_stream_ch_chain.h @@ -34,7 +34,7 @@ #include "uthash.h" #include "dap_global_db_remote.h" -#define DAP_CHAIN_NODE_SYNC_TIMEOUT 30 // sec +#define DAP_CHAIN_NODE_SYNC_TIMEOUT 60 // sec #define DAP_SYNC_TICKS_PER_SECOND 10 typedef struct dap_stream_ch_chain dap_stream_ch_chain_t; @@ -94,7 +94,6 @@ int dap_stream_ch_chain_init(void); void dap_stream_ch_chain_deinit(void); inline static uint8_t dap_stream_ch_chain_get_id(void) { return (uint8_t) 'C'; } -dap_chain_t * dap_chain_get_chain_from_group_name(dap_chain_net_id_t a_net_id, const char *a_group_name); void dap_stream_ch_chain_create_sync_request_gdb(dap_stream_ch_chain_t * a_ch_chain, dap_chain_net_t * a_net); void dap_stream_ch_chain_timer_start(dap_stream_ch_chain_t *a_ch_chain); void dap_stream_ch_chain_reset_unsafe(dap_stream_ch_chain_t *a_ch_chain); diff --git a/modules/common/dap_chain_common.c b/modules/common/dap_chain_common.c index e1ccc2930913f3994f02a57dd3d5d1aa1e182ae5..20fa9b9fc3e3a41ccda24a238caae7d07d3fd1ff 100644 --- a/modules/common/dap_chain_common.c +++ b/modules/common/dap_chain_common.c @@ -296,6 +296,10 @@ uint128_t dap_chain_uint128_from_uint256(uint256_t a_from) char *dap_chain_balance_print128(uint128_t a_balance) { char *l_buf = DAP_NEW_Z_SIZE(char, DATOSHI_POW + 2); + if (!l_buf) { + log_it(L_ERROR, "Memory allocation error in dap_chain_balance_print128"); + return NULL; + } int l_pos = 0; uint128_t l_value = a_balance; #ifdef DAP_GLOBAL_IS_INT128 @@ -626,6 +630,10 @@ uint256_t dap_chain_coins_to_balance256(const char *a_coins) char *dap_cvt_uint256_to_str(uint256_t a_uint256) { char *l_buf = DAP_NEW_Z_SIZE(char, DATOSHI_POW256 + 2); // for decimal dot and trailing zero + if (!l_buf) { + log_it(L_ERROR, "Memory allocation error in dap_cvt_uint256_to_str"); + return NULL; + } int l_pos = 0; uint256_t l_value = a_uint256; uint256_t uint256_ten = GET_256_FROM_64(10); diff --git a/modules/common/dap_chain_datum.c b/modules/common/dap_chain_datum.c index 945c9d35e86acd461304e6209c5c2eae8c7336a4..fa21942e376fe3541cdb300c51ccf1e83a8897d7 100644 --- a/modules/common/dap_chain_datum.c +++ b/modules/common/dap_chain_datum.c @@ -349,8 +349,20 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum, l_value_str); if (((dap_chain_datum_tx_receipt_t*)item)->exts_size == sizeof(dap_sign_t) + sizeof(dap_sign_t)){ dap_sign_t *l_provider = DAP_NEW_Z(dap_sign_t); + if (!l_provider) { + log_it(L_ERROR, "Memory allocation error in dap_chain_datum_dump_tx"); + DAP_DELETE(l_value_str); + DAP_DELETE(l_coins_str); + return false; + } memcpy(l_provider, ((dap_chain_datum_tx_receipt_t*)item)->exts_n_signs, sizeof(dap_sign_t)); dap_sign_t *l_client = DAP_NEW_Z(dap_sign_t); + if (!l_client) { + log_it(L_ERROR, "Memory allocation error in dap_chain_datum_dump_tx"); + DAP_DELETE(l_value_str); + DAP_DELETE(l_coins_str); + return false; + } memcpy(l_client, ((dap_chain_datum_tx_receipt_t*)item)->exts_n_signs + sizeof(dap_sign_t), sizeof(dap_sign_t)); @@ -361,6 +373,12 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum, dap_sign_get_information(l_client, a_str_out, a_hash_out_type); } else if (((dap_chain_datum_tx_receipt_t*)item)->exts_size == sizeof(dap_sign_t)) { dap_sign_t *l_provider = DAP_NEW_Z(dap_sign_t); + if (!l_provider) { + log_it(L_ERROR, "Memory allocation error in dap_chain_datum_dump_tx"); + DAP_DELETE(l_value_str); + DAP_DELETE(l_coins_str); + return false; + } memcpy(l_provider, ((dap_chain_datum_tx_receipt_t*)item)->exts_n_signs, sizeof(dap_sign_t)); dap_string_append_printf(a_str_out, "Exts:\n" " Provider:\n"); diff --git a/modules/common/dap_chain_datum_decree.c b/modules/common/dap_chain_datum_decree.c index 40adfe8121c6761740e0cf694624396766441399..1a9c50e8fe0fd840023e6e21beaad0bd72dbb978 100644 --- a/modules/common/dap_chain_datum_decree.c +++ b/modules/common/dap_chain_datum_decree.c @@ -450,6 +450,11 @@ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree char *l_stake_addr_signing_str = dap_chain_addr_to_str(&l_stake_addr_signing); dap_string_append_printf(a_str_out, "\tSigning addr: %s\n", l_stake_addr_signing_str); dap_chain_hash_fast_t *l_pkey_signing = DAP_NEW(dap_chain_hash_fast_t); + if (!l_pkey_signing) { + log_it(L_ERROR, "Memory allocation error in dap_chain_datum_decree_dump"); + DAP_DELETE(l_stake_addr_signing_str); + return; + } memcpy(l_pkey_signing, l_stake_addr_signing.data.key, sizeof(dap_chain_hash_fast_t)); char *l_pkey_signing_str = dap_strcmp(a_hash_out_type, "hex") ? dap_enc_base58_encode_hash_to_str(l_pkey_signing) diff --git a/modules/common/dap_chain_datum_token.c b/modules/common/dap_chain_datum_token.c index 4b10d01fd1c946098af9ba6885532a88abb98361..b2504b308f5ca1cb4366866980f5e31278335f15 100644 --- a/modules/common/dap_chain_datum_token.c +++ b/modules/common/dap_chain_datum_token.c @@ -66,107 +66,128 @@ const char *c_dap_chain_datum_token_flag_str[] = { */ dap_tsd_t* dap_chain_datum_token_tsd_get(dap_chain_datum_token_t *a_token, size_t a_token_size) { - // Check if token type could have tsd section - size_t l_hdr_size = sizeof(dap_chain_datum_token_t); - if (l_hdr_size > a_token_size){ - log_it(L_WARNING, "Token size smaller then header, corrupted data"); + if (a_token_size < sizeof(dap_chain_datum_token_t)){ + log_it(L_WARNING, "Token size %lu < %lu header size, corrupted token datum", a_token_size, sizeof(dap_chain_datum_token_t)); return NULL; } - return (dap_tsd_t *)a_token->data_n_tsd; + return (dap_tsd_t*)a_token->data_n_tsd; } dap_chain_datum_token_t *dap_chain_datum_token_read(const byte_t *a_token_serial, size_t *a_token_size) { dap_chain_datum_token_old_t *l_token_old = (dap_chain_datum_token_old_t*)a_token_serial; size_t l_token_data_n_tsd_size = *a_token_size - sizeof(dap_chain_datum_token_old_t); - size_t l_token_size = l_token_data_n_tsd_size + sizeof(dap_chain_datum_token_t); - dap_chain_datum_token_t *l_token = DAP_NEW_Z_SIZE(dap_chain_datum_token_t, l_token_size); - memcpy(l_token->ticker, l_token_old->ticker, sizeof(l_token_old->ticker)); - memcpy(l_token->data_n_tsd, l_token_old->data_n_tsd, (uint32_t)l_token_data_n_tsd_size); -// *a_token_size = l_token_size; + size_t l_token_size = l_token_data_n_tsd_size + sizeof(dap_chain_datum_token_t); switch (((dap_chain_datum_token_t*)a_token_serial)->type) { case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_SIMPLE: { - memcpy(l_token->ticker, l_token_old->ticker, sizeof(l_token_old->ticker)); -// memcpy(l_token->data_n_tsd, l_token_old->data_n_tsd, l_token_tsd_size); + dap_chain_datum_token_t *l_token = DAP_NEW_Z_SIZE(dap_chain_datum_token_t, l_token_size); + *l_token = (dap_chain_datum_token_t) { + .type = DAP_CHAIN_DATUM_TOKEN_TYPE_DECL, + .version = 1, + .subtype = DAP_CHAIN_DATUM_TOKEN_SUBTYPE_SIMPLE, + .signs_valid = l_token_old->signs_valid, + .signs_total = l_token_old->signs_total, + .total_supply = l_token_old->total_supply, + .header_simple.decimals = l_token_old->header_simple.decimals, + }; + dap_stpcpy(l_token->ticker, l_token_old->ticker); + memcpy(l_token->data_n_tsd, l_token_old->data_n_tsd, (uint32_t)l_token_data_n_tsd_size); *a_token_size = l_token_size; - l_token->type = DAP_CHAIN_DATUM_TOKEN_DECL; - l_token->total_supply = l_token_old->total_supply; - l_token->signs_valid = l_token_old->signs_valid; - l_token->signs_total = l_token_old->signs_total; - l_token->header_simple.decimals = l_token_old->header_simple.decimals; -// l_token->header_native_decl.tsd_total_size = l_token_tsd_size; - l_token->subtype = DAP_CHAIN_DATUM_TOKEN_SUBTYPE_SIMPLE; - l_token->version = 1; return l_token; } case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_DECL: { + dap_chain_datum_token_t *l_token = DAP_NEW_Z_SIZE(dap_chain_datum_token_t, l_token_size); + *l_token = (dap_chain_datum_token_t) { + .type = DAP_CHAIN_DATUM_TOKEN_TYPE_DECL, + .version = 1, + .subtype = DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE, + .signs_valid = l_token_old->signs_valid, + .signs_total = l_token_old->signs_total, + .total_supply = l_token_old->total_supply, + .header_private_decl.flags = l_token_old->header_private_decl.flags, + .header_private_decl.tsd_total_size = l_token_old->header_private_decl.tsd_total_size, + .header_private_decl.decimals = l_token_old->header_private_decl.decimals + }; + dap_stpcpy(l_token->ticker, l_token_old->ticker); + memcpy(l_token->data_n_tsd, l_token_old->data_n_tsd, (uint32_t)l_token_data_n_tsd_size); *a_token_size = l_token_size; - l_token->type = DAP_CHAIN_DATUM_TOKEN_TYPE_DECL; - l_token->total_supply = l_token_old->total_supply; - l_token->signs_valid = l_token_old->signs_valid; - l_token->signs_total = l_token_old->signs_total; - l_token->subtype = DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE; - l_token->header_private_decl.decimals = l_token_old->header_private_decl.decimals; - l_token->header_private_decl.tsd_total_size = l_token_old->header_private_decl.tsd_total_size; - l_token->header_private_decl.flags = l_token_old->header_private_decl.flags; - l_token->version = 1; return l_token; } case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_UPDATE: { + dap_chain_datum_token_t *l_token = DAP_NEW_Z_SIZE(dap_chain_datum_token_t, l_token_size); + *l_token = (dap_chain_datum_token_t) { + .type = DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE, + .version = 1, + .subtype = DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE, + .signs_valid = l_token_old->signs_valid, + .signs_total = l_token_old->signs_total, + .total_supply = l_token_old->total_supply, + .header_private_update.flags = l_token_old->header_private_update.flags, + .header_private_update.tsd_total_size = l_token_old->header_private_update.tsd_total_size, + .header_private_update.decimals = l_token_old->header_private_update.decimals + }; + dap_stpcpy(l_token->ticker, l_token_old->ticker); + memcpy(l_token->data_n_tsd, l_token_old->data_n_tsd, (uint32_t)l_token_data_n_tsd_size); *a_token_size = l_token_size; - l_token->type = DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE; - l_token->total_supply = l_token_old->total_supply; - l_token->signs_valid = l_token_old->signs_valid; - l_token->signs_total = l_token_old->signs_total; - l_token->subtype = DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE; - l_token->header_private_update.decimals = l_token_old->header_private_update.decimals; - l_token->header_private_update.tsd_total_size = l_token_old->header_private_update.tsd_total_size; - l_token->header_private_update.flags = l_token_old->header_private_update.flags; - l_token->version = 1; return l_token; } case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_NATIVE_DECL: { + dap_chain_datum_token_t *l_token = DAP_NEW_Z_SIZE(dap_chain_datum_token_t, l_token_size); + *l_token = (dap_chain_datum_token_t) { + .type = DAP_CHAIN_DATUM_TOKEN_TYPE_DECL, + .version = 1, + .subtype = DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE, + .signs_valid = l_token_old->signs_valid, + .signs_total = l_token_old->signs_total, + .total_supply = l_token_old->total_supply, + .header_native_decl.flags = l_token_old->header_native_decl.flags, + .header_native_decl.tsd_total_size = l_token_old->header_native_decl.tsd_total_size, + .header_native_decl.decimals = l_token_old->header_native_decl.decimals + }; + dap_stpcpy(l_token->ticker, l_token_old->ticker); + memcpy(l_token->data_n_tsd, l_token_old->data_n_tsd, (uint32_t)l_token_data_n_tsd_size); *a_token_size = l_token_size; - l_token->type = DAP_CHAIN_DATUM_TOKEN_TYPE_DECL; - l_token->total_supply = l_token_old->total_supply; - l_token->signs_valid = l_token_old->signs_valid; - l_token->signs_total = l_token_old->signs_total; - l_token->subtype = DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE; - l_token->header_native_decl.decimals = l_token_old->header_native_decl.decimals; - l_token->header_native_decl.tsd_total_size = l_token_old->header_native_decl.tsd_total_size; - l_token->header_native_decl.flags = l_token_old->header_native_decl.flags; - l_token->version = 1; return l_token; } case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_NATIVE_UPDATE: { + dap_chain_datum_token_t *l_token = DAP_NEW_Z_SIZE(dap_chain_datum_token_t, l_token_size); + *l_token = (dap_chain_datum_token_t) { + .type = DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE, + .version = 1, + .subtype = DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE, + .signs_valid = l_token_old->signs_valid, + .signs_total = l_token_old->signs_total, + .total_supply = l_token_old->total_supply, + .header_native_update.flags = l_token_old->header_native_update.flags, + .header_native_update.tsd_total_size = l_token_old->header_native_update.tsd_total_size, + .header_native_update.decimals = l_token_old->header_native_update.decimals + }; + dap_stpcpy(l_token->ticker, l_token_old->ticker); + memcpy(l_token->data_n_tsd, l_token_old->data_n_tsd, (uint32_t)l_token_data_n_tsd_size); *a_token_size = l_token_size; - l_token->type = DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE; - l_token->total_supply = l_token_old->total_supply; - l_token->signs_valid = l_token_old->signs_valid; - l_token->signs_total = l_token_old->signs_total; - l_token->subtype = DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE; - l_token->header_native_update.decimals = l_token_old->header_native_update.decimals; - l_token->header_native_update.tsd_total_size = l_token_old->header_native_update.tsd_total_size; - l_token->header_native_update.flags = l_token_old->header_native_update.flags; - l_token->version = 1; return l_token; } case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PUBLIC: { + dap_chain_datum_token_t *l_token = DAP_NEW_Z_SIZE(dap_chain_datum_token_t, l_token_size); + *l_token = (dap_chain_datum_token_t) { + .type = DAP_CHAIN_DATUM_TOKEN_TYPE_DECL, + .version = 1, + .subtype = DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PUBLIC, + .signs_valid = l_token_old->signs_valid, + .signs_total = l_token_old->signs_total, + .total_supply = l_token_old->total_supply, + .header_public.flags = l_token_old->header_public.flags, + .header_public.premine_supply = l_token_old->header_public.premine_supply, + .header_public.premine_address = l_token_old->header_public.premine_address + }; + dap_stpcpy(l_token->ticker, l_token_old->ticker); + memcpy(l_token->data_n_tsd, l_token_old->data_n_tsd, (uint32_t)l_token_data_n_tsd_size); *a_token_size = l_token_size; - l_token->type = DAP_CHAIN_DATUM_TOKEN_TYPE_DECL; - l_token->total_supply = l_token_old->total_supply; - l_token->signs_valid = l_token_old->signs_valid; - l_token->signs_total = l_token_old->signs_total; - l_token->subtype = DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PUBLIC; - l_token->header_public.flags = l_token_old->header_public.flags; - l_token->header_public.premine_address = l_token_old->header_public.premine_address; - l_token->header_public.premine_supply = l_token_old->header_public.premine_supply; - l_token->version = 1; return l_token; } default: - DAP_DELETE(l_token); + log_it(L_NOTICE, "Unknown token type '%d' read", ((dap_chain_datum_token_t*)a_token_serial)->type); return DAP_DUP_SIZE(a_token_serial, *a_token_size); - }; + } } /** @@ -250,6 +271,10 @@ dap_sign_t ** dap_chain_datum_token_signs_parse(dap_chain_datum_token_t * a_datu assert(a_signs_total); assert(a_signs_valid); assert(a_datum_token_size >= sizeof(dap_chain_datum_token_old_t)); + if (!a_datum_token->signs_total) { + log_it(L_ERROR, "No signs in datum token with ticker '%s', type %d", a_datum_token->ticker, a_datum_token->type); + return NULL; + } *a_signs_total = 0; *a_signs_valid = a_datum_token->signs_valid; size_t l_offset = 0; @@ -325,10 +350,13 @@ dap_sign_t ** dap_chain_datum_token_signs_parse(dap_chain_datum_token_t * a_datu dap_chain_datum_token_emission_t *dap_chain_datum_emission_create(uint256_t a_value, const char *a_ticker, dap_chain_addr_t *a_addr) { dap_chain_datum_token_emission_t *l_emission = DAP_NEW_Z(dap_chain_datum_token_emission_t); + if (!l_emission) { + log_it(L_ERROR, "Memory allocation error in dap_chain_datum_emission_create"); + return NULL; + } l_emission->hdr.version = 3; l_emission->hdr.value_256 = a_value; strncpy(l_emission->hdr.ticker, a_ticker, DAP_CHAIN_TICKER_SIZE_MAX - 1); - l_emission->hdr.ticker[DAP_CHAIN_TICKER_SIZE_MAX - 1] = '\0'; l_emission->hdr.type = DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH; l_emission->hdr.address = *a_addr; dap_uuid_generate_nonce(&l_emission->hdr.nonce, DAP_CHAIN_DATUM_NONCE_SIZE); diff --git a/modules/common/dap_chain_datum_tx.c b/modules/common/dap_chain_datum_tx.c index 6fdbfb13f137271b4fadb0e3fc7c499210fc1a7f..9480c69043adc17d7ff3e81a872496fcbfb991d5 100644 --- a/modules/common/dap_chain_datum_tx.c +++ b/modules/common/dap_chain_datum_tx.c @@ -39,6 +39,10 @@ dap_chain_datum_tx_t* dap_chain_datum_tx_create(void) { dap_chain_datum_tx_t *tx = DAP_NEW_Z(dap_chain_datum_tx_t); + if (!tx) { + log_it(L_ERROR, "Memory allocation error in dap_chain_datum_tx_create"); + return 0; + } tx->header.ts_created = time(NULL); return tx; } diff --git a/modules/common/dap_chain_datum_tx_items.c b/modules/common/dap_chain_datum_tx_items.c index b22863e40c30d66cac79789bd51778a65d684efd..5ec7c2a87bb068da296692742d95cdc411dc469d 100644 --- a/modules/common/dap_chain_datum_tx_items.c +++ b/modules/common/dap_chain_datum_tx_items.c @@ -235,6 +235,9 @@ dap_chain_tx_in_ems_t *dap_chain_datum_tx_item_in_ems_create(dap_chain_id_t a_id if(!a_ticker) return NULL; dap_chain_tx_in_ems_t *l_item = DAP_NEW_Z(dap_chain_tx_in_ems_t); + if (!l_item) { + return NULL; + } l_item->header.type = TX_ITEM_TYPE_IN_EMS; l_item->header.token_emission_chain_id.uint64 = a_id.uint64; l_item->header.token_emission_hash = *a_datum_token_hash;; @@ -266,6 +269,9 @@ dap_chain_tx_in_t* dap_chain_datum_tx_item_in_create(dap_chain_hash_fast_t *a_tx if(!a_tx_prev_hash) return NULL; dap_chain_tx_in_t *l_item = DAP_NEW_Z(dap_chain_tx_in_t); + if (!l_item) { + return NULL; + } l_item->header.type = TX_ITEM_TYPE_IN; l_item->header.tx_out_prev_idx = a_tx_out_prev_idx; l_item->header.tx_prev_hash = *a_tx_prev_hash; @@ -325,6 +331,9 @@ dap_chain_tx_in_cond_t* dap_chain_datum_tx_item_in_cond_create(dap_chain_hash_fa if(!a_tx_prev_hash ) return NULL; dap_chain_tx_in_cond_t *l_item = DAP_NEW_Z(dap_chain_tx_in_cond_t); + if (!l_item) { + return NULL; + } l_item->header.type = TX_ITEM_TYPE_IN_COND; l_item->header.receipt_idx = a_receipt_idx; l_item->header.tx_out_prev_idx = a_tx_out_prev_idx; @@ -360,6 +369,9 @@ dap_chain_tx_out_t* dap_chain_datum_tx_item_out_create(const dap_chain_addr_t *a if (!a_addr || IS_ZERO_256(a_value)) return NULL; dap_chain_tx_out_t *l_item = DAP_NEW_Z(dap_chain_tx_out_t); + if (!l_item) { + return NULL; + } l_item->addr = *a_addr; l_item->header.type = TX_ITEM_TYPE_OUT; l_item->header.value = a_value; @@ -382,6 +394,9 @@ dap_chain_tx_out_ext_t* dap_chain_datum_tx_item_out_ext_create(const dap_chain_a if (IS_ZERO_256(a_value)) return NULL; dap_chain_tx_out_ext_t *l_item = DAP_NEW_Z(dap_chain_tx_out_ext_t); + if (!l_item) { + return NULL; + } l_item->header.type = TX_ITEM_TYPE_OUT_EXT; l_item->header.value = a_value; l_item->addr = *a_addr; @@ -407,6 +422,9 @@ dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_fee(uint256_t a if (IS_ZERO_256(a_value)) return NULL; dap_chain_tx_out_cond_t *l_item = DAP_NEW_Z(dap_chain_tx_out_cond_t); + if (!l_item) { + return NULL; + } l_item->header.item_type = TX_ITEM_TYPE_OUT_COND; l_item->header.value = a_value; l_item->header.subtype = DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE; @@ -544,6 +562,9 @@ dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_stake(dap_c if (IS_ZERO_256(a_value)) return NULL; dap_chain_tx_out_cond_t *l_item = DAP_NEW_Z(dap_chain_tx_out_cond_t); + if (!l_item) { + return NULL; + } l_item->header.item_type = TX_ITEM_TYPE_OUT_COND; l_item->header.value = a_value; l_item->header.subtype = DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE; @@ -591,6 +612,9 @@ dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_stake_lock( if (IS_ZERO_256(a_value)) return NULL; dap_chain_tx_out_cond_t *l_item = DAP_NEW_Z(dap_chain_tx_out_cond_t); + if (!l_item) { + return NULL; + } l_item->header.item_type = TX_ITEM_TYPE_OUT_COND; l_item->header.value = a_value; l_item->header.subtype = DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK; diff --git a/modules/consensus/block-poa/dap_chain_cs_block_poa.c b/modules/consensus/block-poa/dap_chain_cs_block_poa.c index 42641314b8300041e05283905e976fd9e551e26b..04f795aebd4b6bab6835b650bf7e033d986c5cd7 100644 --- a/modules/consensus/block-poa/dap_chain_cs_block_poa.c +++ b/modules/consensus/block-poa/dap_chain_cs_block_poa.c @@ -176,11 +176,19 @@ static int s_callback_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg) dap_chain_cs_blocks_new(a_chain, a_chain_cfg); dap_chain_cs_blocks_t * l_blocks = DAP_CHAIN_CS_BLOCKS( a_chain ); dap_chain_cs_block_poa_t * l_poa = DAP_NEW_Z ( dap_chain_cs_block_poa_t); + if (!l_poa) { + log_it(L_ERROR, "Memory allocation error in s_callback_new"); + return -1; + } l_blocks->_inheritor = l_poa; l_blocks->callback_delete = s_callback_delete; l_blocks->callback_block_verify = s_callback_block_verify; l_blocks->callback_block_sign = s_callback_block_sign; l_poa->_pvt = DAP_NEW_Z(dap_chain_cs_block_poa_pvt_t); + if (!l_poa->_pvt) { + log_it(L_ERROR, "Memory allocation error in s_callback_new"); + return -1; + } dap_chain_cs_block_poa_pvt_t *l_poa_pvt = PVT(l_poa); if (dap_config_get_item_str(a_chain_cfg,"block-poa","auth_certs_prefix") ) { @@ -190,6 +198,10 @@ static int s_callback_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg) if (l_poa_pvt->auth_certs_count && l_poa_pvt->auth_certs_count_verify ) { // Type sizeof's misunderstanding in malloc? l_poa_pvt->auth_certs = DAP_NEW_Z_SIZE ( dap_cert_t *, l_poa_pvt->auth_certs_count * sizeof(dap_cert_t*)); + if (!l_poa_pvt->auth_certs) { + log_it(L_ERROR, "Memory allocation error in s_callback_new"); + return -1; + } char l_cert_name[512]; for (size_t i = 0; i < l_poa_pvt->auth_certs_count ; i++ ){ snprintf(l_cert_name,sizeof(l_cert_name),"%s.%zu",l_poa_pvt->auth_certs_prefix, i); diff --git a/modules/consensus/block-pos/dap_chain_cs_block_pos.c b/modules/consensus/block-pos/dap_chain_cs_block_pos.c index 70195b519698d764e5afac6f3b21cff3f50ab12a..6efe30b407bd14737c681e8017b930a2d9713b86 100644 --- a/modules/consensus/block-pos/dap_chain_cs_block_pos.c +++ b/modules/consensus/block-pos/dap_chain_cs_block_pos.c @@ -80,20 +80,26 @@ void dap_chain_cs_block_pos_deinit(void) static int s_callback_new(dap_chain_t *a_chain, dap_config_t *a_chain_cfg) { dap_chain_cs_blocks_new(a_chain, a_chain_cfg); + char ** l_tokens_hold = NULL; + char ** l_tokens_hold_value_str = NULL; + uint16_t l_tokens_hold_size = 0; + uint16_t l_tokens_hold_value_size = 0; dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain); dap_chain_cs_block_pos_t *l_pos = DAP_NEW_Z(dap_chain_cs_block_pos_t); + if (!l_pos) { + log_it(L_ERROR, "Memory allocation error in s_callback_new"); + return -1; + } l_blocks->_inheritor = l_pos; l_blocks->callback_delete = s_callback_delete; l_blocks->callback_block_verify = s_callback_block_verify; l_blocks->callback_block_sign = s_callback_block_sign; l_pos->_pvt = DAP_NEW_Z(dap_chain_cs_block_pos_pvt_t); - dap_chain_cs_block_pos_pvt_t *l_pos_pvt = PVT(l_pos); - - char ** l_tokens_hold = NULL; - char ** l_tokens_hold_value_str = NULL; - uint16_t l_tokens_hold_size = 0; - uint16_t l_tokens_hold_value_size = 0; + if (!l_pos->_pvt) { + log_it(L_ERROR, "Memory allocation error in s_callback_new"); + goto lb_err; + } l_tokens_hold = dap_config_get_array_str(a_chain_cfg, "block-pos", "stake_tokens", &l_tokens_hold_size); l_tokens_hold_value_str = dap_config_get_array_str(a_chain_cfg, "block-pos", "stake_tokens_value", &l_tokens_hold_value_size); @@ -105,8 +111,15 @@ static int s_callback_new(dap_chain_t *a_chain, dap_config_t *a_chain_cfg) l_pos_pvt->confirmations_minimum = dap_config_get_item_uint16_default(a_chain_cfg, "block-pos", "verifications_minimum", 1); l_pos_pvt->tokens_hold_size = l_tokens_hold_size; l_pos_pvt->tokens_hold = DAP_NEW_Z_SIZE(char *, sizeof(char *) * l_tokens_hold_size); + if (!l_pos_pvt->tokens_hold) { + log_it(L_ERROR, "Memory allocation error in s_callback_new"); + goto lb_err; + } l_pos_pvt->tokens_hold_value = DAP_NEW_Z_SIZE(uint64_t, l_tokens_hold_value_size * sizeof(uint64_t)); - + if (!l_pos_pvt->tokens_hold_value) { + log_it(L_ERROR, "Memory allocation error in s_callback_new"); + goto lb_err; + } for (size_t i = 0; i < l_tokens_hold_value_size; i++) { l_pos_pvt->tokens_hold[i] = dap_strdup(l_tokens_hold[i]); if ((l_pos_pvt->tokens_hold_value[i] = @@ -122,17 +135,22 @@ static int s_callback_new(dap_chain_t *a_chain, dap_config_t *a_chain_cfg) return 0; lb_err: - for (int i = 0; i < l_tokens_hold_size; i++) - DAP_DELETE(l_tokens_hold[i]); - DAP_DELETE(l_tokens_hold); - DAP_DELETE(l_pos_pvt->tokens_hold_value); - DAP_DELETE(l_pos_pvt); - DAP_DELETE(l_pos ); + for (int i = 0; i < l_tokens_hold_size; i++) { + if (l_tokens_hold[i]) + DAP_DELETE(l_tokens_hold[i]); + } + if (l_tokens_hold) + DAP_DELETE(l_tokens_hold); + if (l_pos_pvt->tokens_hold_value) + DAP_DELETE(l_pos_pvt->tokens_hold_value); + if (l_pos_pvt) + DAP_DELETE(l_pos_pvt); + if (l_pos) + DAP_DELETE(l_pos); l_blocks->_inheritor = NULL; l_blocks->callback_delete = NULL; l_blocks->callback_block_verify = NULL; return -1; - } /** diff --git a/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c b/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c index ab297ae76f82a9a9ef9a8d66d95a043c4935167e..28876785406260cf4600542ae481ce8a54e05315 100644 --- a/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c +++ b/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c @@ -157,6 +157,10 @@ void dap_chain_cs_dag_poa_presign_callback_set(dap_chain_t *a_chain, dap_chain_c dap_chain_cs_dag_poa_pvt_t * l_poa_pvt = PVT(DAP_CHAIN_CS_DAG_POA(l_dag)); l_poa_pvt->callback_pre_sign = (dap_chain_cs_dag_poa_presign_callback_t*)DAP_NEW_Z(dap_chain_cs_dag_poa_presign_callback_t); + if (!l_poa_pvt->callback_pre_sign) { + log_it(L_ERROR, "Memory allocation error in dap_chain_cs_dag_poa_presign_callback_set"); + return; + } l_poa_pvt->callback_pre_sign->callback = a_callback; l_poa_pvt->callback_pre_sign->arg = a_arg; } @@ -332,12 +336,20 @@ static int s_callback_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg) dap_chain_cs_dag_new(a_chain,a_chain_cfg); dap_chain_cs_dag_t *l_dag = DAP_CHAIN_CS_DAG ( a_chain ); dap_chain_cs_dag_poa_t *l_poa = DAP_NEW_Z ( dap_chain_cs_dag_poa_t); + if (!l_poa) { + log_it(L_ERROR, "Memory allocation error in s_callback_new"); + return -1; + } l_dag->_inheritor = l_poa; l_dag->callback_delete = s_callback_delete; l_dag->callback_cs_verify = s_callback_event_verify; l_dag->callback_cs_event_create = s_callback_event_create; l_dag->chain->callback_get_poa_certs = dap_chain_cs_dag_poa_get_auth_certs; l_poa->_pvt = DAP_NEW_Z ( dap_chain_cs_dag_poa_pvt_t ); + if (!l_poa->_pvt) { + log_it(L_ERROR, "Memory allocation error in s_callback_new"); + return -1; + } dap_chain_cs_dag_poa_pvt_t *l_poa_pvt = PVT(l_poa); pthread_rwlock_init(&l_poa_pvt->rounds_rwlock, NULL); // PoA rounds @@ -351,6 +363,10 @@ static int s_callback_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg) l_poa_pvt->auth_certs_count_verify = dap_config_get_item_uint16_default(a_chain_cfg,"dag-poa","auth_certs_number_verify",0); if (l_poa_pvt->auth_certs_count && l_poa_pvt->auth_certs_count_verify) { l_poa_pvt->auth_certs = DAP_NEW_Z_SIZE ( dap_cert_t *, l_poa_pvt->auth_certs_count * sizeof(dap_cert_t *)); + if (!l_poa_pvt->auth_certs) { + log_it(L_ERROR, "Memory allocation error in s_callback_new"); + return -1; + } char l_cert_name[512]; for (size_t i = 0; i < l_poa_pvt->auth_certs_count ; i++ ){ snprintf(l_cert_name,sizeof(l_cert_name),"%s.%zu",l_poa_pvt->auth_certs_prefix, i); @@ -591,10 +607,8 @@ static void s_callback_round_event_to_chain_callback_get_round_item(dap_global_d DAP_DELETE(l_new_atom); char l_datum_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; dap_chain_hash_fast_to_str(&l_chosen_item->round_info.datum_hash, l_datum_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE); - char *l_err_verify_str = dap_chain_net_verify_datum_err_code_to_str(l_datum, l_verify_datum); log_it(L_INFO, "Event %s from round %"DAP_UINT64_FORMAT_U" not added into chain, because the inner datum %s doesn't pass verification (%s)", - l_event_hash_hex_str, l_arg->round_id, l_datum_hash_str, l_err_verify_str); - DAP_DELETE(l_err_verify_str); + l_event_hash_hex_str, l_arg->round_id, l_datum_hash_str, dap_chain_net_verify_datum_err_code_to_str(l_datum, l_verify_datum)); } } else { /* !l_chosen_item */ log_it(L_WARNING, "No candidates for round id %"DAP_UINT64_FORMAT_U, l_arg->round_id); @@ -628,6 +642,11 @@ static void s_round_event_cs_done(dap_chain_cs_dag_t * a_dag, uint64_t a_round_i return; } l_callback_arg = DAP_NEW_Z(struct round_timer_arg); + if (!l_callback_arg) { + log_it(L_ERROR, "Memory allocation error in s_round_event_cs_done"); + pthread_rwlock_unlock(&l_poa_pvt->rounds_rwlock); + return; + } l_callback_arg->dag = a_dag; l_callback_arg->round_id = a_round_id; // placement in chain by timer @@ -865,11 +884,16 @@ static int s_callback_event_verify(dap_chain_cs_dag_t * a_dag, dap_chain_cs_dag_ } a_event->header.signs_count = l_event_signs_count; DAP_DELETE(l_signs); - if ( l_ret != 0 ) { - return l_ret; + if (l_signs_verified_count < l_certs_count_verify) { + dap_hash_fast_t l_event_hash; + dap_hash_fast(a_event, a_event_size, &l_event_hash); + char l_event_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; + dap_hash_fast_to_str(&l_event_hash, l_event_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE); + log_it(L_ERROR, "Corrupted event %s, not enough signs %hu from %hu", + l_event_hash_str, l_signs_verified_count, l_certs_count_verify); + return l_ret ? l_ret : -4; } - return l_signs_verified_count >= l_certs_count_verify ? 0 : -1; - + return 0; } else if (a_event->header.hash_count == 0){ dap_chain_hash_fast_t l_event_hash; diff --git a/modules/consensus/dag-pos/dap_chain_cs_dag_pos.c b/modules/consensus/dag-pos/dap_chain_cs_dag_pos.c index 75aa18e310d09be01ad7db6cd55b24cd9cb8e6a6..ec07f04253620f6b00e927ba0e39b771dbeba53d 100644 --- a/modules/consensus/dag-pos/dap_chain_cs_dag_pos.c +++ b/modules/consensus/dag-pos/dap_chain_cs_dag_pos.c @@ -81,13 +81,11 @@ static int s_callback_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg) { dap_chain_cs_dag_new(a_chain,a_chain_cfg); dap_chain_cs_dag_t * l_dag = DAP_CHAIN_CS_DAG ( a_chain ); - dap_chain_cs_dag_pos_t * l_pos = DAP_NEW_Z ( dap_chain_cs_dag_pos_t); - l_dag->_inheritor = l_pos; - l_dag->callback_delete = s_callback_delete; - l_dag->callback_cs_verify = s_callback_event_verify; - l_dag->callback_cs_event_create = s_callback_event_create; - l_pos->_pvt = DAP_NEW_Z ( dap_chain_cs_dag_pos_pvt_t ); - + dap_chain_cs_dag_pos_t *l_pos = DAP_NEW_Z( dap_chain_cs_dag_pos_t); + if (!l_pos) { + log_it(L_ERROR, "Memory allocation error in s_callback_new"); + return -1; + } dap_chain_cs_dag_pos_pvt_t * l_pos_pvt = PVT ( l_pos ); char ** l_tokens_hold = NULL; @@ -95,21 +93,37 @@ static int s_callback_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg) uint16_t l_tokens_hold_size = 0; uint16_t l_tokens_hold_value_size = 0; + l_dag->_inheritor = l_pos; + l_dag->callback_delete = s_callback_delete; + l_dag->callback_cs_verify = s_callback_event_verify; + l_dag->callback_cs_event_create = s_callback_event_create; + l_pos->_pvt = DAP_NEW_Z ( dap_chain_cs_dag_pos_pvt_t ); + if (!l_pos->_pvt) { + log_it(L_ERROR, "Memory allocation error in s_callback_new"); + goto lb_err; + } + l_tokens_hold = dap_config_get_array_str( a_chain_cfg,"dag-pos","tokens_hold",&l_tokens_hold_size); l_tokens_hold_value_str = dap_config_get_array_str( a_chain_cfg,"dag-pos","tokens_hold_value",&l_tokens_hold_value_size); if ( l_tokens_hold_size != l_tokens_hold_value_size ){ - log_it(L_CRITICAL, "tokens_hold and tokens_hold_value are different size!"); + log_it(L_CRITICAL, "Entries tokens_hold and tokens_hold_value are different size!"); goto lb_err; } l_pos_pvt->confirmations_minimum = dap_config_get_item_uint16_default( a_chain_cfg,"dag-pos","confirmations_minimum",1); l_pos_pvt->tokens_hold_size = l_tokens_hold_size; l_pos_pvt->tokens_hold = DAP_NEW_Z_SIZE( char*, sizeof(char*) * l_tokens_hold_size ); - + if (!l_pos_pvt->tokens_hold) { + log_it(L_ERROR, "Memory allocation error in s_callback_new"); + goto lb_err; + } l_pos_pvt->tokens_hold_value = DAP_NEW_Z_SIZE(uint64_t, (l_tokens_hold_value_size +1) *sizeof (uint64_t)); - + if (!l_pos_pvt->tokens_hold_value) { + log_it(L_ERROR, "Memory allocation error in s_callback_new"); + goto lb_err; + } for (size_t i = 0; i < l_tokens_hold_value_size; i++){ l_pos_pvt->tokens_hold[i] = dap_strdup( l_tokens_hold[i] ); if ( ( l_pos_pvt->tokens_hold_value[i] = @@ -123,12 +137,18 @@ static int s_callback_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg) return 0; lb_err: - for (int i = 0; i < l_tokens_hold_size; i++ ) - DAP_DELETE(l_tokens_hold[i]); - DAP_DELETE(l_tokens_hold); - DAP_DELETE( l_pos_pvt->tokens_hold_value); - DAP_DELETE( l_pos_pvt); - DAP_DELETE(l_pos ); + for (int i = 0; i < l_tokens_hold_size; i++) { + if (l_tokens_hold[i]) + DAP_DELETE(l_tokens_hold[i]); + } + if (l_tokens_hold) + DAP_DELETE(l_tokens_hold); + if (l_pos_pvt->tokens_hold_value) + DAP_DELETE(l_pos_pvt->tokens_hold_value); + if (l_pos_pvt) + DAP_DELETE(l_pos_pvt); + if (l_pos) + DAP_DELETE(l_pos); l_dag->_inheritor = NULL; l_dag->callback_delete = NULL; l_dag->callback_cs_verify = NULL; diff --git a/modules/consensus/esbocs/dap_chain_cs_esbocs.c b/modules/consensus/esbocs/dap_chain_cs_esbocs.c index f9471f2ab185ec72cd31ce275c90de9de71448b1..7633b717a47172897fd426747571bb78d7d12ec5 100644 --- a/modules/consensus/esbocs/dap_chain_cs_esbocs.c +++ b/modules/consensus/esbocs/dap_chain_cs_esbocs.c @@ -61,6 +61,7 @@ static int s_callback_block_verify(dap_chain_cs_blocks_t *a_blocks, dap_chain_bl static uint256_t s_callback_get_minimum_fee(dap_chain_t *a_chain); static dap_enc_key_t *s_callback_get_sign_key(dap_chain_t *a_chain); static void s_callback_set_min_validators_count(dap_chain_t *a_chain, uint16_t a_new_value); +static void s_db_change_notifier(dap_global_db_context_t *a_context, dap_store_obj_t *a_obj, void * a_arg); static int s_cli_esbocs(int argc, char ** argv, char **str_reply); @@ -76,6 +77,7 @@ DAP_STATIC_INLINE const char *s_voting_msg_type_to_str(uint8_t a_type) case DAP_CHAIN_ESBOCS_MSG_TYPE_DIRECTIVE: return "DIRECTIVE"; case DAP_CHAIN_ESBOCS_MSG_TYPE_VOTE_FOR: return "VOTE_FOR"; case DAP_CHAIN_ESBOCS_MSG_TYPE_VOTE_AGAINST: return "VOTE_AGAINST"; + case DAP_CHAIN_ESBOCS_MSG_TYPE_SEND_DB: return "SEND_DB"; default: return "UNKNOWN"; } } @@ -131,6 +133,16 @@ typedef struct dap_chain_esbocs_pvt { #define PVT(a) ((dap_chain_esbocs_pvt_t *)a->_pvt) +struct sync_params { + uint64_t attempt; + dap_hash_fast_t db_hash; +} DAP_ALIGN_PACKED; + +DAP_STATIC_INLINE uint16_t s_get_round_skip_timeout(dap_chain_esbocs_session_t *a_session) +{ + return PVT(a_session->esbocs)->round_attempt_timeout * 6 * PVT(a_session->esbocs)->round_attempts_max; +} + int dap_chain_cs_esbocs_init() { dap_stream_ch_chain_voting_init(); @@ -152,7 +164,12 @@ static int s_callback_new(dap_chain_t *a_chain, dap_config_t *a_chain_cfg) dap_chain_cs_blocks_new(a_chain, a_chain_cfg); dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain); + int l_ret = 0; dap_chain_esbocs_t *l_esbocs = DAP_NEW_Z(dap_chain_esbocs_t); + if (!l_esbocs) { + log_it(L_ERROR, "Memory allocation error in s_callback_new"); + return - 5; + } l_esbocs->blocks = l_blocks; l_blocks->_inheritor = l_esbocs; l_blocks->callback_delete = s_callback_delete; @@ -166,6 +183,11 @@ static int s_callback_new(dap_chain_t *a_chain, dap_config_t *a_chain_cfg) l_esbocs->_pvt = DAP_NEW_Z(dap_chain_esbocs_pvt_t); dap_chain_esbocs_pvt_t *l_esbocs_pvt = PVT(l_esbocs); + if (!l_esbocs->_pvt) { + log_it(L_ERROR, "Memory allocation error in s_callback_new"); + l_ret = - 5; + goto lb_err; + } l_esbocs_pvt->debug = dap_config_get_item_bool_default(a_chain_cfg, "esbocs", "consensus_debug", false); l_esbocs_pvt->poa_mode = dap_config_get_item_bool_default(a_chain_cfg, "esbocs", "poa_mode", false); l_esbocs_pvt->round_start_sync_timeout = dap_config_get_item_uint16_default(a_chain_cfg, "esbocs", "round_start_sync_timeout", 15); @@ -173,7 +195,6 @@ static int s_callback_new(dap_chain_t *a_chain, dap_config_t *a_chain_cfg) l_esbocs_pvt->round_attempts_max = dap_config_get_item_uint16_default(a_chain_cfg, "esbocs", "round_attempts_max", 4); l_esbocs_pvt->round_attempt_timeout = dap_config_get_item_uint16_default(a_chain_cfg, "esbocs", "round_attempt_timeout", 10); - int l_ret = 0; l_esbocs_pvt->start_validators_min = l_esbocs_pvt->min_validators_count = dap_config_get_item_uint16(a_chain_cfg, "esbocs", "min_validators_count"); if (!l_esbocs_pvt->min_validators_count) { @@ -210,9 +231,16 @@ static int s_callback_new(dap_chain_t *a_chain, dap_config_t *a_chain_cfg) l_ret = -4; goto lb_err; } - log_it(L_MSG, "add validator addr:"NODE_ADDR_FP_STR"", NODE_ADDR_FP_ARGS_S(l_signer_node_addr)); + char *l_signer_addr = dap_chain_addr_to_str(&l_signing_addr); + log_it(L_MSG, "add validator addr "NODE_ADDR_FP_STR", signing addr %s", NODE_ADDR_FP_ARGS_S(l_signer_node_addr), l_signer_addr); + DAP_DELETE(l_signer_addr); dap_chain_esbocs_validator_t *l_validator = DAP_NEW_Z(dap_chain_esbocs_validator_t); + if (!l_validator) { + log_it(L_ERROR, "Memory allocation error in s_callback_new"); + l_ret = - 5; + goto lb_err; + } l_validator->signing_addr = l_signing_addr; l_validator->node_addr = l_signer_node_addr; l_validator->weight = uint256_1; @@ -227,12 +255,15 @@ static int s_callback_new(dap_chain_t *a_chain, dap_config_t *a_chain_cfg) } } l_blocks->chain->callback_created = s_callback_created; + return 0; lb_err: dap_list_free_full(l_esbocs_pvt->poa_validators, NULL); - DAP_DELETE(l_esbocs_pvt); - DAP_DELETE(l_esbocs); + if (l_esbocs_pvt) + DAP_DELETE(l_esbocs_pvt); + if (l_esbocs) + DAP_DELETE(l_esbocs); l_blocks->_inheritor = NULL; l_blocks->callback_delete = NULL; l_blocks->callback_block_verify = NULL; @@ -251,6 +282,67 @@ static void s_new_atom_notifier(void *a_arg, UNUSED_ARG dap_chain_t *a_chain, UN pthread_mutex_unlock(&l_session->mutex); } +/* *** Temporary added section for over-consensus sync. Remove this after global DB sync refactoring *** */ + +void s_callback_clean_db_old_records(UNUSED_ARG dap_global_db_context_t *a_global_db_context, void *a_arg) +{ + dap_global_db_driver_delete(a_arg, 1); + dap_store_obj_free_one(a_arg); +} + +static void s_session_db_serialize(dap_chain_esbocs_session_t *a_session) +{ + char *l_sync_group = s_get_penalty_group(a_session->chain->net_id); + size_t l_objs_count = 0; + dap_global_db_pkt_t *l_pkt = 0; + dap_store_obj_t *l_objs = dap_global_db_get_all_raw_sync(l_sync_group, 0, &l_objs_count); + for (size_t i = 0; i < l_objs_count; i++) { + dap_store_obj_t *it = l_objs + i; + it->type = DAP_DB$K_OPTYPE_ADD; + dap_global_db_pkt_t *l_pkt_single = dap_global_db_pkt_serialize(it); + dap_global_db_pkt_change_id(l_pkt_single, 0); + l_pkt = dap_global_db_pkt_pack(l_pkt, l_pkt_single); + DAP_DELETE(l_pkt_single); + } + dap_store_obj_free(l_objs, l_objs_count); + + uint32_t l_time_store_lim_hours = dap_global_db_context_get_default()->instance->store_time_limit; + uint64_t l_limit_time = l_time_store_lim_hours ? dap_nanotime_now() - dap_nanotime_from_sec(l_time_store_lim_hours * 3600) : 0; + char *l_del_sync_group = dap_strdup_printf("%s.del", l_sync_group); + l_objs_count = 0; + l_objs = dap_global_db_get_all_raw_sync(l_del_sync_group, 0, &l_objs_count); + DAP_DELETE(l_del_sync_group); + for (size_t i = 0; i < l_objs_count; i++) { + dap_store_obj_t *it = l_objs + i; + if (l_limit_time && it->timestamp < l_limit_time) { + dap_global_db_context_exec(s_callback_clean_db_old_records, dap_store_obj_copy(it, 1)); + continue; + } + it->type = DAP_DB$K_OPTYPE_DEL; + DAP_DEL_Z(it->group); + it->group = dap_strdup(l_sync_group); + dap_global_db_pkt_t *l_pkt_single = dap_global_db_pkt_serialize(it); + dap_global_db_pkt_change_id(l_pkt_single, 0); + l_pkt = dap_global_db_pkt_pack(l_pkt, l_pkt_single); + DAP_DELETE(l_pkt_single); + } + dap_store_obj_free(l_objs, l_objs_count); + DAP_DELETE(l_sync_group); + DAP_DEL_Z(a_session->db_serial); + a_session->db_serial = l_pkt; + if (l_pkt) + dap_hash_fast(l_pkt->data, l_pkt->data_size, &a_session->db_hash); + else + a_session->db_hash = (dap_hash_fast_t){}; + if (PVT(a_session->esbocs)->debug) { + char l_sync_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; + dap_chain_hash_fast_to_str(&a_session->db_hash, l_sync_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE); + log_it(L_MSG, "DB changes applied, new DB resync hash is %s", l_sync_hash_str); + } +} + +/* *** End of the temporary added section for over-consensus sync. *** */ + static void s_session_load_penaltys(dap_chain_esbocs_session_t *a_session) { const char *l_penalty_group = s_get_penalty_group(a_session->chain->net_id); @@ -358,6 +450,10 @@ static int s_callback_created(dap_chain_t *a_chain, dap_config_t *a_chain_net_cf l_session->my_addr.uint64 = dap_chain_net_get_cur_addr_int(l_net); l_session->my_signing_addr = l_my_signing_addr; s_session_load_penaltys(l_session); + s_session_db_serialize(l_session); + dap_global_db_add_notify_group_mask(dap_global_db_context_get_default()->instance, + DAP_CHAIN_ESBOCS_GDB_GROUPS_PREFIX ".*", + s_db_change_notifier, l_session); pthread_mutexattr_t l_mutex_attr; pthread_mutexattr_init(&l_mutex_attr); pthread_mutexattr_settype(&l_mutex_attr, PTHREAD_MUTEX_RECURSIVE); @@ -367,7 +463,7 @@ static int s_callback_created(dap_chain_t *a_chain, dap_config_t *a_chain_net_cf dap_chain_add_callback_notify(a_chain, s_new_atom_notifier, l_session); s_session_round_new(l_session); - log_it(L_INFO, "init session for net:%s, chain:%s", a_chain->net_name, a_chain->name); + log_it(L_INFO, "Init session for net:%s, chain:%s", a_chain->net_name, a_chain->name); DL_APPEND(s_session_items, l_session); if (!s_session_cs_timer) { s_session_cs_timer = dap_timerfd_start(1000, s_session_timer, NULL); @@ -429,6 +525,10 @@ static void *s_callback_list_copy(const void *a_validator, UNUSED_ARG void *a_da static void *s_callback_list_form(const void *a_srv_validator, UNUSED_ARG void *a_data) { dap_chain_esbocs_validator_t *l_validator = DAP_NEW_Z(dap_chain_esbocs_validator_t); + if (!l_validator) { + log_it(L_ERROR, "Memory allocation error in s_callback_list_form"); + return NULL; + } l_validator->node_addr = ((dap_chain_net_srv_stake_item_t *)a_srv_validator)->node_addr; l_validator->signing_addr = ((dap_chain_net_srv_stake_item_t *)a_srv_validator)->signing_addr; l_validator->weight = ((dap_chain_net_srv_stake_item_t *)a_srv_validator)->value; @@ -462,10 +562,12 @@ static dap_list_t *s_get_validators_list(dap_chain_esbocs_session_t *a_session, if (!l_esbocs_pvt->poa_mode) { dap_list_t *l_validators = dap_chain_net_srv_stake_get_validators(a_session->chain->net_id, true); + a_session->cur_round.all_validators = dap_list_copy_deep(l_validators, s_callback_list_form, NULL); uint16_t l_total_validators_count = dap_list_length(l_validators); if (l_total_validators_count < l_esbocs_pvt->min_validators_count) { + l_ret = dap_list_copy_deep(l_esbocs_pvt->poa_validators, s_callback_list_copy, NULL); dap_list_free_full(l_validators, NULL); - return NULL; + return l_ret; } // TODO: make dap_chain_net_srv_stake_get_total_weight() call @@ -480,8 +582,6 @@ static dap_list_t *s_get_validators_list(dap_chain_esbocs_session_t *a_session, } } - a_session->cur_round.all_validators = dap_list_copy_deep(l_validators, s_callback_list_form, NULL); - size_t l_consensus_optimum = (size_t)l_esbocs_pvt->min_validators_count * 2 - 1; size_t l_need_vld_cnt = MIN(l_total_validators_count, l_consensus_optimum); @@ -579,18 +679,21 @@ static void s_session_send_startsync(dap_chain_esbocs_session_t *a_session) dap_string_append_printf(l_addr_list, NODE_ADDR_FP_STR"; ", NODE_ADDR_FP_ARGS_S(((dap_chain_esbocs_validator_t *)it->data)->node_addr)); } + char *l_sync_hash = dap_chain_hash_fast_to_str_new(&a_session->db_hash); log_it(L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U"." - " Sent START_SYNC pkt, sync attempt %"DAP_UINT64_FORMAT_U" current validators list: %s", + " Sent START_SYNC pkt, sync attempt %"DAP_UINT64_FORMAT_U" current validators list: %s DB sync hash %s", a_session->chain->net_name, a_session->chain->name, a_session->cur_round.id, - a_session->cur_round.sync_attempt, l_addr_list->str); + a_session->cur_round.sync_attempt, l_addr_list->str, l_sync_hash); dap_string_free(l_addr_list, true); + DAP_DELETE(l_sync_hash); } dap_list_t *l_inactive_validators = dap_chain_net_srv_stake_get_validators(a_session->chain->net_id, false); dap_list_t *l_inactive_sendlist = dap_list_copy_deep(l_inactive_validators, s_callback_list_form, NULL); dap_list_free_full(l_inactive_validators, NULL); dap_list_t *l_total_sendlist = dap_list_concat(a_session->cur_round.all_validators, l_inactive_sendlist); + struct sync_params l_params = { .attempt = a_session->cur_round.sync_attempt, .db_hash = a_session->db_hash }; s_message_send(a_session, DAP_CHAIN_ESBOCS_MSG_TYPE_START_SYNC, &l_last_block_hash, - &a_session->cur_round.sync_attempt, sizeof(uint64_t), + &l_params, sizeof(struct sync_params), l_total_sendlist); if (l_inactive_sendlist && l_inactive_sendlist->prev) { // List splitting l_inactive_sendlist->prev->next = NULL; @@ -688,41 +791,51 @@ static void s_session_round_new(dap_chain_esbocs_session_t *a_session) a_session->cur_round.sync_attempt = 1; } a_session->cur_round.validators_list = s_get_validators_list(a_session, a_session->cur_round.sync_attempt - 1); + if (!a_session->cur_round.validators_list) { + log_it(L_WARNING, "Totally no active validators found"); + a_session->ts_round_sync_start = dap_time_now(); + return; + } bool l_round_already_started = a_session->round_fast_forward; - if (s_validator_check(&a_session->my_signing_addr, a_session->cur_round.validators_list)) { - //I am a current round validator - dap_chain_esbocs_sync_item_t *l_item, *l_tmp; - HASH_FIND(hh, a_session->sync_items, &a_session->cur_round.last_block_hash, sizeof(dap_hash_fast_t), l_item); - if (l_item) { - debug_if(PVT(a_session->esbocs)->debug, - L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U" already started. Process sync messages", - a_session->chain->net_name, a_session->chain->name, a_session->cur_round.id); - l_round_already_started = true; - for (dap_list_t *it = l_item->messages; it; it = it->next) { - dap_hash_fast_t l_msg_hash; - dap_chain_esbocs_message_t *l_msg = it->data; - size_t l_msg_size = s_get_esbocs_message_size(l_msg); - dap_hash_fast(l_msg, l_msg_size, &l_msg_hash); - s_session_packet_in(a_session, NULL, NULL, &l_msg_hash, (uint8_t *)l_msg, l_msg_size); - } - } - HASH_ITER(hh, a_session->sync_items, l_item, l_tmp) { - HASH_DEL(a_session->sync_items, l_item); - dap_list_free_full(l_item->messages, NULL); - DAP_DELETE(l_item); - } - + dap_chain_esbocs_sync_item_t *l_item, *l_tmp; + HASH_FIND(hh, a_session->sync_items, &a_session->cur_round.last_block_hash, sizeof(dap_hash_fast_t), l_item); + if (l_item) { + debug_if(PVT(a_session->esbocs)->debug, + L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U" already started. Process sync messages", + a_session->chain->net_name, a_session->chain->name, a_session->cur_round.id); + l_round_already_started = true; + for (dap_list_t *it = l_item->messages; it; it = it->next) { + dap_hash_fast_t l_msg_hash; + dap_chain_esbocs_message_t *l_msg = it->data; + size_t l_msg_size = s_get_esbocs_message_size(l_msg); + dap_hash_fast(l_msg, l_msg_size, &l_msg_hash); + s_session_packet_in(a_session, NULL, NULL, &l_msg_hash, (uint8_t *)l_msg, l_msg_size); + } + } + HASH_ITER(hh, a_session->sync_items, l_item, l_tmp) { + HASH_DEL(a_session->sync_items, l_item); + dap_list_free_full(l_item->messages, NULL); + DAP_DELETE(l_item); + } + + if (!a_session->cur_round.sync_sent) { + uint16_t l_sync_send_delay = a_session->sync_failed ? + s_get_round_skip_timeout(a_session) : + PVT(a_session->esbocs)->new_round_delay; + if (l_round_already_started) + l_sync_send_delay = 0; debug_if(PVT(a_session->esbocs)->debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U" start. Syncing validators in %u seconds", a_session->chain->net_name, a_session->chain->name, - a_session->cur_round.id, l_round_already_started ? 0 : PVT(a_session->esbocs)->new_round_delay); + a_session->cur_round.id, l_sync_send_delay); + if (l_sync_send_delay) + a_session->sync_timer = dap_timerfd_start(l_sync_send_delay * 1000, s_session_send_startsync_on_timer, a_session); + else + s_session_send_startsync(a_session); } - if (PVT(a_session->esbocs)->new_round_delay && !l_round_already_started && !a_session->cur_round.sync_sent) - a_session->sync_timer = dap_timerfd_start(PVT(a_session->esbocs)->new_round_delay * 1000, - s_session_send_startsync_on_timer, a_session); - else - s_session_send_startsync(a_session); a_session->round_fast_forward = false; + a_session->sync_failed = false; + a_session->listen_ensure = 0; } static void s_session_attempt_new(dap_chain_esbocs_session_t *a_session) @@ -976,17 +1089,14 @@ static void s_session_proc_state(dap_chain_esbocs_session_t *a_session) { if (pthread_mutex_trylock(&a_session->mutex) != 0) return; // Session is busy - static unsigned int l_listen_ensure; bool l_cs_debug = PVT(a_session->esbocs)->debug; dap_time_t l_time = dap_time_now(); switch (a_session->state) { case DAP_CHAIN_ESBOCS_SESSION_STATE_WAIT_START: { - l_listen_ensure = 1; - dap_time_t l_round_timeout = PVT(a_session->esbocs)->round_start_sync_timeout; + a_session->listen_ensure = 1; bool l_round_skip = !s_validator_check(&a_session->my_signing_addr, a_session->cur_round.validators_list); - if (l_round_skip) - l_round_timeout += PVT(a_session->esbocs)->round_attempt_timeout * 6 * PVT(a_session->esbocs)->round_attempts_max; - if (a_session->ts_round_sync_start && l_time - a_session->ts_round_sync_start >= l_round_timeout) { + if (a_session->ts_round_sync_start && l_time - a_session->ts_round_sync_start >= + PVT(a_session->esbocs)->round_start_sync_timeout) { if (a_session->cur_round.validators_synced_count >= PVT(a_session->esbocs)->min_validators_count && !l_round_skip) { a_session->cur_round.id = s_session_calc_current_round_id(a_session); debug_if(l_cs_debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu." @@ -1000,13 +1110,14 @@ static void s_session_proc_state(dap_chain_esbocs_session_t *a_session) a_session->chain->net_name, a_session->chain->name, a_session->cur_round.id, a_session->cur_round.attempt_num, l_round_skip ? "skipped" : "can't synchronize minimum number of validators"); + a_session->sync_failed = true; s_session_round_new(a_session); } } } break; case DAP_CHAIN_ESBOCS_SESSION_STATE_WAIT_PROC: - if (l_time - a_session->ts_stage_entry >= PVT(a_session->esbocs)->round_attempt_timeout * l_listen_ensure) { - l_listen_ensure += 2; + if (l_time - a_session->ts_stage_entry >= PVT(a_session->esbocs)->round_attempt_timeout * a_session->listen_ensure) { + a_session->listen_ensure += 2; debug_if(l_cs_debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu." " Attempt finished by reason: haven't cantidate submitted", a_session->chain->net_name, a_session->chain->name, @@ -1015,7 +1126,6 @@ static void s_session_proc_state(dap_chain_esbocs_session_t *a_session) } break; case DAP_CHAIN_ESBOCS_SESSION_STATE_WAIT_SIGNS: - l_listen_ensure = 1; if (l_time - a_session->ts_stage_entry >= PVT(a_session->esbocs)->round_attempt_timeout) { dap_chain_esbocs_store_t *l_store; HASH_FIND(hh, a_session->cur_round.store_items, &a_session->cur_round.attempt_candidate_hash, sizeof(dap_hash_fast_t), l_store); @@ -1087,8 +1197,16 @@ static void s_message_chain_add(dap_chain_esbocs_session_t *a_session, dap_chain_hash_fast_t *a_message_hash, dap_chain_addr_t *a_signing_addr) { + if (NULL == a_message) { + log_it(L_ERROR, "Argument is NULL for s_message_chain_add"); + return; + } dap_chain_esbocs_round_t *l_round = &a_session->cur_round; dap_chain_esbocs_message_item_t *l_message_item = DAP_NEW_Z(dap_chain_esbocs_message_item_t); + if (!l_message_item) { + log_it(L_ERROR, "Memory allocation error in s_message_chain_add"); + return; + } if (!a_message_hash) { dap_chain_hash_fast_t l_message_hash; dap_hash_fast(a_message, a_message_size, &l_message_hash); @@ -1134,6 +1252,10 @@ static void s_session_candidate_submit(dap_chain_esbocs_session_t *a_session) static void s_session_candidate_verify(dap_chain_esbocs_session_t *a_session, dap_chain_block_t *a_candidate, size_t a_candidate_size, dap_hash_fast_t *a_candidate_hash) { + if (NULL == a_candidate) { + log_it(L_ERROR, "Argument is NULL for s_session_candidate_verify"); + return; + } // Process early received messages for (dap_chain_esbocs_message_item_t *l_item = a_session->cur_round.message_items; l_item; l_item = l_item->hh.next) { if (l_item->unprocessed && @@ -1177,6 +1299,10 @@ static void s_session_candidate_verify(dap_chain_esbocs_session_t *a_session, da static void s_session_candidate_precommit(dap_chain_esbocs_session_t *a_session, dap_chain_esbocs_message_t *a_message) { + if (NULL == a_message) { + log_it(L_ERROR, "Argument is NULL for s_session_candidate_precommit"); + return; + } bool l_cs_debug = PVT(a_session->esbocs)->debug; uint16_t l_cs_level = PVT(a_session->esbocs)->min_validators_count; byte_t *l_message_data = a_message->msg_n_sign; @@ -1240,6 +1366,10 @@ static void s_session_candidate_precommit(dap_chain_esbocs_session_t *a_session, static bool s_session_candidate_to_chain(dap_chain_esbocs_session_t *a_session, dap_chain_hash_fast_t *a_candidate_hash, dap_chain_block_t *a_candidate, size_t a_candidate_size) { + if (NULL == a_candidate) { + log_it(L_ERROR, "Argument is NULL for s_session_candidate_to_chain"); + return false; + } bool res = false; dap_chain_block_t *l_candidate = DAP_DUP_SIZE(a_candidate, a_candidate_size); dap_chain_atom_verify_res_t l_res = a_session->chain->callback_atom_add(a_session->chain, l_candidate, a_candidate_size); @@ -1435,7 +1565,15 @@ static void s_session_round_finish(dap_chain_esbocs_session_t *a_session, dap_ch l_compare && PVT(a_session->esbocs)->fee_addr) { fee_serv_param_t *tmp = DAP_NEW(fee_serv_param_t); + if (!tmp) { + log_it(L_ERROR, "Memory allocation error in s_session_round_finish"); + return; + } dap_chain_addr_t * addr = DAP_NEW_Z(dap_chain_addr_t); + if (!addr) { + log_it(L_ERROR, "Memory allocation error in s_session_round_finish"); + return; + } *addr = *PVT(a_session->esbocs)->fee_addr; tmp->a_addr_to = addr; tmp->block_hash = l_precommit_candidate_hash; @@ -1454,6 +1592,10 @@ void s_session_sync_queue_add(dap_chain_esbocs_session_t *a_session, dap_chain_e HASH_FIND(hh, a_session->sync_items, &a_message->hdr.candidate_hash, sizeof(dap_hash_fast_t), l_sync_item); if (!l_sync_item) { l_sync_item = DAP_NEW_Z(dap_chain_esbocs_sync_item_t); + if (!l_sync_item) { + log_it(L_ERROR, "Memory allocation error in s_session_sync_queue_add"); + return; + } l_sync_item->last_block_hash = a_message->hdr.candidate_hash; HASH_ADD(hh, a_session->sync_items, last_block_hash, sizeof(dap_hash_fast_t), l_sync_item); } @@ -1465,9 +1607,16 @@ void s_session_validator_mark_online(dap_chain_esbocs_session_t *a_session, dap_ bool l_in_list = false; dap_list_t *l_list = s_validator_check(a_signing_addr, a_session->cur_round.all_validators); if (l_list) { + bool l_was_synced = ((dap_chain_esbocs_validator_t *)l_list->data)->is_synced; ((dap_chain_esbocs_validator_t *)l_list->data)->is_synced = true; - a_session->cur_round.total_validators_synced++; + if (!l_was_synced) + a_session->cur_round.total_validators_synced++; l_in_list = true; + if (PVT(a_session->esbocs)->debug) { + const char *l_addr_str = dap_chain_addr_to_str(a_signing_addr); + log_it(L_DEBUG, "Mark validator %s as online", l_addr_str); + DAP_DELETE(l_addr_str); + } } dap_chain_esbocs_penalty_item_t *l_item = NULL; HASH_FIND(hh, a_session->penalty, a_signing_addr, sizeof(*a_signing_addr), l_item); @@ -1564,7 +1713,6 @@ static void s_session_directive_process(dap_chain_esbocs_session_t *a_session, d l_directive_hash_str); DAP_DELETE(l_directive_hash_str); } - a_session->cur_round.directive_hash = *a_directive_hash; a_session->cur_round.directive = DAP_DUP_SIZE(a_directive, a_directive->size); @@ -1586,6 +1734,28 @@ static void s_session_directive_process(dap_chain_esbocs_session_t *a_session, d s_message_send(a_session, l_type, a_directive_hash, NULL, 0, a_session->cur_round.all_validators); } +static void s_db_change_notifier(dap_global_db_context_t *a_context, dap_store_obj_t *a_obj, void *a_arg) +{ + dap_chain_addr_t *l_validator_addr = dap_chain_addr_from_str(a_obj->key); + if (!l_validator_addr) { + log_it(L_WARNING, "Unreadable address in esbocs global DB group"); + dap_global_db_del_unsafe(a_context, a_obj->group, a_obj->key); + return; + } + if (dap_chain_net_srv_stake_mark_validator_active(l_validator_addr, a_obj->type != DAP_DB$K_OPTYPE_ADD)) { + dap_global_db_del_unsafe(a_context, a_obj->group, a_obj->key); + return; + } + dap_chain_esbocs_session_t *l_session = a_arg; + dap_global_db_pkt_t *l_pkt = dap_global_db_pkt_serialize(a_obj); + dap_hash_fast_t l_blank_hash = {}; + pthread_mutex_lock(&l_session->mutex); + s_message_send(l_session, DAP_CHAIN_ESBOCS_MSG_TYPE_SEND_DB, &l_blank_hash, l_pkt, + sizeof(*l_pkt) + l_pkt->data_size, l_session->cur_round.all_validators); + pthread_mutex_unlock(&l_session->mutex); + DAP_DELETE(l_pkt); +} + static int s_session_directive_apply(dap_chain_esbocs_directive_t *a_directive, dap_hash_fast_t *a_directive_hash) { if (!a_directive) { @@ -1609,12 +1779,12 @@ static int s_session_directive_apply(dap_chain_esbocs_directive_t *a_directive, const char *l_directive_hash_str = dap_chain_hash_fast_to_str_new(a_directive_hash); const char *l_key_hash_str = dap_chain_hash_fast_to_str_new(&l_key_addr->data.hash_fast); if (l_status == 1 && a_directive->type == DAP_CHAIN_ESBOCS_DIRECTIVE_KICK) { - dap_chain_net_srv_stake_mark_validator_active(l_key_addr, false); + // Offline wiil be set in gdb notifier for aim of sync supporting dap_global_db_set(l_penalty_group, l_key_str, NULL, 0, false, NULL, 0); log_it(L_MSG, "Applied %s directive to exclude validator %s with pkey hash %s from consensus", l_directive_hash_str, l_key_str, l_key_hash_str); } else if (l_status == -1 && a_directive->type == DAP_CHAIN_ESBOCS_DIRECTIVE_LIFT) { - dap_chain_net_srv_stake_mark_validator_active(l_key_addr, true); + // Online wiil be set in gdb notifier for aim of sync supporting dap_global_db_del(l_penalty_group, l_key_str, NULL, 0); log_it(L_MSG, "Applied %s directive to include validator %s with pkey hash %s in consensus", l_directive_hash_str, l_key_str, l_key_hash_str); @@ -1659,7 +1829,7 @@ static void s_session_packet_in(void *a_arg, dap_chain_node_addr_t *a_sender_nod } size_t l_message_data_size = l_message->hdr.message_size; - byte_t *l_message_data = l_message->msg_n_sign; + void *l_message_data = l_message->msg_n_sign; dap_chain_hash_fast_t *l_candidate_hash = &l_message->hdr.candidate_hash; dap_sign_t *l_sign = (dap_sign_t *)(l_message_data + l_message_data_size); size_t l_sign_size = l_message->hdr.sign_size; @@ -1726,6 +1896,15 @@ static void s_session_packet_in(void *a_arg, dap_chain_node_addr_t *a_sender_nod s_session_sync_queue_add(l_session, l_message, a_data_size); goto session_unlock; } + } else if (l_message->hdr.type == DAP_CHAIN_ESBOCS_MSG_TYPE_SEND_DB) { + if (dap_hash_fast_compare(&l_message->hdr.candidate_hash, &l_session->db_hash) && + !dap_hash_fast_is_blank(&l_session->db_hash)) { + debug_if(l_cs_debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U"." + " Send DB message with same DB hash is ignored", + l_session->chain->net_name, l_session->chain->name, + l_session->cur_round.id); + goto session_unlock; + } } else if (l_message->hdr.round_id != l_session->cur_round.id) { // round check debug_if(l_cs_debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu." @@ -1761,7 +1940,8 @@ static void s_session_packet_in(void *a_arg, dap_chain_node_addr_t *a_sender_nod if (l_same_type && dap_chain_addr_compare(&l_chain_message->signing_addr, &l_signing_addr) && dap_hash_fast_compare(&l_chain_message->message->hdr.candidate_hash, &l_message->hdr.candidate_hash)) { if (l_message->hdr.type != DAP_CHAIN_ESBOCS_MSG_TYPE_START_SYNC || // Not sync or same sync attempt - *(uint64_t *)l_message_data == *(uint64_t *)l_chain_message->message->msg_n_sign) { + ((struct sync_params *)l_message_data)->attempt == + ((struct sync_params *)l_chain_message->message->msg_n_sign)->attempt) { debug_if(l_cs_debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu." " Message rejected: duplicate message %s", l_session->chain->net_name, l_session->chain->name, @@ -1781,6 +1961,7 @@ static void s_session_packet_in(void *a_arg, dap_chain_node_addr_t *a_sender_nod bool l_not_in_list = false; switch (l_message->hdr.type) { case DAP_CHAIN_ESBOCS_MSG_TYPE_START_SYNC: + case DAP_CHAIN_ESBOCS_MSG_TYPE_SEND_DB: // Add local sync messages, cause a round clear if (!a_sender_node_addr) s_message_chain_add(l_session, l_message, a_data_size, a_data_hash, &l_signing_addr); @@ -1810,15 +1991,31 @@ static void s_session_packet_in(void *a_arg, dap_chain_node_addr_t *a_sender_nod switch (l_message->hdr.type) { case DAP_CHAIN_ESBOCS_MSG_TYPE_START_SYNC: { - if (l_message_data_size != sizeof(uint64_t)) { + if (l_message_data_size != sizeof(struct sync_params)) { log_it(L_WARNING, "Invalid START_SYNC message size"); break; } - uint64_t l_sync_attempt = *(uint64_t *)l_message_data; + uint64_t l_sync_attempt = ((struct sync_params *)l_message_data)->attempt; debug_if(l_cs_debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U " Receive START_SYNC: from validator:%s, sync attempt %"DAP_UINT64_FORMAT_U, l_session->chain->net_name, l_session->chain->name, l_message->hdr.round_id, l_validator_addr_str, l_sync_attempt); + if (!dap_hash_fast_compare(&((struct sync_params *)l_message_data)->db_hash, &l_session->db_hash)) { + debug_if(l_cs_debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", sync_attempt %"DAP_UINT64_FORMAT_U + " SYNC message is rejected cause DB hash mismatch", + l_session->chain->net_name, l_session->chain->name, l_session->cur_round.id, + l_session->cur_round.sync_attempt); + if (l_session->db_serial) { + dap_chain_esbocs_validator_t *l_validator = DAP_NEW_Z(dap_chain_esbocs_validator_t); + l_validator->node_addr = *dap_chain_net_srv_stake_key_get_node_addr(&l_signing_addr); + l_validator->signing_addr = l_signing_addr; + dap_list_t *l_validator_list = dap_list_append(NULL, l_validator); + s_message_send(l_session, DAP_CHAIN_ESBOCS_MSG_TYPE_SEND_DB, &l_session->db_hash, l_session->db_serial, + sizeof(*l_session->db_serial) + l_session->db_serial->data_size, l_validator_list); + dap_list_free_full(l_validator_list, NULL); + } + break; + } if (l_sync_attempt != l_session->cur_round.sync_attempt) { if (l_sync_attempt < l_session->cur_round.sync_attempt) { debug_if(l_cs_debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U @@ -1826,6 +2023,7 @@ static void s_session_packet_in(void *a_arg, dap_chain_node_addr_t *a_sender_nod " is greater than meassage sync attempt %"DAP_UINT64_FORMAT_U, l_session->chain->net_name, l_session->chain->name, l_session->cur_round.id, l_session->cur_round.sync_attempt, l_sync_attempt); + break; } else { uint64_t l_attempts_miss = l_sync_attempt - l_session->cur_round.sync_attempt; uint32_t l_attempts_miss_max = UINT16_MAX; // TODO calculate it rely on last block aceeption time & min round duration @@ -1834,6 +2032,7 @@ static void s_session_packet_in(void *a_arg, dap_chain_node_addr_t *a_sender_nod " SYNC message is rejected - too much sync attempt difference %"DAP_UINT64_FORMAT_U, l_session->chain->net_name, l_session->chain->name, l_session->cur_round.id, l_attempts_miss); + break; } else { debug_if(l_cs_debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U " SYNC message sync attempt %"DAP_UINT64_FORMAT_U" is greater than" @@ -1856,19 +2055,38 @@ static void s_session_packet_in(void *a_arg, dap_chain_node_addr_t *a_sender_nod if (!l_list) break; dap_chain_esbocs_validator_t *l_validator = l_list->data; - l_validator->is_synced = true; - if (++l_session->cur_round.validators_synced_count == dap_list_length(l_session->cur_round.validators_list)) { - l_session->cur_round.id = s_session_calc_current_round_id(l_session); - debug_if(l_cs_debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu." - " All validators are synchronized, wait to submit candidate", - l_session->chain->net_name, l_session->chain->name, - l_session->cur_round.id, l_message->hdr.attempt_num); - s_session_state_change(l_session, DAP_CHAIN_ESBOCS_SESSION_STATE_WAIT_PROC, dap_time_now()); + if (!l_validator->is_synced) { + l_validator->is_synced = true; + if (++l_session->cur_round.validators_synced_count == dap_list_length(l_session->cur_round.validators_list)) { + l_session->cur_round.id = s_session_calc_current_round_id(l_session); + debug_if(l_cs_debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu." + " All validators are synchronized, wait to submit candidate", + l_session->chain->net_name, l_session->chain->name, + l_session->cur_round.id, l_message->hdr.attempt_num); + s_session_state_change(l_session, DAP_CHAIN_ESBOCS_SESSION_STATE_WAIT_PROC, dap_time_now()); + } + } + } break; + + case DAP_CHAIN_ESBOCS_MSG_TYPE_SEND_DB: { + dap_global_db_pkt_t *l_db_pkt = l_message_data; + if (l_db_pkt->data_size + sizeof(*l_db_pkt) != l_message_data_size) { + log_it(L_WARNING, "Wrong send_db message size, have %zu bytes, must be %zu bytes", + l_message_data_size, l_db_pkt->data_size + sizeof(*l_db_pkt)); + break; + } + size_t l_data_objs_count = 0; + dap_store_obj_t *l_store_objs = dap_global_db_pkt_deserialize(l_db_pkt, &l_data_objs_count); + for (size_t i = 0; i < l_data_objs_count; i++) + dap_global_db_remote_apply_obj(l_store_objs + i, NULL, NULL); + if (l_store_objs) { + dap_store_obj_free(l_store_objs, l_data_objs_count); + s_session_db_serialize(l_session); } } break; case DAP_CHAIN_ESBOCS_MSG_TYPE_SUBMIT: { - uint8_t *l_candidate = l_message->msg_n_sign; + uint8_t *l_candidate = l_message_data; size_t l_candidate_size = l_message_data_size; if (!l_candidate_size || dap_hash_fast_is_blank(&l_message->hdr.candidate_hash)) { debug_if(l_cs_debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu." @@ -1910,6 +2128,10 @@ static void s_session_packet_in(void *a_arg, dap_chain_node_addr_t *a_sender_nod // store for new candidate l_store = DAP_NEW_Z(dap_chain_esbocs_store_t); + if (!l_store) { + log_it(L_ERROR, "Memory allocation error in s_session_packet_in"); + goto session_unlock; + } l_store->candidate_size = l_candidate_size; l_store->candidate_hash = *l_candidate_hash; l_store->candidate = DAP_DUP_SIZE(l_candidate, l_candidate_size); @@ -2045,7 +2267,7 @@ static void s_session_packet_in(void *a_arg, dap_chain_node_addr_t *a_sender_nod log_it(L_WARNING, "Only one directive can be processed at a time"); break; } - dap_chain_esbocs_directive_t *l_directive = (dap_chain_esbocs_directive_t *)l_message->msg_n_sign; + dap_chain_esbocs_directive_t *l_directive = l_message_data; size_t l_directive_size = l_message_data_size; if (l_directive_size < sizeof(dap_chain_esbocs_directive_t) || l_directive_size != l_directive->size) { log_it(L_WARNING, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu." @@ -2110,15 +2332,16 @@ static void s_session_packet_in(void *a_arg, dap_chain_node_addr_t *a_sender_nod if (!l_session->cur_round.directive_applied && ++l_session->cur_round.votes_for_count * 3 >= dap_list_length(l_session->cur_round.all_validators) * 2) { - s_session_directive_apply(l_session->cur_round.directive, &l_session->cur_round.directive_hash); + int l_res = s_session_directive_apply(l_session->cur_round.directive, &l_session->cur_round.directive_hash); l_session->cur_round.directive_applied = true; + if (!l_res) + s_session_db_serialize(l_session); s_session_state_change(l_session, DAP_CHAIN_ESBOCS_SESSION_STATE_PREVIOUS, dap_time_now()); } } else // l_message->hdr.type == DAP_CHAIN_ESBOCS_MSG_TYPE_VOTE_AGAINST if (++l_session->cur_round.votes_against_count * 3 >= dap_list_length(l_session->cur_round.all_validators) * 2) s_session_state_change(l_session, DAP_CHAIN_ESBOCS_SESSION_STATE_PREVIOUS, dap_time_now()); - } break; case DAP_CHAIN_ESBOCS_MSG_TYPE_PRE_COMMIT: @@ -2165,7 +2388,9 @@ static void s_message_send(dap_chain_esbocs_session_t *a_session, uint8_t a_mess for (dap_list_t *it = a_validators; it; it = it->next) { dap_chain_esbocs_validator_t *l_validator = it->data; - if (l_validator->is_synced || a_message_type == DAP_CHAIN_ESBOCS_MSG_TYPE_START_SYNC) { + if (l_validator->is_synced || + a_message_type == DAP_CHAIN_ESBOCS_MSG_TYPE_START_SYNC || + a_message_type == DAP_CHAIN_ESBOCS_MSG_TYPE_SEND_DB) { debug_if(PVT(a_session->esbocs)->debug, L_MSG, "Send pkt type 0x%x to "NODE_ADDR_FP_STR, a_message_type, NODE_ADDR_FP_ARGS_S(l_validator->node_addr)); l_voting_pkt->hdr.receiver_node_addr = l_validator->node_addr; @@ -2205,10 +2430,10 @@ static int s_callback_block_verify(dap_chain_cs_blocks_t *a_blocks, dap_chain_bl return -7; } - if (a_block->hdr.meta_n_datum_n_signs_size != a_block_size - sizeof(a_block->hdr)) { + /*if (a_block->hdr.meta_n_datum_n_signs_size != a_block_size - sizeof(a_block->hdr)) { log_it(L_WARNING, "Incorrect size with block %p on chain %s", a_block, a_blocks->chain->name); return -8; - } + }*/ // TODO Retunn it after hard-fork with correct block sizes if (l_esbocs->session && l_esbocs->session->processing_candidate == a_block) // It's a block candidate, don't check signs @@ -2235,6 +2460,7 @@ static int s_callback_block_verify(dap_chain_cs_blocks_t *a_blocks, dap_chain_bl uint16_t l_signs_verified_count = 0; size_t l_block_excl_sign_size = dap_chain_block_get_sign_offset(a_block, a_block_size) + sizeof(a_block->hdr); // Get the header on signing operation time + size_t l_block_original = a_block->hdr.meta_n_datum_n_signs_size; a_block->hdr.meta_n_datum_n_signs_size = l_block_excl_sign_size - sizeof(a_block->hdr); for (size_t i=0; i< l_signs_count; i++) { dap_sign_t *l_sign = (dap_sign_t *)l_signs[i]; @@ -2249,7 +2475,7 @@ static int s_callback_block_verify(dap_chain_cs_blocks_t *a_blocks, dap_chain_bl if (!l_esbocs_pvt->poa_mode) { // Compare signature with delegated keys if (!dap_chain_net_srv_stake_key_delegated(&l_signing_addr)) { - char *l_bad_addr = dap_chain_addr_to_str(&l_signing_addr); + char *l_bad_addr = dap_chain_hash_fast_to_str_new(&l_signing_addr.data.hash_fast); log_it(L_ATT, "Unknown PoS signer %s", l_bad_addr); DAP_DELETE(l_bad_addr); continue; @@ -2268,14 +2494,16 @@ static int s_callback_block_verify(dap_chain_cs_blocks_t *a_blocks, dap_chain_bl } DAP_DELETE(l_signs); // Restore the original header - a_block->hdr.meta_n_datum_n_signs_size = a_block_size - sizeof(a_block->hdr); + a_block->hdr.meta_n_datum_n_signs_size = l_block_original; - if ( l_ret != 0 ) { - return l_ret; - } if (l_signs_verified_count < l_esbocs_pvt->min_validators_count) { - log_it(L_ERROR, "Corrupted block: not enough authorized signs: %u of %u", l_signs_verified_count, l_esbocs_pvt->min_validators_count); - return -1; + dap_hash_fast_t l_block_hash; + dap_hash_fast(a_block, a_block_size, &l_block_hash); + char l_block_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; + dap_hash_fast_to_str(&l_block_hash, l_block_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE); + log_it(L_ERROR, "Corrupted block %s: not enough authorized signs: %u of %u", + l_block_hash_str, l_signs_verified_count, l_esbocs_pvt->min_validators_count); + return l_ret ? l_ret : -4; } return 0; } @@ -2305,12 +2533,21 @@ static dap_chain_datum_decree_t *s_esbocs_decree_set_min_validators_count(dap_ch l_total_tsd_size += sizeof(dap_tsd_t) + sizeof(uint256_t); l_tsd = DAP_NEW_Z_SIZE(dap_tsd_t, l_total_tsd_size); + if (!l_tsd) { + log_it(L_ERROR, "Memory allocation error in s_esbocs_decree_set_min_validators_count"); + return NULL; + } l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT; l_tsd->size = sizeof(uint256_t); *(uint256_t*)(l_tsd->data) = a_value; l_tsd_list = dap_list_append(l_tsd_list, l_tsd); l_decree = DAP_NEW_Z_SIZE(dap_chain_datum_decree_t, sizeof(dap_chain_datum_decree_t) + l_total_tsd_size); + if (!l_decree) { + log_it(L_ERROR, "Memory allocation error in s_esbocs_decree_set_min_validators_count"); + DAP_DEL_Z(l_tsd); + return NULL; + } l_decree->decree_version = DAP_CHAIN_DATUM_DECREE_VERSION; l_decree->header.ts_created = dap_time_now(); l_decree->header.type = DAP_CHAIN_DATUM_DECREE_TYPE_COMMON; @@ -2320,6 +2557,7 @@ static dap_chain_datum_decree_t *s_esbocs_decree_set_min_validators_count(dap_ch l_chain = dap_chain_net_get_default_chain_by_chain_type(a_net, CHAIN_TYPE_ANCHOR); if(!l_chain){ log_it(L_ERROR, "Can't find chain with decree support."); + DAP_DEL_Z(l_tsd); DAP_DELETE(l_decree); return NULL; } @@ -2355,10 +2593,12 @@ static dap_chain_datum_decree_t *s_esbocs_decree_set_min_validators_count(dap_ch log_it(L_DEBUG,"<-- Signed with '%s'", a_cert->name); }else{ log_it(L_ERROR, "Decree signing failed"); + DAP_DEL_Z(l_tsd); DAP_DELETE(l_decree); return NULL; } - + + DAP_DEL_Z(l_tsd); return l_decree; } diff --git a/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h b/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h index 6d99bb1b692a4ab8c2b24cfe6a5fdb78a875d6f2..cdee77d8c20e026e3ca0c01060f6f7ee4eedc2ce 100644 --- a/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h +++ b/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h @@ -5,8 +5,9 @@ #include "dap_chain_block.h" #include "dap_chain_cs_blocks.h" #include "dap_cert.h" +#include "dap_global_db_remote.h" -#define DAP_CHAIN_ESBOCS_PROTOCOL_VERSION 6 +#define DAP_CHAIN_ESBOCS_PROTOCOL_VERSION 7 #define DAP_CHAIN_ESBOCS_GDB_GROUPS_PREFIX "esbocs" #define DAP_CHAIN_ESBOCS_MSG_TYPE_SUBMIT 0x04 @@ -18,6 +19,7 @@ #define DAP_CHAIN_ESBOCS_MSG_TYPE_VOTE_FOR 0x22 #define DAP_CHAIN_ESBOCS_MSG_TYPE_VOTE_AGAINST 0x24 #define DAP_CHAIN_ESBOCS_MSG_TYPE_START_SYNC 0x32 +#define DAP_CHAIN_ESBOCS_MSG_TYPE_SEND_DB 0x36 #define DAP_CHAIN_BLOCKS_SESSION_ROUND_ID_SIZE 8 #define DAP_CHAIN_BLOCKS_SESSION_MESSAGE_ID_SIZE 8 @@ -161,6 +163,8 @@ typedef struct dap_chain_esbocs_session { uint8_t old_state; // for previous state return dap_chain_esbocs_round_t cur_round; bool round_fast_forward; + unsigned int listen_ensure; + bool sync_failed; dap_time_t ts_round_sync_start; // time of start sync dap_time_t ts_stage_entry; // time of current stage entrance @@ -171,6 +175,9 @@ typedef struct dap_chain_esbocs_session { dap_chain_addr_t my_signing_addr; dap_chain_esbocs_penalty_item_t *penalty; + // Temporary sync-over-consensus params + dap_global_db_pkt_t *db_serial; + dap_hash_fast_t db_hash; struct dap_chain_esbocs_session *next; struct dap_chain_esbocs_session *prev; diff --git a/modules/consensus/none/dap_chain_cs_none.c b/modules/consensus/none/dap_chain_cs_none.c index 608ea742ffe1cd4c9cc7cc9ece14dc0e1858a2dd..b9d4c4b149cd01286b5e544b5b0875b0c825114e 100644 --- a/modules/consensus/none/dap_chain_cs_none.c +++ b/modules/consensus/none/dap_chain_cs_none.c @@ -139,6 +139,7 @@ static void s_history_callback_notify(dap_global_db_context_t *a_context, dap_st dap_chain_net_t *l_net = dap_chain_net_by_id( l_gdb->chain->net_id); log_it(L_DEBUG,"%s.%s: op_code='%c' group=\"%s\" key=\"%s\" value_size=%zu",l_net->pub.name, l_gdb->chain->name, a_obj->type, a_obj->group, a_obj->key, a_obj->value_len); + s_chain_callback_atom_add(l_gdb->chain, a_obj->value, a_obj->value_len); dap_chain_net_sync_gdb_broadcast(a_context, a_obj, l_net); } } @@ -170,7 +171,16 @@ static void s_callback_memepool_notify(dap_global_db_context_t *a_context UNUSED int dap_chain_gdb_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg) { dap_chain_gdb_t *l_gdb = DAP_NEW_Z(dap_chain_gdb_t); + if (!l_gdb) { + log_it(L_ERROR, "Memory allocation error in dap_chain_gdb_new"); + return -1; + } dap_chain_gdb_private_t *l_gdb_priv = DAP_NEW_Z(dap_chain_gdb_private_t); + if (!l_gdb_priv) { + log_it(L_ERROR, "Memory allocation error in dap_chain_gdb_new"); + DAP_DELETE(l_gdb); + return -1; + } l_gdb->chain = a_chain; l_gdb->_internal = (void*) l_gdb_priv; a_chain->_inheritor = l_gdb; @@ -239,7 +249,8 @@ void dap_chain_gdb_delete(dap_chain_t * a_chain) DAP_DELETE(l_gdb_priv->group_datums); DAP_DELETE(l_gdb); - a_chain->_inheritor = NULL; + if (a_chain) + a_chain->_inheritor = NULL; } /** @@ -288,9 +299,9 @@ const char* dap_chain_gdb_get_group(dap_chain_t * a_chain) * @param a_values * @param a_arg */ -static void s_ledger_load_callback(dap_global_db_context_t *a_global_db_context, - int a_rc, const char *a_group, - const size_t a_values_total, const size_t a_values_count, +static void s_ledger_load_callback(UNUSED_ARG dap_global_db_context_t *a_global_db_context, + UNUSED_ARG int a_rc, UNUSED_ARG const char *a_group, + UNUSED_ARG const size_t a_values_total, const size_t a_values_count, dap_global_db_obj_t *a_values, void *a_arg) { assert(a_arg); @@ -302,7 +313,9 @@ static void s_ledger_load_callback(dap_global_db_context_t *a_global_db_context, assert(l_gdb_pvt); // make list of datums for(size_t i = 0; i < a_values_count; i++) { - s_chain_callback_atom_add(l_chain, a_values[i].value, a_values[i].value_len); + dap_global_db_obj_t *it = a_values + i; + s_chain_callback_atom_add(l_chain, it->value, it->value_len); + log_it(L_DEBUG,"Load mode, doesn't save item %s:%s", it->key, l_gdb_pvt->group_datums); } pthread_mutex_lock(&l_gdb_pvt->load_mutex); @@ -340,12 +353,21 @@ static void s_chain_gdb_ledger_load(dap_chain_t *a_chain) * @param a_datums_count object counts in datums array * @return size_t */ -static size_t s_chain_callback_datums_pool_proc(dap_chain_t * a_chain, dap_chain_datum_t ** a_datums, - size_t a_datums_count) +static size_t s_chain_callback_datums_pool_proc(dap_chain_t * a_chain, dap_chain_datum_t ** a_datums, size_t a_datums_count) { for(size_t i = 0; i < a_datums_count; i++) { - dap_chain_datum_t * l_datum = a_datums[i]; - s_chain_callback_atom_add(a_chain, l_datum,dap_chain_datum_size(l_datum) ); + dap_chain_datum_t *l_datum = a_datums[i]; + dap_hash_fast_t l_datum_hash; + char l_db_key[DAP_CHAIN_HASH_FAST_STR_SIZE]; + dap_hash_fast(l_datum->data, l_datum->header.data_size, &l_datum_hash); + dap_chain_hash_fast_to_str(&l_datum_hash, l_db_key, sizeof(l_db_key)); + int l_rc = dap_chain_net_verify_datum_for_add(a_chain, l_datum, &l_datum_hash); + if (l_rc != 0) { + log_it(L_ERROR, "Verified datum %s not passed the check, code %d", l_db_key, l_rc); + return i; + } + dap_global_db_set(PVT(DAP_CHAIN_GDB(a_chain))->group_datums, l_db_key, l_datum, + dap_chain_datum_size(l_datum), false, NULL, NULL); } return a_datums_count; } @@ -360,6 +382,10 @@ static size_t s_chain_callback_datums_pool_proc(dap_chain_t * a_chain, dap_chain */ static dap_chain_atom_verify_res_t s_chain_callback_atom_add(dap_chain_t * a_chain, dap_chain_atom_ptr_t a_atom, size_t a_atom_size) { + if (NULL == a_chain) { + log_it(L_WARNING, "Arguments is NULL for s_chain_callback_atom_add"); + return ATOM_REJECT; + } dap_chain_gdb_t * l_gdb = DAP_CHAIN_GDB(a_chain); dap_chain_gdb_private_t *l_gdb_priv = PVT(l_gdb); dap_chain_datum_t *l_datum = (dap_chain_datum_t*) a_atom; @@ -369,13 +395,13 @@ static dap_chain_atom_verify_res_t s_chain_callback_atom_add(dap_chain_t * a_cha return ATOM_REJECT; dap_chain_gdb_datum_hash_item_t * l_hash_item = DAP_NEW_Z(dap_chain_gdb_datum_hash_item_t); + if (!l_hash_item) { + log_it(L_ERROR, "Memory allocation error in s_chain_callback_atom_add"); + return ATOM_REJECT; + } size_t l_datum_size = dap_chain_datum_size(l_datum); dap_hash_fast(l_datum->data,l_datum->header.data_size,&l_hash_item->datum_data_hash ); dap_chain_hash_fast_to_str(&l_hash_item->datum_data_hash, l_hash_item->key, sizeof(l_hash_item->key)); - if (!l_gdb_priv->is_load_mode) { - dap_global_db_set(l_gdb_priv->group_datums, l_hash_item->key, l_datum, l_datum_size, false, NULL, NULL); - } else - log_it(L_DEBUG,"Load mode, doesn't save item %s:%s", l_hash_item->key, l_gdb_priv->group_datums); DL_APPEND(l_gdb_priv->hash_items, l_hash_item); if (!l_gdb_priv->is_load_mode && a_chain->atom_notifiers) { for(dap_list_t *l_iter = a_chain->atom_notifiers; l_iter; l_iter = dap_list_next(l_iter)) { @@ -425,6 +451,10 @@ static size_t s_chain_callback_atom_get_static_hdr_size() static dap_chain_atom_iter_t* s_chain_callback_atom_iter_create(dap_chain_t * a_chain, dap_chain_cell_id_t a_cell_id, bool a_with_treshold) { dap_chain_atom_iter_t * l_iter = DAP_NEW_Z(dap_chain_atom_iter_t); + if (!l_iter) { + log_it(L_ERROR, "Memory allocation error in s_chain_callback_atom_iter_create"); + return NULL; + } l_iter->chain = a_chain; l_iter->cell_id = a_cell_id; l_iter->with_treshold = a_with_treshold; @@ -443,6 +473,10 @@ static dap_chain_atom_iter_t* s_chain_callback_atom_iter_create_from(dap_chain_t dap_chain_atom_ptr_t a_atom, size_t a_atom_size) { dap_chain_atom_iter_t * l_iter = DAP_NEW_Z(dap_chain_atom_iter_t); + if (!l_iter) { + log_it(L_ERROR, "Memory allocation error in s_chain_callback_atom_iter_create"); + return NULL; + } l_iter->chain = a_chain; l_iter->cur = a_atom; l_iter->cur_size = a_atom_size; @@ -608,6 +642,10 @@ static dap_chain_datum_t **s_chain_callback_atom_get_datum(dap_chain_atom_ptr_t dap_chain_datum_t *l_datum = (dap_chain_datum_t *)a_atom; if (l_datum){ dap_chain_datum_t **l_datums = DAP_NEW(dap_chain_datum_t *); + if (!l_datums) { + log_it(L_ERROR, "Memory allocation error in s_chain_callback_atom_get_datum"); + return NULL; + } if (a_datums_count) *a_datums_count = 1; l_datums[0] = l_datum; diff --git a/modules/mempool/dap_chain_mempool.c b/modules/mempool/dap_chain_mempool.c index 562dbc76647670e61e86811e890870384605f6aa..be5d6ae3db2d0a7c1d165c7a33d6120c57bfb3c2 100644 --- a/modules/mempool/dap_chain_mempool.c +++ b/modules/mempool/dap_chain_mempool.c @@ -533,6 +533,12 @@ int dap_chain_mempool_tx_create_massive( dap_chain_t * a_chain, dap_enc_key_t *a } if ( memcmp(&l_out->addr, a_addr_from, sizeof (*a_addr_from))==0 ){ dap_chain_tx_used_out_item_t *l_item_back = DAP_NEW_Z(dap_chain_tx_used_out_item_t); + if (!l_item_back) { + log_it(L_ERROR, "Memory allocation error in dap_chain_mempool_tx_create_massive"); + DAP_DELETE(l_objs); + dap_list_free( l_list_out_items); + return -6; + } l_item_back->tx_hash_fast = l_tx_new_hash; l_item_back->num_idx_out = l_out_idx_tmp; l_item_back->value = l_value_back; @@ -828,21 +834,22 @@ char *dap_chain_mempool_tx_create_cond(dap_chain_net_t *a_net, char *dap_chain_mempool_base_tx_create(dap_chain_t *a_chain, dap_chain_hash_fast_t *a_emission_hash, dap_chain_id_t a_emission_chain_id, uint256_t a_emission_value, const char *a_ticker, - dap_enc_key_t *a_key_from, dap_chain_addr_t *a_addr_to, dap_cert_t **a_certs, size_t a_certs_count, + dap_chain_addr_t *a_addr_to, dap_enc_key_t *a_private_key, const char *a_hash_out_type, uint256_t a_value_fee) { uint256_t l_net_fee = {}; uint256_t l_total_fee = a_value_fee; uint256_t l_value_need = a_emission_value; uint256_t l_value_transfer = {}; - dap_chain_addr_t l_addr_fee = {}; - dap_chain_addr_t* l_addr_from = NULL; + dap_chain_addr_t l_addr_to_fee = {}; + dap_chain_addr_t l_addr_from_fee = {}; dap_list_t *l_list_used_out; const char *l_native_ticker = dap_chain_net_by_id(a_chain->net_id)->pub.native_ticker; bool not_native = dap_strcmp(a_ticker, l_native_ticker); - bool l_net_fee_used = dap_chain_net_tx_get_fee(a_chain->net_id, &l_net_fee, &l_addr_fee); - if(l_net_fee_used) - SUM_256_256(l_total_fee,l_net_fee,&l_total_fee); + bool l_net_fee_used = IS_ZERO_256(a_value_fee) ? false : + dap_chain_net_tx_get_fee(a_chain->net_id, &l_net_fee, &l_addr_to_fee); + if (l_net_fee_used) + SUM_256_256(l_total_fee, l_net_fee, &l_total_fee); dap_chain_datum_tx_t *l_tx = DAP_NEW_Z_SIZE(dap_chain_datum_tx_t, sizeof(dap_chain_datum_tx_t)); l_tx->header.ts_created = time(NULL); @@ -855,21 +862,18 @@ char *dap_chain_mempool_base_tx_create(dap_chain_t *a_chain, dap_chain_hash_fast dap_chain_datum_tx_delete(l_tx); return NULL; } - if (not_native) + if (not_native && !IS_ZERO_256(l_total_fee)) { - l_addr_from = DAP_NEW_Z(dap_chain_addr_t); - dap_chain_addr_fill_from_key(l_addr_from, a_key_from, a_chain->net_id); - if(!l_addr_from){ + if (dap_chain_addr_fill_from_key(&l_addr_from_fee, a_private_key, a_chain->net_id) != 0 ) { log_it(L_WARNING,"Can't fill address from transfer"); dap_chain_datum_tx_delete(l_tx); return NULL; } - // list of transaction with 'out' items + // list of transaction with 'out' items l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(a_chain->ledger, l_native_ticker, - l_addr_from, l_total_fee, &l_value_transfer); + &l_addr_from_fee, l_total_fee, &l_value_transfer); if (!l_list_used_out) { log_it(L_WARNING,"Not enough funds to transfer"); - DAP_DEL_Z(l_addr_from); dap_chain_datum_tx_delete(l_tx); return NULL; } @@ -881,72 +885,54 @@ char *dap_chain_mempool_base_tx_create(dap_chain_t *a_chain, dap_chain_hash_fast } //add out uint256_t l_value_back = l_value_transfer; // how much datoshi add to 'out' items - // Network fee - if (!dap_chain_datum_tx_add_out_ext_item(&l_tx, &l_addr_fee, l_net_fee, l_native_ticker)){ - dap_chain_datum_tx_delete(l_tx); - DAP_DEL_Z(l_addr_from); - return NULL; + // Network fee + if (l_net_fee_used) { + SUBTRACT_256_256(l_value_back, l_net_fee, &l_value_back); + if (!dap_chain_datum_tx_add_out_ext_item(&l_tx, &l_addr_to_fee, l_net_fee, l_native_ticker)){ + dap_chain_datum_tx_delete(l_tx); + return NULL; + } } - SUBTRACT_256_256(l_value_back, l_net_fee, &l_value_back); - if (!IS_ZERO_256(a_value_fee)) + if (!IS_ZERO_256(a_value_fee)) { SUBTRACT_256_256(l_value_back, a_value_fee, &l_value_back); + if (!dap_chain_datum_tx_add_fee_item(&l_tx, a_value_fee)){ + dap_chain_datum_tx_delete(l_tx); + return NULL; + } + } // coin back - if (!dap_chain_datum_tx_add_out_ext_item(&l_tx, l_addr_from, l_value_back, l_native_ticker)){ + if (!dap_chain_datum_tx_add_out_ext_item(&l_tx, &l_addr_from_fee, l_value_back, l_native_ticker)) { dap_chain_datum_tx_delete(l_tx); - DAP_DEL_Z(l_addr_from); return NULL; } - DAP_DEL_Z(l_addr_from); - - if (!dap_chain_datum_tx_add_out_ext_item(&l_tx, a_addr_to, l_value_need, a_ticker)){ + if (!dap_chain_datum_tx_add_out_ext_item(&l_tx, a_addr_to, l_value_need, a_ticker)) { dap_chain_datum_tx_delete(l_tx); return NULL; } } else { //native ticker - if (!IS_ZERO_256(a_value_fee)) + if (!IS_ZERO_256(a_value_fee)) { SUBTRACT_256_256(l_value_need, a_value_fee, &l_value_need); - if(l_net_fee_used){ + if (!dap_chain_datum_tx_add_fee_item(&l_tx, a_value_fee)){ + dap_chain_datum_tx_delete(l_tx); + return NULL; + } + } + if (l_net_fee_used) { SUBTRACT_256_256(l_value_need, l_net_fee, &l_value_need); - if (!dap_chain_datum_tx_add_out_item(&l_tx, &l_addr_fee, l_net_fee)){ + if (!dap_chain_datum_tx_add_out_item(&l_tx, &l_addr_to_fee, l_net_fee)) { dap_chain_datum_tx_delete(l_tx); return NULL; } } - if (!dap_chain_datum_tx_add_out_item(&l_tx, a_addr_to, l_value_need)){ + if (!dap_chain_datum_tx_add_out_item(&l_tx, a_addr_to, l_value_need)) { dap_chain_datum_tx_delete(l_tx); return NULL; } } - if (!IS_ZERO_256(a_value_fee)){ - if (!dap_chain_datum_tx_add_fee_item(&l_tx, a_value_fee)){ - dap_chain_datum_tx_delete(l_tx); - return NULL; - } - } //sign item - if (not_native) - { - if(a_key_from) - if(dap_chain_datum_tx_add_sign_item(&l_tx, a_key_from) < 0) { - log_it(L_WARNING, "No private key for sign"); - return NULL; - } - } - else{ - if (a_certs) { - for(size_t i = 0; i < a_certs_count; i++) { - if(dap_chain_datum_tx_add_sign_item(&l_tx, a_certs[i]->enc_key) < 0) { - log_it(L_WARNING, "No private key for certificate '%s'", a_certs[i]->name); - return NULL; - } - } - } - else - if(a_key_from) - if(dap_chain_datum_tx_add_sign_item(&l_tx, a_key_from) < 0) { - log_it(L_WARNING, "No private key for sign"); - return NULL; - } + if(dap_chain_datum_tx_add_sign_item(&l_tx, a_private_key) < 0) { + log_it(L_WARNING, "No private key for sign"); + return NULL; } size_t l_tx_size = dap_chain_datum_tx_get_size(l_tx); @@ -1054,6 +1040,10 @@ dap_datum_mempool_t * dap_datum_mempool_deserialize(uint8_t *a_datum_mempool_ser //uint8_t *a_datum_mempool_ser = DAP_NEW_Z_SIZE(uint8_t, datum_mempool_size / 2 + 1); //datum_mempool_size = hex2bin(a_datum_mempool_ser, datum_mempool_str_in, datum_mempool_size) / 2; dap_datum_mempool_t *datum_mempool = DAP_NEW_Z(dap_datum_mempool_t); + if (!datum_mempool) { + log_it(L_ERROR, "Memory allocation error in dap_datum_mempool_deserialize"); + return NULL; + } datum_mempool->version = *(uint16_t*)(a_datum_mempool_ser + shift_size); shift_size += sizeof(uint16_t); datum_mempool->datum_count = *(uint16_t*)(a_datum_mempool_ser + shift_size); diff --git a/modules/mempool/include/dap_chain_mempool.h b/modules/mempool/include/dap_chain_mempool.h index f14bdce4ebae2ee3249b48147e618ab0b787a0e9..97a3042c191e27cf21c386cb799deadf115e269e 100644 --- a/modules/mempool/include/dap_chain_mempool.h +++ b/modules/mempool/include/dap_chain_mempool.h @@ -83,9 +83,23 @@ int dap_chain_mempool_tx_create_massive(dap_chain_t * a_chain, dap_enc_key_t *a_ const char a_token_ticker[DAP_CHAIN_TICKER_SIZE_MAX], uint256_t a_value, uint256_t a_value_fee, size_t a_tx_num); +/** + * @brief dap_chain_mempool_base_tx_create + * @param a_chain + * @param a_emission_hash + * @param a_emission_chain_id + * @param a_emission_value + * @param a_ticker + * @param a_addr_to + * @param a_private_key For a basic transaction not in a native token, use the key obtained from the wallet. For the + * basic transaction in the native token, use the key obtained from the certificate. + * @param a_hash_out_type + * @param a_value_fee + * @return + */ char *dap_chain_mempool_base_tx_create(dap_chain_t *a_chain, dap_chain_hash_fast_t *a_emission_hash, dap_chain_id_t a_emission_chain_id, uint256_t a_emission_value, const char *a_ticker, - dap_enc_key_t *a_key_from, dap_chain_addr_t *a_addr_to, dap_cert_t **a_certs, size_t a_certs_count, + dap_chain_addr_t *a_addr_to, dap_enc_key_t *a_private_key, const char *a_hash_out_type, uint256_t a_value_fee); dap_chain_datum_token_emission_t *dap_chain_mempool_emission_get(dap_chain_t *a_chain, const char *a_emission_hash_str); diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c index 81229ae1a2313b649130d8ceacddf5d5e5516058..c642c468154ca296e1c12fe133e3ab39b42d5339 100644 --- a/modules/net/dap_chain_net.c +++ b/modules/net/dap_chain_net.c @@ -115,8 +115,8 @@ #include "dap_chain_node_dns_client.h" #include "dap_module.h" -#include "json-c/json.h" -#include "json-c/json_object.h" +#include "json.h" +#include "json_object.h" #include "dap_chain_net_srv_stake_pos_delegate.h" #include "dap_chain_net_srv_xchange.h" @@ -329,7 +329,9 @@ int dap_chain_net_init() "net -net <chain net name> ca del -hash <cert hash> [-H {hex | base58(default)}]\n" "\tDelete certificate from list of authority cetificates in GDB group by it's hash\n" "net -net <chain net name> ledger reload\n" - "\tPurge the cache of chain net ledger and recalculate it from chain file\n"); + "\tPurge the cache of chain net ledger and recalculate it from chain file\n" + "net -net <chain net name> poa_cets list\n" + "\tPrint list of PoA cerificates for this network\n"); s_seed_mode = dap_config_get_item_bool_default(g_config,"general","seed_mode",false); s_debug_more = dap_config_get_item_bool_default(g_config,"chain_net","debug_more",false); @@ -443,6 +445,10 @@ dap_chain_net_state_t dap_chain_net_get_target_state(dap_chain_net_t *a_net) void dap_chain_net_add_gdb_notify_callback(dap_chain_net_t *a_net, dap_store_obj_callback_notify_t a_callback, void *a_cb_arg) { dap_chain_gdb_notifier_t *l_notifier = DAP_NEW(dap_chain_gdb_notifier_t); + if (!l_notifier) { + log_it(L_ERROR, "Memory allocation error in dap_chain_net_add_gdb_notify_callback"); + return; + } l_notifier->callback = a_callback; l_notifier->cb_arg = a_cb_arg; PVT(a_net)->gdb_notifiers = dap_list_append(PVT(a_net)->gdb_notifiers, l_notifier); @@ -463,6 +469,11 @@ int dap_chain_net_add_downlink(dap_chain_net_t *a_net, dap_stream_worker_t *a_wo return -2; } l_downlink = DAP_NEW_Z(struct downlink); + if (!l_downlink) { + log_it(L_ERROR, "Memory allocation error in dap_chain_net_add_downlink"); + pthread_rwlock_unlock(&l_net_pvt->downlinks_lock); + return -1; + } l_downlink->worker = a_worker; l_downlink->ch_uuid = a_ch_uuid; l_downlink->esocket_uuid = a_esocket_uuid; @@ -489,12 +500,7 @@ void dap_chain_net_sync_gdb_broadcast(dap_global_db_context_t *a_context, dap_st return; dap_chain_net_t *l_net = (dap_chain_net_t *)a_arg; - dap_chain_t *l_chain = NULL; - if (a_obj->type == DAP_DB$K_OPTYPE_ADD) - l_chain = dap_chain_get_chain_from_group_name(l_net->pub.id, a_obj->group); - dap_chain_id_t l_chain_id = l_chain ? l_chain->id : (dap_chain_id_t) {}; - dap_chain_cell_id_t l_cell_id = l_chain ? l_chain->cells->id : (dap_chain_cell_id_t){}; - dap_global_db_pkt_t *l_data_out = dap_store_packet_single(a_obj); + dap_global_db_pkt_t *l_data_out = dap_global_db_pkt_serialize(a_obj); struct downlink *l_link, *l_tmp; pthread_rwlock_rdlock(&PVT(l_net)->downlinks_lock); HASH_ITER(hh, PVT(l_net)->downlinks, l_link, l_tmp) { @@ -507,7 +513,7 @@ void dap_chain_net_sync_gdb_broadcast(dap_global_db_context_t *a_context, dap_st if (!dap_stream_ch_chain_pkt_write_inter(a_context->queue_worker_ch_io_input[l_link->worker->worker->id], l_link->ch_uuid, DAP_STREAM_CH_CHAIN_PKT_TYPE_GLOBAL_DB, l_net->pub.id.uint64, - l_chain_id.uint64, l_cell_id.uint64, l_data_out, + 0, 0, l_data_out, sizeof(dap_global_db_pkt_t) + l_data_out->data_size)) debug_if(g_debug_reactor, L_ERROR, "Can't send pkt to worker (%d) for writing", l_link->worker->worker->id); } @@ -556,8 +562,10 @@ static bool s_net_send_atoms(dap_proc_thread_t *a_thread, void *a_arg) */ static void s_chain_callback_notify(void *a_arg, dap_chain_t *a_chain, dap_chain_cell_id_t a_id, void* a_atom, size_t a_atom_size) { - if (!a_arg) + if (!a_arg || !a_chain) { + log_it(L_ERROR, "Argument is NULL for s_chain_callback_notify"); return; + } dap_chain_net_t *l_net = (dap_chain_net_t *)a_arg; if (!HASH_COUNT(PVT(l_net)->downlinks)) return; @@ -567,6 +575,10 @@ static void s_chain_callback_notify(void *a_arg, dap_chain_t *a_chain, dap_chain return; struct net_broadcast_atoms_args *l_args = DAP_NEW(struct net_broadcast_atoms_args); + if (!l_args) { + log_it(L_ERROR, "Memory allocation error in s_chain_callback_notify"); + return; + } l_args->net = l_net; l_args->atom = DAP_DUP_SIZE(a_atom, a_atom_size); l_args->atom_size = a_atom_size; @@ -691,6 +703,11 @@ static int s_net_link_add(dap_chain_net_t *a_net, dap_chain_node_info_t *a_link_ return -3; } l_new_link = DAP_NEW_Z(struct net_link); + if (!l_new_link) { + log_it(L_ERROR, "Memory allocation error in s_net_link_add"); + pthread_mutex_unlock(&PVT(a_net)->uplinks_mutex); + return -4; + } l_new_link->link_info = DAP_DUP(a_link_node_info); l_new_link->uplink_ip = a_link_node_info->hdr.ext_addr_v4.s_addr; HASH_ADD(hh, l_pvt_net->net_links, uplink_ip, sizeof(l_new_link->uplink_ip), l_new_link); @@ -1139,6 +1156,10 @@ static bool s_new_balancer_link_request(dap_chain_net_t *a_net, int a_link_repla inet_ntop(AF_INET, &l_link_node_info->hdr.ext_addr_v4, l_node_addr_str, INET_ADDRSTRLEN); log_it(L_DEBUG, "Start balancer %s request to %s", PVT(a_net)->balancer_http ? "HTTP" : "DNS", l_node_addr_str); struct balancer_link_request *l_balancer_request = DAP_NEW_Z(struct balancer_link_request); + if (!l_balancer_request) { + log_it(L_ERROR, "Memory allocation error in s_new_balancer_link_request"); + return false; + } l_balancer_request->net = a_net; l_balancer_request->link_info = l_link_node_info; l_balancer_request->worker = dap_events_worker_get_auto(); @@ -1296,6 +1317,11 @@ static bool s_net_states_proc(dap_proc_thread_t *a_thread, void *a_arg) if (i >= l_net_pvt->gdb_sync_nodes_addrs_count) break; dap_chain_node_info_t *l_link_node_info = DAP_NEW_Z(dap_chain_node_info_t); + if (!l_link_node_info) { + log_it(L_ERROR, "Memory allocation error in s_net_states_proc"); + pthread_rwlock_unlock(&l_net_pvt->states_lock); + return false; + } l_link_node_info->hdr.address.uint64 = l_net_pvt->gdb_sync_nodes_addrs[i].uint64; l_link_node_info->hdr.ext_addr_v4.s_addr = l_net_pvt->gdb_sync_nodes_links_ips[i]; l_link_node_info->hdr.ext_port = l_net_pvt->gdb_sync_nodes_links_ports[i]; @@ -1453,6 +1479,10 @@ static dap_chain_net_t *s_net_new(const char *a_id, const char *a_name, if (!a_id || !a_name || !a_native_ticker || !a_node_role) return NULL; dap_chain_net_t *ret = DAP_NEW_Z_SIZE( dap_chain_net_t, sizeof(ret->pub) + sizeof(dap_chain_net_pvt_t) ); + if (!ret) { + log_it(L_ERROR, "Memory allocation error in s_net_new"); + return NULL; + } ret->pub.name = strdup( a_name ); ret->pub.native_ticker = strdup( a_native_ticker ); pthread_mutexattr_t l_mutex_attr; @@ -1791,6 +1821,7 @@ static int s_cli_net(int argc, char **argv, char **a_str_reply) const char *l_stats_str = NULL; const char *l_ca_str = NULL; const char *l_ledger_str = NULL; + const char *l_list_str = NULL; dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "sync", &l_sync_str); dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "link", &l_links_str); dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "go", &l_go_str); @@ -1798,6 +1829,7 @@ static int s_cli_net(int argc, char **argv, char **a_str_reply) dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "stats", &l_stats_str); dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "ca", &l_ca_str); dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "ledger", &l_ledger_str); + dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "poa_certs", &l_list_str); const char * l_sync_mode_str = "updates"; dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-mode", &l_sync_mode_str); @@ -2121,6 +2153,31 @@ static int s_cli_net(int argc, char **argv, char **a_str_reply) s_chain_net_ledger_cache_reload(l_net); if (l_return_state) dap_chain_net_start(l_net); + } else if (l_list_str && !strcmp(l_list_str, "list")) { + dap_list_t *l_net_keys = NULL; + for (dap_chain_t *l_chain = l_net->pub.chains; l_chain; l_chain = l_chain->next) { + if (!l_chain->callback_get_poa_certs) + continue; + l_net_keys = l_chain->callback_get_poa_certs(l_chain, NULL, NULL); + if (l_net_keys) + break; + } + if (!l_net_keys) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "No PoA certs found for this network"); + return -11; + } + dap_string_t *l_str_out = dap_string_new("List of network PoA certificates:\n"); + int i = 0; + for (dap_list_t *it = l_net_keys; it; it = it->next) { + dap_hash_fast_t l_pkey_hash; + char l_pkey_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; + dap_pkey_get_hash(it->data, &l_pkey_hash); + dap_chain_hash_fast_to_str(&l_pkey_hash, l_pkey_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE); + dap_string_append_printf(l_str_out, "%d) %s\n", i++, l_pkey_hash_str); + } + *a_str_reply = l_str_out->str; + dap_string_free(l_str_out, false); + } else { dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'net' requires one of subcomands: sync, link, go, get, stats, ca, ledger"); @@ -2203,365 +2260,475 @@ int s_net_init(const char * a_net_name, uint16_t a_acl_idx) log_it(L_ERROR,"Can't open default network config"); dap_string_free(l_cfg_path,true); return -1; - } else { - dap_string_free(l_cfg_path,true); - dap_chain_net_t * l_net = s_net_new( - dap_config_get_item_str(l_cfg , "general" , "id" ), - dap_config_get_item_str(l_cfg , "general" , "name" ), - dap_config_get_item_str(l_cfg , "general" , "native_ticker"), - dap_config_get_item_str(l_cfg , "general" , "node-role" ) - ); - if(!l_net) { - log_it(L_ERROR,"Can't create l_net"); + } + dap_string_free(l_cfg_path,true); + dap_chain_net_t * l_net = s_net_new( + dap_config_get_item_str(l_cfg , "general" , "id" ), + dap_config_get_item_str(l_cfg , "general" , "name" ), + dap_config_get_item_str(l_cfg , "general" , "native_ticker"), + dap_config_get_item_str(l_cfg , "general" , "node-role" ) + ); + if(!l_net) { + log_it(L_ERROR,"Can't create l_net"); + return -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; + l_net->pub.gdb_groups_prefix = dap_strdup ( + dap_config_get_item_str_default(l_cfg , "general" , "gdb_groups_prefix", + dap_config_get_item_str(l_cfg , "general" , "name" ) ) ); + dap_global_db_add_sync_group(l_net->pub.name, "global", s_gbd_history_callback_notify, l_net); + dap_global_db_add_sync_group(l_net->pub.name, l_net->pub.gdb_groups_prefix, s_gbd_history_callback_notify, l_net); + + l_net->pub.gdb_nodes = dap_strdup_printf("%s.nodes",l_net->pub.gdb_groups_prefix); + l_net->pub.gdb_nodes_aliases = dap_strdup_printf("%s.nodes.aliases",l_net->pub.gdb_groups_prefix); + + // nodes for special sync + char **l_gdb_sync_nodes_addrs = dap_config_get_array_str(l_cfg, "general", "gdb_sync_nodes_addrs", + &l_net_pvt->gdb_sync_nodes_addrs_count); + if(l_gdb_sync_nodes_addrs && l_net_pvt->gdb_sync_nodes_addrs_count > 0) { + l_net_pvt->gdb_sync_nodes_addrs = DAP_NEW_Z_SIZE(dap_chain_node_addr_t, + sizeof(dap_chain_node_addr_t)*l_net_pvt->gdb_sync_nodes_addrs_count); + if (!l_net_pvt->gdb_sync_nodes_addrs) { + log_it(L_ERROR, "Memory allocation error in s_net_init"); + dap_config_close(l_cfg); return -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; - l_net->pub.gdb_groups_prefix = dap_strdup ( - dap_config_get_item_str_default(l_cfg , "general" , "gdb_groups_prefix", - dap_config_get_item_str(l_cfg , "general" , "name" ) ) ); - dap_global_db_add_sync_group(l_net->pub.name, "global", s_gbd_history_callback_notify, l_net); - dap_global_db_add_sync_group(l_net->pub.name, l_net->pub.gdb_groups_prefix, s_gbd_history_callback_notify, l_net); - - l_net->pub.gdb_nodes = dap_strdup_printf("%s.nodes",l_net->pub.gdb_groups_prefix); - l_net->pub.gdb_nodes_aliases = dap_strdup_printf("%s.nodes.aliases",l_net->pub.gdb_groups_prefix); - - // nodes for special sync - char **l_gdb_sync_nodes_addrs = dap_config_get_array_str(l_cfg, "general", "gdb_sync_nodes_addrs", - &l_net_pvt->gdb_sync_nodes_addrs_count); - if(l_gdb_sync_nodes_addrs && l_net_pvt->gdb_sync_nodes_addrs_count > 0) { - l_net_pvt->gdb_sync_nodes_addrs = DAP_NEW_Z_SIZE(dap_chain_node_addr_t, - sizeof(dap_chain_node_addr_t)*l_net_pvt->gdb_sync_nodes_addrs_count); - for(uint16_t i = 0; i < l_net_pvt->gdb_sync_nodes_addrs_count; i++) { - dap_chain_node_addr_from_str(l_net_pvt->gdb_sync_nodes_addrs + i, l_gdb_sync_nodes_addrs[i]); - } + for(uint16_t i = 0; i < l_net_pvt->gdb_sync_nodes_addrs_count; i++) { + dap_chain_node_addr_from_str(l_net_pvt->gdb_sync_nodes_addrs + i, l_gdb_sync_nodes_addrs[i]); } - // links for special sync - uint16_t l_gdb_links_count = 0; - PVT(l_net)->gdb_sync_nodes_links_count = 0; - char **l_gdb_sync_nodes_links = dap_config_get_array_str(l_cfg, "general", "gdb_sync_nodes_links", &l_gdb_links_count); - if (l_gdb_sync_nodes_links && l_gdb_links_count > 0) { - l_net_pvt->gdb_sync_nodes_links_ips = DAP_NEW_Z_SIZE(uint32_t, l_gdb_links_count * sizeof(uint32_t)); - l_net_pvt->gdb_sync_nodes_links_ports = DAP_NEW_SIZE(uint16_t, l_gdb_links_count * sizeof(uint16_t)); - for(uint16_t i = 0; i < l_gdb_links_count; i++) { - char *l_gdb_link_port_str = strchr(l_gdb_sync_nodes_links[i], ':'); - if (!l_gdb_link_port_str) { - continue; - } - uint16_t l_gdb_link_port = atoi(l_gdb_link_port_str + 1); - if (!l_gdb_link_port) { - continue; - } - int l_gdb_link_len = l_gdb_link_port_str - l_gdb_sync_nodes_links[i]; - char l_gdb_link_ip_str[l_gdb_link_len + 1]; - memcpy(l_gdb_link_ip_str, l_gdb_sync_nodes_links[i], l_gdb_link_len); - l_gdb_link_ip_str[l_gdb_link_len] = '\0'; - struct in_addr l_in_addr; - if (inet_pton(AF_INET, (const char *)l_gdb_link_ip_str, &l_in_addr) > 0) { - PVT(l_net)->gdb_sync_nodes_links_ips[PVT(l_net)->gdb_sync_nodes_links_count] = l_in_addr.s_addr; - PVT(l_net)->gdb_sync_nodes_links_ports[PVT(l_net)->gdb_sync_nodes_links_count] = l_gdb_link_port; - PVT(l_net)->gdb_sync_nodes_links_count++; - } - } + } + // links for special sync + uint16_t l_gdb_links_count = 0; + PVT(l_net)->gdb_sync_nodes_links_count = 0; + char **l_gdb_sync_nodes_links = dap_config_get_array_str(l_cfg, "general", "gdb_sync_nodes_links", &l_gdb_links_count); + if (l_gdb_sync_nodes_links && l_gdb_links_count > 0) { + l_net_pvt->gdb_sync_nodes_links_ips = DAP_NEW_Z_SIZE(uint32_t, l_gdb_links_count * sizeof(uint32_t)); + if (!l_net_pvt->gdb_sync_nodes_links_ips) { + log_it(L_ERROR, "Memory allocation error in s_net_init"); + dap_config_close(l_cfg); + return -1; } - // groups for special sync - uint16_t l_gdb_sync_groups_count; - char **l_gdb_sync_groups = dap_config_get_array_str(l_cfg, "general", "gdb_sync_groups", &l_gdb_sync_groups_count); - if (l_gdb_sync_groups && l_gdb_sync_groups_count > 0) { - for(uint16_t i = 0; i < l_gdb_sync_groups_count; i++) { - // add group to special sync - dap_global_db_add_sync_extra_group(l_net->pub.name, l_gdb_sync_groups[i], s_gbd_history_callback_notify, l_net); - } + l_net_pvt->gdb_sync_nodes_links_ports = DAP_NEW_SIZE(uint16_t, l_gdb_links_count * sizeof(uint16_t)); + if (!l_net_pvt->gdb_sync_nodes_links_ports) { + log_it(L_ERROR, "Memory allocation error in s_net_init"); + DAP_DEL_Z(l_net_pvt->gdb_sync_nodes_links_ips); + dap_config_close(l_cfg); + return -1; } - - // Add network to the list - dap_chain_net_item_t * l_net_item = DAP_NEW_Z( dap_chain_net_item_t); - snprintf(l_net_item->name,sizeof (l_net_item->name),"%s" - ,dap_config_get_item_str(l_cfg , "general" , "name" )); - l_net_item->chain_net = l_net; - l_net_item->net_id.uint64 = l_net->pub.id.uint64; - pthread_rwlock_wrlock(&s_net_items_rwlock); - HASH_ADD_STR(s_net_items,name,l_net_item); - HASH_ADD(hh2, s_net_ids, net_id, sizeof(l_net_item->net_id), l_net_item); - pthread_rwlock_unlock(&s_net_items_rwlock); - - // LEDGER model - uint16_t l_ledger_flags = 0; - switch ( PVT( l_net )->node_role.enums ) { - case NODE_ROLE_LIGHT: - break; - case NODE_ROLE_FULL: - l_ledger_flags |= DAP_CHAIN_LEDGER_CHECK_LOCAL_DS | DAP_CHAIN_LEDGER_CHECK_TOKEN_EMISSION; - if (dap_config_get_item_bool_default(g_config, "ledger", "cache_enabled", true)) - l_ledger_flags |= DAP_CHAIN_LEDGER_CACHE_ENABLED; - default: - l_ledger_flags |= DAP_CHAIN_LEDGER_CHECK_CELLS_DS; + for(uint16_t i = 0; i < l_gdb_links_count; i++) { + char *l_gdb_link_port_str = strchr(l_gdb_sync_nodes_links[i], ':'); + if (!l_gdb_link_port_str) { + continue; + } + uint16_t l_gdb_link_port = atoi(l_gdb_link_port_str + 1); + if (!l_gdb_link_port) + continue; + int l_gdb_link_len = l_gdb_link_port_str - l_gdb_sync_nodes_links[i]; + char l_gdb_link_ip_str[l_gdb_link_len + 1]; + memcpy(l_gdb_link_ip_str, l_gdb_sync_nodes_links[i], l_gdb_link_len); + l_gdb_link_ip_str[l_gdb_link_len] = '\0'; + struct in_addr l_in_addr; + if (inet_pton(AF_INET, (const char *)l_gdb_link_ip_str, &l_in_addr) > 0) { + PVT(l_net)->gdb_sync_nodes_links_ips[PVT(l_net)->gdb_sync_nodes_links_count] = l_in_addr.s_addr; + PVT(l_net)->gdb_sync_nodes_links_ports[PVT(l_net)->gdb_sync_nodes_links_count] = l_gdb_link_port; + PVT(l_net)->gdb_sync_nodes_links_count++; + } } - // init LEDGER model - l_net->pub.ledger = dap_chain_ledger_create(l_ledger_flags, l_net->pub.name, l_net->pub.native_ticker); - // Check if seed nodes are present in local db alias - char **l_seed_aliases = dap_config_get_array_str(l_cfg, "general", "seed_nodes_aliases", - &l_net_pvt->seed_aliases_count); - if (l_net_pvt->seed_aliases_count) - l_net_pvt->seed_aliases = DAP_NEW_Z_SIZE(char*, sizeof(char*) * l_net_pvt->seed_aliases_count); - for(size_t i = 0; i < l_net_pvt->seed_aliases_count; i++) - l_net_pvt->seed_aliases[i] = dap_strdup(l_seed_aliases[i]); - // randomize seed nodes list - for (int j = l_net_pvt->seed_aliases_count - 1; j > 0; j--) { - int n = rand() % j; - char *tmp = l_net_pvt->seed_aliases[n]; - l_net_pvt->seed_aliases[n] = l_net_pvt->seed_aliases[j]; - l_net_pvt->seed_aliases[j] = tmp; + } + // groups for special sync + uint16_t l_gdb_sync_groups_count; + char **l_gdb_sync_groups = dap_config_get_array_str(l_cfg, "general", "gdb_sync_groups", &l_gdb_sync_groups_count); + if (l_gdb_sync_groups && l_gdb_sync_groups_count > 0) { + for(uint16_t i = 0; i < l_gdb_sync_groups_count; i++) { + // add group to special sync + dap_global_db_add_sync_extra_group(l_net->pub.name, l_gdb_sync_groups[i], s_gbd_history_callback_notify, l_net); } + } - uint16_t l_seed_nodes_addrs_len =0; - char ** l_seed_nodes_addrs = dap_config_get_array_str( l_cfg , "general" ,"seed_nodes_addrs" - ,&l_seed_nodes_addrs_len); - - uint16_t l_seed_nodes_ipv4_len =0; - char ** l_seed_nodes_ipv4 = dap_config_get_array_str( l_cfg , "general" ,"seed_nodes_ipv4" - ,&l_seed_nodes_ipv4_len); - - uint16_t l_seed_nodes_ipv6_len =0; - char ** l_seed_nodes_ipv6 = dap_config_get_array_str( l_cfg , "general" ,"seed_nodes_ipv6" - ,&l_seed_nodes_ipv6_len); - - uint16_t l_seed_nodes_hostnames_len =0; - char ** l_seed_nodes_hostnames = dap_config_get_array_str( l_cfg , "general" ,"seed_nodes_hostnames" - ,&l_seed_nodes_hostnames_len); - - uint16_t l_seed_nodes_port_len =0; - char ** l_seed_nodes_port = dap_config_get_array_str( l_cfg , "general" ,"seed_nodes_port" - ,&l_seed_nodes_port_len); - uint16_t l_bootstrap_nodes_len = 0; - char **l_bootstrap_nodes = dap_config_get_array_str(l_cfg, "general", "bootstrap_hostnames", &l_bootstrap_nodes_len); - - // maximum number of prepared connections to other nodes - l_net_pvt->max_links_count = dap_config_get_item_int16_default(l_cfg, "general", "max_links", 5); - // required number of active connections to other nodes - l_net_pvt->required_links_count = dap_config_get_item_int16_default(l_cfg, "general", "require_links", 3); - // wait time before reconnect attempt with same link - l_net_pvt->reconnect_delay = dap_config_get_item_int16_default(l_cfg, "general", "reconnect_delay", 10); - - const char * l_node_addr_type = dap_config_get_item_str_default(l_cfg , "general" ,"node_addr_type","auto"); - - const char * l_node_addr_str = NULL; - const char * l_node_alias_str = NULL; - - // use unique addr from pub key - if(!dap_strcmp(l_node_addr_type, "auto")) { - size_t l_pub_key_data_size = 0; - uint8_t *l_pub_key_data = NULL; - - // read pub key - char *l_addr_key = dap_strdup_printf("node-addr-%s", l_net->pub.name); - l_pub_key_data = dap_global_db_get_sync(GROUP_LOCAL_NODE_ADDR, l_addr_key, &l_pub_key_data_size, NULL, NULL); - // generate a new pub key if it doesn't exist - if(!l_pub_key_data || !l_pub_key_data_size){ - - const char * l_certs_name_str = l_addr_key; - dap_cert_t ** l_certs = NULL; - size_t l_certs_size = 0; - dap_cert_t * l_cert = NULL; - // Load certs or create if not found - if(!dap_cert_parse_str_list(l_certs_name_str, &l_certs, &l_certs_size)) { // Load certs - const char *l_cert_folder = dap_cert_get_folder(0); - // create new cert - if(l_cert_folder) { - char *l_cert_path = dap_strdup_printf("%s/%s.dcert", l_cert_folder, l_certs_name_str); - l_cert = dap_cert_generate(l_certs_name_str, l_cert_path, DAP_ENC_KEY_TYPE_SIG_DILITHIUM); - DAP_DELETE(l_cert_path); - } - } - if(l_certs_size > 0) - l_cert = l_certs[0]; - if(l_cert) { - l_pub_key_data = dap_enc_key_serialize_pub_key(l_cert->enc_key, &l_pub_key_data_size); - // save pub key - if(l_pub_key_data && l_pub_key_data_size > 0) - dap_global_db_set(GROUP_LOCAL_NODE_ADDR, l_addr_key, l_pub_key_data, l_pub_key_data_size, false, - NULL, NULL); + // Add network to the list + dap_chain_net_item_t * l_net_item = DAP_NEW_Z( dap_chain_net_item_t); + if (!l_net_item) { + log_it(L_ERROR, "Memory allocation error in s_net_init"); + dap_config_close(l_cfg); + return -1; + } + snprintf(l_net_item->name,sizeof (l_net_item->name),"%s" + ,dap_config_get_item_str(l_cfg , "general" , "name" )); + l_net_item->chain_net = l_net; + l_net_item->net_id.uint64 = l_net->pub.id.uint64; + pthread_rwlock_wrlock(&s_net_items_rwlock); + HASH_ADD_STR(s_net_items,name,l_net_item); + HASH_ADD(hh2, s_net_ids, net_id, sizeof(l_net_item->net_id), l_net_item); + pthread_rwlock_unlock(&s_net_items_rwlock); + + // Check if seed nodes are present in local db alias + char **l_seed_aliases = dap_config_get_array_str(l_cfg, "general", "seed_nodes_aliases", + &l_net_pvt->seed_aliases_count); + if (l_net_pvt->seed_aliases_count) + l_net_pvt->seed_aliases = DAP_NEW_Z_SIZE(char*, sizeof(char*) * l_net_pvt->seed_aliases_count); + for(size_t i = 0; i < l_net_pvt->seed_aliases_count; i++) + l_net_pvt->seed_aliases[i] = dap_strdup(l_seed_aliases[i]); + // randomize seed nodes list + for (int j = l_net_pvt->seed_aliases_count - 1; j > 0; j--) { + int n = rand() % j; + char *tmp = l_net_pvt->seed_aliases[n]; + l_net_pvt->seed_aliases[n] = l_net_pvt->seed_aliases[j]; + l_net_pvt->seed_aliases[j] = tmp; + } + + uint16_t l_seed_nodes_addrs_len =0; + char ** l_seed_nodes_addrs = dap_config_get_array_str( l_cfg , "general" ,"seed_nodes_addrs" + ,&l_seed_nodes_addrs_len); + + uint16_t l_seed_nodes_ipv4_len =0; + char ** l_seed_nodes_ipv4 = dap_config_get_array_str( l_cfg , "general" ,"seed_nodes_ipv4" + ,&l_seed_nodes_ipv4_len); + + uint16_t l_seed_nodes_ipv6_len =0; + char ** l_seed_nodes_ipv6 = dap_config_get_array_str( l_cfg , "general" ,"seed_nodes_ipv6" + ,&l_seed_nodes_ipv6_len); + + uint16_t l_seed_nodes_hostnames_len =0; + char ** l_seed_nodes_hostnames = dap_config_get_array_str( l_cfg , "general" ,"seed_nodes_hostnames" + ,&l_seed_nodes_hostnames_len); + + uint16_t l_seed_nodes_port_len =0; + char ** l_seed_nodes_port = dap_config_get_array_str( l_cfg , "general" ,"seed_nodes_port" + ,&l_seed_nodes_port_len); + uint16_t l_bootstrap_nodes_len = 0; + char **l_bootstrap_nodes = dap_config_get_array_str(l_cfg, "general", "bootstrap_hostnames", &l_bootstrap_nodes_len); + + // maximum number of prepared connections to other nodes + l_net_pvt->max_links_count = dap_config_get_item_int16_default(l_cfg, "general", "max_links", 5); + // required number of active connections to other nodes + l_net_pvt->required_links_count = dap_config_get_item_int16_default(l_cfg, "general", "require_links", 3); + // wait time before reconnect attempt with same link + l_net_pvt->reconnect_delay = dap_config_get_item_int16_default(l_cfg, "general", "reconnect_delay", 10); + + const char * l_node_addr_type = dap_config_get_item_str_default(l_cfg , "general" ,"node_addr_type","auto"); + + const char * l_node_addr_str = NULL; + const char * l_node_alias_str = NULL; + + // use unique addr from pub key + if(!dap_strcmp(l_node_addr_type, "auto")) { + size_t l_pub_key_data_size = 0; + uint8_t *l_pub_key_data = NULL; + + // read pub key + char *l_addr_key = dap_strdup_printf("node-addr-%s", l_net->pub.name); + l_pub_key_data = dap_global_db_get_sync(GROUP_LOCAL_NODE_ADDR, l_addr_key, &l_pub_key_data_size, NULL, NULL); + // generate a new pub key if it doesn't exist + if(!l_pub_key_data || !l_pub_key_data_size){ + + const char * l_certs_name_str = l_addr_key; + dap_cert_t ** l_certs = NULL; + size_t l_certs_size = 0; + dap_cert_t * l_cert = NULL; + // Load certs or create if not found + if(!dap_cert_parse_str_list(l_certs_name_str, &l_certs, &l_certs_size)) { // Load certs + const char *l_cert_folder = dap_cert_get_folder(0); + // create new cert + if(l_cert_folder) { + char *l_cert_path = dap_strdup_printf("%s/%s.dcert", l_cert_folder, l_certs_name_str); + l_cert = dap_cert_generate(l_certs_name_str, l_cert_path, DAP_ENC_KEY_TYPE_SIG_DILITHIUM); + DAP_DELETE(l_cert_path); } } - // generate addr from pub_key - dap_chain_hash_fast_t l_hash; - if(l_pub_key_data_size > 0 && dap_hash_fast(l_pub_key_data, l_pub_key_data_size, &l_hash) == 1) { - l_node_addr_str = dap_strdup_printf("%04X::%04X::%04X::%04X", - (uint16_t) *(uint16_t*) (l_hash.raw), - (uint16_t) *(uint16_t*) (l_hash.raw + 2), - (uint16_t) *(uint16_t*) (l_hash.raw + DAP_CHAIN_HASH_FAST_SIZE - 4), - (uint16_t) *(uint16_t*) (l_hash.raw + DAP_CHAIN_HASH_FAST_SIZE - 2)); + if(l_certs_size > 0) + l_cert = l_certs[0]; + if(l_cert) { + l_pub_key_data = dap_enc_key_serialize_pub_key(l_cert->enc_key, &l_pub_key_data_size); + // save pub key + if(l_pub_key_data && l_pub_key_data_size > 0) + dap_global_db_set(GROUP_LOCAL_NODE_ADDR, l_addr_key, l_pub_key_data, l_pub_key_data_size, false, + NULL, NULL); } - DAP_DELETE(l_addr_key); - DAP_DELETE(l_pub_key_data); } - // use static addr from setting - else if(!dap_strcmp(l_node_addr_type, "static")) { - //const char * l_node_ipv4_str = dap_config_get_item_str(l_cfg , "general" ,"node-ipv4"); - l_node_addr_str = dap_strdup(dap_config_get_item_str(l_cfg, "general", "node-addr")); - l_node_alias_str = dap_config_get_item_str(l_cfg, "general", "node-alias"); + // generate addr from pub_key + dap_chain_hash_fast_t l_hash; + if(l_pub_key_data_size > 0 && dap_hash_fast(l_pub_key_data, l_pub_key_data_size, &l_hash) == 1) { + l_node_addr_str = dap_strdup_printf("%04X::%04X::%04X::%04X", + (uint16_t) *(uint16_t*) (l_hash.raw), + (uint16_t) *(uint16_t*) (l_hash.raw + 2), + (uint16_t) *(uint16_t*) (l_hash.raw + DAP_CHAIN_HASH_FAST_SIZE - 4), + (uint16_t) *(uint16_t*) (l_hash.raw + DAP_CHAIN_HASH_FAST_SIZE - 2)); } - - log_it (L_DEBUG, "Read %u aliases, %u address and %u ipv4 addresses, check them", - l_net_pvt->seed_aliases_count,l_seed_nodes_addrs_len, l_seed_nodes_ipv4_len ); - PVT(l_net)->seed_nodes_addrs_v4 = DAP_NEW_SIZE(struct in_addr, l_net_pvt->seed_aliases_count * sizeof(struct in_addr)); - // save new nodes from cfg file to db - for ( size_t i = 0; i < PVT(l_net)->seed_aliases_count && - i < l_seed_nodes_addrs_len && - ( - ( l_seed_nodes_ipv4_len && i < l_seed_nodes_ipv4_len ) || - ( l_seed_nodes_ipv6_len && i < l_seed_nodes_ipv6_len ) || - ( l_seed_nodes_hostnames_len && i < l_seed_nodes_hostnames_len ) - ); i++) { - dap_chain_node_addr_t l_seed_node_addr = { 0 }, *l_seed_node_addr_gdb = NULL; - dap_chain_node_info_t l_node_info = { 0 }, *l_node_info_gdb = NULL; - - log_it(L_NOTICE, "Check alias %s in db", l_net_pvt->seed_aliases[i]); - snprintf(l_node_info.hdr.alias,sizeof (l_node_info.hdr.alias),"%s", PVT(l_net)->seed_aliases[i]); - if (dap_chain_node_addr_from_str(&l_seed_node_addr, l_seed_nodes_addrs[i])) { - log_it(L_ERROR,"Wrong address format, must be 0123::4567::89AB::CDEF"); - continue; - } - if (l_seed_nodes_ipv4_len) - inet_pton(AF_INET, l_seed_nodes_ipv4[i], &l_node_info.hdr.ext_addr_v4); - if (l_seed_nodes_ipv6_len) - inet_pton(AF_INET6, l_seed_nodes_ipv6[i], &l_node_info.hdr.ext_addr_v6); - l_node_info.hdr.ext_port = l_seed_nodes_port_len && l_seed_nodes_port_len >= i ? - strtoul(l_seed_nodes_port[i], NULL, 10) : 8079; - - if (l_seed_nodes_hostnames_len) { - struct sockaddr l_sa = {}; - log_it(L_DEBUG, "Resolve %s addr", l_seed_nodes_hostnames[i]); - int l_ret_code = dap_net_resolve_host(l_seed_nodes_hostnames[i], AF_INET, &l_sa); - if (l_ret_code == 0) { - struct in_addr *l_res = (struct in_addr *)&l_sa; - log_it(L_NOTICE, "Resolved %s to %s (ipv4)", l_seed_nodes_hostnames[i], inet_ntoa(*l_res)); - l_node_info.hdr.ext_addr_v4.s_addr = l_res->s_addr; - l_net_pvt->seed_nodes_addrs_v4[i].s_addr = l_res->s_addr; - } else { - log_it(L_ERROR, "%s", gai_strerror(l_ret_code)); - } + DAP_DELETE(l_addr_key); + DAP_DELETE(l_pub_key_data); + } + // use static addr from setting + else if(!dap_strcmp(l_node_addr_type, "static")) { + //const char * l_node_ipv4_str = dap_config_get_item_str(l_cfg , "general" ,"node-ipv4"); + l_node_addr_str = dap_strdup(dap_config_get_item_str(l_cfg, "general", "node-addr")); + l_node_alias_str = dap_config_get_item_str(l_cfg, "general", "node-alias"); + } + + log_it (L_DEBUG, "Read %u aliases, %u address and %u ipv4 addresses, check them", + l_net_pvt->seed_aliases_count,l_seed_nodes_addrs_len, l_seed_nodes_ipv4_len ); + PVT(l_net)->seed_nodes_addrs_v4 = DAP_NEW_SIZE(struct in_addr, l_net_pvt->seed_aliases_count * sizeof(struct in_addr)); + // save new nodes from cfg file to db + for ( size_t i = 0; i < PVT(l_net)->seed_aliases_count && + i < l_seed_nodes_addrs_len && + ( + ( l_seed_nodes_ipv4_len && i < l_seed_nodes_ipv4_len ) || + ( l_seed_nodes_ipv6_len && i < l_seed_nodes_ipv6_len ) || + ( l_seed_nodes_hostnames_len && i < l_seed_nodes_hostnames_len ) + ); i++) { + dap_chain_node_addr_t l_seed_node_addr = { 0 }, *l_seed_node_addr_gdb = NULL; + dap_chain_node_info_t l_node_info = { 0 }, *l_node_info_gdb = NULL; + + log_it(L_NOTICE, "Check alias %s in db", l_net_pvt->seed_aliases[i]); + snprintf(l_node_info.hdr.alias,sizeof (l_node_info.hdr.alias),"%s", PVT(l_net)->seed_aliases[i]); + if (dap_chain_node_addr_from_str(&l_seed_node_addr, l_seed_nodes_addrs[i])) { + log_it(L_ERROR,"Wrong address format, must be 0123::4567::89AB::CDEF"); + continue; + } + if (l_seed_nodes_ipv4_len) + inet_pton(AF_INET, l_seed_nodes_ipv4[i], &l_node_info.hdr.ext_addr_v4); + if (l_seed_nodes_ipv6_len) + inet_pton(AF_INET6, l_seed_nodes_ipv6[i], &l_node_info.hdr.ext_addr_v6); + l_node_info.hdr.ext_port = l_seed_nodes_port_len && l_seed_nodes_port_len >= i ? + strtoul(l_seed_nodes_port[i], NULL, 10) : 8079; + + if (l_seed_nodes_hostnames_len) { + struct sockaddr l_sa = {}; + log_it(L_DEBUG, "Resolve %s addr", l_seed_nodes_hostnames[i]); + int l_ret_code = dap_net_resolve_host(l_seed_nodes_hostnames[i], AF_INET, &l_sa); + if (l_ret_code == 0) { + struct in_addr *l_res = (struct in_addr *)&l_sa; + log_it(L_NOTICE, "Resolved %s to %s (ipv4)", l_seed_nodes_hostnames[i], inet_ntoa(*l_res)); + l_node_info.hdr.ext_addr_v4.s_addr = l_res->s_addr; + l_net_pvt->seed_nodes_addrs_v4[i].s_addr = l_res->s_addr; + } else { + log_it(L_ERROR, "%s", gai_strerror(l_ret_code)); } + } - l_seed_node_addr_gdb = dap_chain_node_alias_find(l_net, l_net_pvt->seed_aliases[i]); - l_node_info_gdb = l_seed_node_addr_gdb ? dap_chain_node_info_read(l_net, l_seed_node_addr_gdb) : NULL; + l_seed_node_addr_gdb = dap_chain_node_alias_find(l_net, l_net_pvt->seed_aliases[i]); + l_node_info_gdb = l_seed_node_addr_gdb ? dap_chain_node_info_read(l_net, l_seed_node_addr_gdb) : NULL; - l_node_info.hdr.address = l_seed_node_addr; - if (l_node_info.hdr.ext_addr_v4.s_addr || + l_node_info.hdr.address = l_seed_node_addr; + if (l_node_info.hdr.ext_addr_v4.s_addr || #ifdef DAP_OS_BSD - l_node_info.hdr.ext_addr_v6.__u6_addr.__u6_addr32[0] + l_node_info.hdr.ext_addr_v6.__u6_addr.__u6_addr32[0] #else - l_node_info.hdr.ext_addr_v6.s6_addr32[0] + l_node_info.hdr.ext_addr_v6.s6_addr32[0] #endif - ) { - /* Let's check if config was altered */ - int l_ret = l_node_info_gdb ? memcmp(&l_node_info, l_node_info_gdb, sizeof(dap_chain_node_info_t)) : 1; + ) { + /* Let's check if config was altered */ + int l_ret = l_node_info_gdb ? memcmp(&l_node_info, l_node_info_gdb, sizeof(dap_chain_node_info_t)) : 1; + if (!l_ret) { + log_it(L_NOTICE,"Seed node "NODE_ADDR_FP_STR" already in list", NODE_ADDR_FP_ARGS_S(l_seed_node_addr)); + } else { + /* Either not yet added or must be altered */ + l_ret = dap_chain_node_info_save(l_net, &l_node_info); if (!l_ret) { - log_it(L_NOTICE,"Seed node "NODE_ADDR_FP_STR" already in list", NODE_ADDR_FP_ARGS_S(l_seed_node_addr)); + if (dap_chain_node_alias_register(l_net,l_net_pvt->seed_aliases[i], &l_seed_node_addr)) + log_it(L_NOTICE,"Seed node "NODE_ADDR_FP_STR" added to the curent list", NODE_ADDR_FP_ARGS_S(l_seed_node_addr)); + else + log_it(L_WARNING,"Cant register alias %s for address "NODE_ADDR_FP_STR, l_net_pvt->seed_aliases[i], NODE_ADDR_FP_ARGS_S(l_seed_node_addr)); } else { - /* Either not yet added or must be altered */ - l_ret = dap_chain_node_info_save(l_net, &l_node_info); - if (!l_ret) { - if (dap_chain_node_alias_register(l_net,l_net_pvt->seed_aliases[i], &l_seed_node_addr)) - log_it(L_NOTICE,"Seed node "NODE_ADDR_FP_STR" added to the curent list", NODE_ADDR_FP_ARGS_S(l_seed_node_addr)); - else - log_it(L_WARNING,"Cant register alias %s for address "NODE_ADDR_FP_STR, l_net_pvt->seed_aliases[i], NODE_ADDR_FP_ARGS_S(l_seed_node_addr)); - } else { - log_it(L_WARNING,"Cant save node info for address "NODE_ADDR_FP_STR" return code %d", NODE_ADDR_FP_ARGS_S(l_seed_node_addr), l_ret); - } + log_it(L_WARNING,"Cant save node info for address "NODE_ADDR_FP_STR" return code %d", NODE_ADDR_FP_ARGS_S(l_seed_node_addr), l_ret); } - } else - log_it(L_WARNING,"No address for seed node, can't populate global_db with it"); - DAP_DEL_Z(l_seed_node_addr_gdb); - DAP_DEL_Z(l_node_info_gdb); - } - - PVT(l_net)->bootstrap_nodes_count = 0; - PVT(l_net)->bootstrap_nodes_addrs = DAP_NEW_SIZE(struct in_addr, l_bootstrap_nodes_len * sizeof(struct in_addr)); - PVT(l_net)->bootstrap_nodes_ports = DAP_NEW_SIZE(uint16_t, l_bootstrap_nodes_len * sizeof(uint16_t)); - for (int i = 0; i < l_bootstrap_nodes_len; i++) { - char *l_bootstrap_port_str = strchr(l_bootstrap_nodes[i], ':'); - if (!l_bootstrap_port_str) { - continue; - } - uint16_t l_bootstrap_port = atoi(l_bootstrap_port_str + 1); - if (!l_bootstrap_port) { - continue; } - int l_bootstrap_name_len = l_bootstrap_port_str - l_bootstrap_nodes[i]; - char *l_bootstrap_name = DAP_NEW_SIZE(char, l_bootstrap_name_len + 1); - strncpy(l_bootstrap_name, l_bootstrap_nodes[i], l_bootstrap_name_len); - struct in_addr l_bootstrap_addr; - if (dap_net_resolve_host(l_bootstrap_name, AF_INET, (struct sockaddr* )&l_bootstrap_addr) == 0) { - PVT(l_net)->bootstrap_nodes_addrs[PVT(l_net)->bootstrap_nodes_count] = l_bootstrap_addr; - PVT(l_net)->bootstrap_nodes_ports[PVT(l_net)->bootstrap_nodes_count] = l_bootstrap_port; - PVT(l_net)->bootstrap_nodes_count++; - } - DAP_DELETE(l_bootstrap_name); + } else + log_it(L_WARNING,"No address for seed node, can't populate global_db with it"); + DAP_DEL_Z(l_seed_node_addr_gdb); + DAP_DEL_Z(l_node_info_gdb); + } + + PVT(l_net)->bootstrap_nodes_count = 0; + PVT(l_net)->bootstrap_nodes_addrs = DAP_NEW_SIZE(struct in_addr, l_bootstrap_nodes_len * sizeof(struct in_addr)); + PVT(l_net)->bootstrap_nodes_ports = DAP_NEW_SIZE(uint16_t, l_bootstrap_nodes_len * sizeof(uint16_t)); + for (int i = 0; i < l_bootstrap_nodes_len; i++) { + char *l_bootstrap_port_str = strchr(l_bootstrap_nodes[i], ':'); + if (!l_bootstrap_port_str) { + continue; } - if ( l_node_addr_str || l_node_alias_str ){ - dap_chain_node_addr_t * l_node_addr; - if ( l_node_addr_str == NULL) - l_node_addr = dap_chain_node_alias_find(l_net, l_node_alias_str); - else { - l_node_addr = DAP_NEW_Z(dap_chain_node_addr_t); - if (dap_chain_node_addr_from_str(l_node_addr, l_node_addr_str) == 0) - log_it(L_NOTICE, "Parse node addr "NODE_ADDR_FP_STR" successfully", NODE_ADDR_FP_ARGS(l_node_addr)); - else - DAP_DEL_Z(l_node_addr); - l_net_pvt->node_addr = l_node_addr; - } - if ( l_node_addr ) { - char *l_addr_hash_str = dap_chain_node_addr_to_hash_str(l_node_addr); - // save current node address - dap_db_set_cur_node_addr(l_node_addr->uint64, l_net->pub.name); - if(!l_addr_hash_str){ - log_it(L_ERROR,"Can't get hash string for node address!"); - } else { - l_net_pvt->node_info = dap_chain_node_info_read (l_net, l_node_addr); - if ( !l_net_pvt->node_info ) { // If not present - create it - l_net_pvt->node_info = DAP_NEW_Z(dap_chain_node_info_t); - l_net_pvt->node_info->hdr.address = *l_node_addr; - if (dap_config_get_item_bool_default(g_config,"server","enabled",false) ){ - const char * l_ext_addr_v4 = dap_config_get_item_str_default(g_config,"server","ext_address",NULL); - const char * l_ext_addr_v6 = dap_config_get_item_str_default(g_config,"server","ext_address6",NULL); - uint16_t l_ext_port = dap_config_get_item_uint16_default(g_config,"server","ext_port_tcp",0); - uint16_t l_node_info_port = l_ext_port ? l_ext_port : - dap_config_get_item_uint16_default(g_config,"server","listen_port_tcp",8089); - if (l_ext_addr_v4) - inet_pton(AF_INET,l_ext_addr_v4,&l_net_pvt->node_info->hdr.ext_addr_v4 ); - if (l_ext_addr_v6) - inet_pton(AF_INET6,l_ext_addr_v6,&l_net_pvt->node_info->hdr.ext_addr_v6 ); - l_net_pvt->node_info->hdr.ext_port =l_node_info_port; - log_it(L_INFO,"Server is enabled on %s:%u",l_ext_addr_v4?l_ext_addr_v4:"<none>", - l_node_info_port); - }else - log_it(L_INFO,"Server is disabled, add only node address in nodelist"); - if (l_net_pvt->node_info->hdr.ext_port && - (l_net_pvt->node_info->hdr.ext_addr_v4.s_addr != INADDR_ANY || - memcmp(&l_net_pvt->node_info->hdr.ext_addr_v6, &in6addr_any, sizeof(struct in6_addr)))) - // Save only info with non null address & port! - dap_chain_node_info_save(l_net,l_net_pvt->node_info); - } - log_it(L_NOTICE,"GDB Info: node_addr: " NODE_ADDR_FP_STR" links: %u cell_id: 0x%016"DAP_UINT64_FORMAT_X, - NODE_ADDR_FP_ARGS(l_node_addr), - l_net_pvt->node_info->hdr.links_number, - l_net_pvt->node_info->hdr.cell_id.uint64); + uint16_t l_bootstrap_port = atoi(l_bootstrap_port_str + 1); + if (!l_bootstrap_port) { + continue; + } + int l_bootstrap_name_len = l_bootstrap_port_str - l_bootstrap_nodes[i]; + char *l_bootstrap_name = DAP_NEW_SIZE(char, l_bootstrap_name_len + 1); + strncpy(l_bootstrap_name, l_bootstrap_nodes[i], l_bootstrap_name_len); + struct in_addr l_bootstrap_addr; + if (dap_net_resolve_host(l_bootstrap_name, AF_INET, (struct sockaddr* )&l_bootstrap_addr) == 0) { + PVT(l_net)->bootstrap_nodes_addrs[PVT(l_net)->bootstrap_nodes_count] = l_bootstrap_addr; + PVT(l_net)->bootstrap_nodes_ports[PVT(l_net)->bootstrap_nodes_count] = l_bootstrap_port; + PVT(l_net)->bootstrap_nodes_count++; + } + DAP_DELETE(l_bootstrap_name); + } + if ( l_node_addr_str || l_node_alias_str ){ + dap_chain_node_addr_t * l_node_addr; + if ( l_node_addr_str == NULL) + l_node_addr = dap_chain_node_alias_find(l_net, l_node_alias_str); + else { + l_node_addr = DAP_NEW_Z(dap_chain_node_addr_t); + if (dap_chain_node_addr_from_str(l_node_addr, l_node_addr_str) == 0) + log_it(L_NOTICE, "Parse node addr "NODE_ADDR_FP_STR" successfully", NODE_ADDR_FP_ARGS(l_node_addr)); + else + DAP_DEL_Z(l_node_addr); + l_net_pvt->node_addr = l_node_addr; + } + if ( l_node_addr ) { + char *l_addr_hash_str = dap_chain_node_addr_to_hash_str(l_node_addr); + // save current node address + dap_db_set_cur_node_addr(l_node_addr->uint64, l_net->pub.name); + if(!l_addr_hash_str){ + log_it(L_ERROR,"Can't get hash string for node address!"); + } else { + l_net_pvt->node_info = dap_chain_node_info_read (l_net, l_node_addr); + if ( !l_net_pvt->node_info ) { // If not present - create it + l_net_pvt->node_info = DAP_NEW_Z(dap_chain_node_info_t); + l_net_pvt->node_info->hdr.address = *l_node_addr; + if (dap_config_get_item_bool_default(g_config,"server","enabled",false) ){ + const char * l_ext_addr_v4 = dap_config_get_item_str_default(g_config,"server","ext_address",NULL); + const char * l_ext_addr_v6 = dap_config_get_item_str_default(g_config,"server","ext_address6",NULL); + uint16_t l_ext_port = dap_config_get_item_uint16_default(g_config,"server","ext_port_tcp",0); + uint16_t l_node_info_port = l_ext_port ? l_ext_port : + dap_config_get_item_uint16_default(g_config,"server","listen_port_tcp",8089); + if (l_ext_addr_v4) + inet_pton(AF_INET,l_ext_addr_v4,&l_net_pvt->node_info->hdr.ext_addr_v4 ); + if (l_ext_addr_v6) + inet_pton(AF_INET6,l_ext_addr_v6,&l_net_pvt->node_info->hdr.ext_addr_v6 ); + l_net_pvt->node_info->hdr.ext_port =l_node_info_port; + log_it(L_INFO,"Server is enabled on %s:%u",l_ext_addr_v4?l_ext_addr_v4:"<none>", + l_node_info_port); + }else + log_it(L_INFO,"Server is disabled, add only node address in nodelist"); + if (l_net_pvt->node_info->hdr.ext_port && + (l_net_pvt->node_info->hdr.ext_addr_v4.s_addr != INADDR_ANY || + memcmp(&l_net_pvt->node_info->hdr.ext_addr_v6, &in6addr_any, sizeof(struct in6_addr)))) + // Save only info with non null address & port! + dap_chain_node_info_save(l_net,l_net_pvt->node_info); } - DAP_DELETE(l_addr_hash_str); - } - else{ - log_it(L_WARNING, "Not present our own address %s in database", (l_node_alias_str) ? l_node_alias_str: ""); + log_it(L_NOTICE,"GDB Info: node_addr: " NODE_ADDR_FP_STR" links: %u cell_id: 0x%016"DAP_UINT64_FORMAT_X, + NODE_ADDR_FP_ARGS(l_node_addr), + l_net_pvt->node_info->hdr.links_number, + l_net_pvt->node_info->hdr.cell_id.uint64); } + DAP_DELETE(l_addr_hash_str); } + else{ + log_it(L_WARNING, "Not present our own address %s in database", (l_node_alias_str) ? l_node_alias_str: ""); + } + } + /* *** Chaiins init by configs *** */ + char * l_chains_path = dap_strdup_printf("%s/network/%s", dap_config_path(), l_net->pub.name); + DIR * l_chains_dir = opendir(l_chains_path); + DAP_DEL_Z(l_chains_path); + if (!l_chains_dir) { + log_it(L_ERROR, "Can't find any chains for network %s", l_net->pub.name); + l_net_pvt->load_mode = false; + return -2; + } + // for sequential loading chains + dap_list_t *l_prior_list = NULL; + struct dirent * l_dir_entry; + while ( (l_dir_entry = readdir(l_chains_dir) )!= NULL ){ + if (l_dir_entry->d_name[0]=='\0') + continue; + char * l_entry_name = strdup(l_dir_entry->d_name); + if (strlen (l_entry_name) > 4 ){ // It has non zero name excluding file extension + if ( strncmp (l_entry_name+ strlen(l_entry_name)-4,".cfg",4) == 0 ) { // its .cfg file + l_entry_name [strlen(l_entry_name)-4] = 0; + log_it(L_DEBUG,"Open chain config \"%s\"...",l_entry_name); + l_chains_path = dap_strdup_printf("network/%s/%s",l_net->pub.name,l_entry_name); + dap_config_t * l_cfg = dap_config_open(l_chains_path); + if(l_cfg) { + list_priority *l_chain_prior = DAP_NEW_Z(list_priority); + if (!l_chain_prior) { + log_it(L_ERROR, "Memory allocation error in s_net_init"); + DAP_DELETE (l_entry_name); + closedir(l_chains_dir); + dap_config_close(l_cfg); + return -1; + } + l_chain_prior->prior = dap_config_get_item_uint16_default(l_cfg, "chain", "load_priority", 100); + l_chain_prior->chains_path = l_chains_path; + // add chain to load list; + l_prior_list = dap_list_append(l_prior_list, l_chain_prior); + dap_config_close(l_cfg); + } + } + } + DAP_DELETE (l_entry_name); + } + closedir(l_chains_dir); + // sort list with chains names by priority + l_prior_list = dap_list_sort(l_prior_list, callback_compare_prioritity_list); - DAP_DELETE(l_node_addr_str); - dap_config_close(l_cfg); + // create and load chains params by priority + dap_chain_t *l_chain; + dap_list_t *l_list = l_prior_list; + while(l_list){ + list_priority *l_chain_prior = l_list->data; + // Create chain object + l_chain = dap_chain_load_from_cfg(l_net->pub.ledger, l_net->pub.name, + l_net->pub.id, l_chain_prior->chains_path); + if(l_chain) + DL_APPEND(l_net->pub.chains, l_chain); + else + log_it(L_WARNING, "Can't process chain from config %s", l_chain_prior->chains_path); + DAP_DELETE (l_chain_prior->chains_path); + l_list = dap_list_next(l_list); + } + dap_list_free_full(l_prior_list, NULL); + dap_chain_t *l_chain02; + DL_FOREACH(l_net->pub.chains, l_chain){ + DL_FOREACH(l_net->pub.chains, l_chain02){ + if (l_chain != l_chain02){ + if (l_chain->id.uint64 == l_chain02->id.uint64) { + log_it(L_ERROR, "Your network %s has chains with duplicate ids: 0x%"DAP_UINT64_FORMAT_U", chain01: %s, chain02: %s", l_chain->net_name, + l_chain->id.uint64, l_chain->name,l_chain02->name); + log_it(L_ERROR, "Please, fix your configs and restart node"); + return -2; + } + if (!dap_strcmp(l_chain->name, l_chain02->name)) { + log_it(L_ERROR, "Your network %s has chains with duplicate names %s: chain01 id = 0x%"DAP_UINT64_FORMAT_U", chain02 id = 0x%"DAP_UINT64_FORMAT_U"",l_chain->net_name, + l_chain->name, l_chain->id.uint64, l_chain02->id.uint64); + log_it(L_ERROR, "Please, fix your configs and restart node"); + return -2; + } + remove_duplicates_in_chain_by_priority(l_chain, l_chain02); + } + } } + // LEDGER model + uint16_t l_ledger_flags = 0; + switch ( PVT( l_net )->node_role.enums ) { + case NODE_ROLE_LIGHT: + break; + case NODE_ROLE_FULL: + l_ledger_flags |= DAP_CHAIN_LEDGER_CHECK_LOCAL_DS; + if (dap_config_get_item_bool_default(g_config, "ledger", "cache_enabled", true)) + l_ledger_flags |= DAP_CHAIN_LEDGER_CACHE_ENABLED; + default: + l_ledger_flags |= DAP_CHAIN_LEDGER_CHECK_CELLS_DS | DAP_CHAIN_LEDGER_CHECK_TOKEN_EMISSION; + } + dap_list_t *l_net_keys = NULL; + for (dap_chain_t *l_chain = l_net->pub.chains; l_chain; l_chain = l_chain->next) { + if (!l_chain->callback_get_poa_certs) + continue; + l_net_keys = l_chain->callback_get_poa_certs(l_chain, NULL, NULL); + if (l_net_keys) + break; + } + if (!l_net_keys) + log_it(L_WARNING,"PoA certificates for net %s not found.", l_net->pub.name); + // init LEDGER model + l_net->pub.ledger = dap_chain_ledger_create(l_ledger_flags, l_net->pub.name, l_net->pub.native_ticker, l_net_keys); + + DAP_DELETE(l_node_addr_str); + dap_config_close(l_cfg); return 0; } @@ -2580,128 +2747,47 @@ int s_net_load(dap_chain_net_t *a_net) } dap_chain_net_pvt_t * l_net_pvt = PVT(l_net); - char * l_chains_path = dap_strdup_printf("%s/network/%s", dap_config_path(), l_net->pub.name); - DIR * l_chains_dir = opendir(l_chains_path); - DAP_DEL_Z(l_chains_path); - if ( l_chains_dir ){ - // for sequential loading chains - dap_list_t *l_prior_list = NULL; - - struct dirent * l_dir_entry; - while ( (l_dir_entry = readdir(l_chains_dir) )!= NULL ){ - if (l_dir_entry->d_name[0]=='\0') - continue; - char * l_entry_name = strdup(l_dir_entry->d_name); - if (strlen (l_entry_name) > 4 ){ // It has non zero name excluding file extension - if ( strncmp (l_entry_name+ strlen(l_entry_name)-4,".cfg",4) == 0 ) { // its .cfg file - l_entry_name [strlen(l_entry_name)-4] = 0; - log_it(L_DEBUG,"Open chain config \"%s\"...",l_entry_name); - l_chains_path = dap_strdup_printf("network/%s/%s",l_net->pub.name,l_entry_name); - dap_config_t * l_cfg = dap_config_open(l_chains_path); - if(l_cfg) { - list_priority *l_chain_prior = DAP_NEW_Z(list_priority); - l_chain_prior->prior = dap_config_get_item_uint16_default(l_cfg, "chain", "load_priority", 100); - l_chain_prior->chains_path = l_chains_path; - // add chain to load list; - l_prior_list = dap_list_append(l_prior_list, l_chain_prior); - dap_config_close(l_cfg); - } - } - } - DAP_DELETE (l_entry_name); - } - closedir(l_chains_dir); - - // reload ledger cache at once - if (s_chain_net_reload_ledger_cache_once(l_net)) { - log_it(L_WARNING,"Start one time ledger cache reloading"); - dap_chain_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); - - // sort list with chains names by priority - l_prior_list = dap_list_sort(l_prior_list, callback_compare_prioritity_list); - - // create and load chains params by priority - dap_chain_t *l_chain; - dap_list_t *l_list = l_prior_list; - while(l_list){ - list_priority *l_chain_prior = l_list->data; - // Create chain object - l_chain = dap_chain_load_from_cfg(l_net->pub.ledger, l_net->pub.name, - l_net->pub.id, l_chain_prior->chains_path); - if(l_chain) { - DL_APPEND(l_net->pub.chains, l_chain); - - // add a callback to monitor changes in the chain - dap_chain_add_callback_notify(l_chain, s_chain_callback_notify, l_net); - } - DAP_DELETE (l_chain_prior->chains_path); - l_list = dap_list_next(l_list); + // reload ledger cache at once + if (s_chain_net_reload_ledger_cache_once(l_net)) { + log_it(L_WARNING,"Start one time ledger cache reloading"); + dap_chain_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); + + //load decree + dap_chain_net_decree_init(l_net); + // load chains + dap_chain_t *l_chain = l_net->pub.chains; + while(l_chain){ + l_chain->ledger = l_net->pub.ledger; + dap_chain_ledger_set_fee(l_net->pub.ledger, uint256_0, c_dap_chain_addr_blank); + if (dap_chain_load_all(l_chain) == 0) + log_it (L_NOTICE, "Loaded chain files"); + else { + dap_chain_save_all( l_chain ); + log_it (L_NOTICE, "Initialized chain files"); } - dap_list_free_full(l_prior_list, NULL); - - //load decree - dap_chain_net_decree_init(l_net); - // load chains - l_chain = l_net->pub.chains; - while(l_chain){ - dap_chain_ledger_set_fee(l_net->pub.ledger, uint256_0, c_dap_chain_addr_blank); - if (dap_chain_load_all(l_chain) == 0) - log_it (L_NOTICE, "Loaded chain files"); - else { - dap_chain_save_all( l_chain ); - log_it (L_NOTICE, "Initialized chain files"); - } - if(l_chain->callback_created) - l_chain->callback_created(l_chain, l_cfg); + if(l_chain->callback_created) + l_chain->callback_created(l_chain, l_cfg); - l_chain = l_chain->next; - } - - dap_chain_t *l_chain02; - DL_FOREACH(l_net->pub.chains, l_chain){ - DL_FOREACH(l_net->pub.chains, l_chain02){ - if (l_chain != l_chain02){ - if (l_chain->id.uint64 == l_chain02->id.uint64) - { - log_it(L_ERROR, "Your network %s has chains with duplicate ids: 0x%"DAP_UINT64_FORMAT_U", chain01: %s, chain02: %s", l_chain->net_name, - l_chain->id.uint64, l_chain->name,l_chain02->name); - log_it(L_ERROR, "Please, fix your configs and restart node"); - return -2; - } - if (!dap_strcmp(l_chain->name, l_chain02->name)) - { - log_it(L_ERROR, "Your network %s has chains with duplicate names %s: chain01 id = 0x%"DAP_UINT64_FORMAT_U", chain02 id = 0x%"DAP_UINT64_FORMAT_U"",l_chain->net_name, - l_chain->name, l_chain->id.uint64, l_chain02->id.uint64); - log_it(L_ERROR, "Please, fix your configs and restart node"); - return -2; - } - remove_duplicates_in_chain_by_priority(l_chain, l_chain02); + l_chain = l_chain->next; + } + // Process thresholds if any + bool l_processed; + do { + l_processed = false; + DL_FOREACH(l_net->pub.chains, l_chain) { + if (l_chain->callback_atom_add_from_treshold) { + while (l_chain->callback_atom_add_from_treshold(l_chain, NULL)) { + log_it(L_DEBUG, "Added atom from treshold"); + l_processed = true; } } } - - bool l_processed; - do { - l_processed = false; - DL_FOREACH(l_net->pub.chains, l_chain) { - if (l_chain->callback_atom_add_from_treshold) { - while (l_chain->callback_atom_add_from_treshold(l_chain, NULL)) { - log_it(L_DEBUG, "Added atom from treshold"); - l_processed = true; - } - } - } - } while (l_processed); - } else { - log_it(L_ERROR, "Can't find any chains for network %s", l_net->pub.name); - l_net_pvt->load_mode = false; - return -2; - } + } while (l_processed); // Do specific role actions post-chain created l_net_pvt->state_target = NET_STATE_OFFLINE; @@ -2711,7 +2797,8 @@ int s_net_load(dap_chain_net_t *a_net) case NODE_ROLE_ROOT_MASTER:{ // Set to process everything in datum pool dap_chain_t * l_chain = NULL; - DL_FOREACH(l_net->pub.chains, l_chain ) l_chain->is_datum_pool_proc = true; + DL_FOREACH(l_net->pub.chains, l_chain) + l_chain->is_datum_pool_proc = true; log_it(L_INFO,"Root master node role established"); } // Master root includes root case NODE_ROLE_ROOT:{ @@ -2765,8 +2852,9 @@ int s_net_load(dap_chain_net_t *a_net) l_net_pvt->balancer_http = !dap_config_get_item_bool_default(l_cfg, "general", "use_dns_links", false); dap_chain_net_add_gdb_notify_callback(l_net, dap_chain_net_sync_gdb_broadcast, l_net); - if (l_target_state != l_net_pvt->state_target) - dap_chain_net_state_go_to(l_net, l_target_state); + DL_FOREACH(l_net->pub.chains, l_chain) + // add a callback to monitor changes in the chain + dap_chain_add_callback_notify(l_chain, s_chain_callback_notify, l_net); uint32_t l_timeout = dap_config_get_item_uint32_default(g_config, "node_client", "timer_update_states", 600); PVT(l_net)->main_timer = dap_interval_timer_create(l_timeout * 1000, s_main_timer_callback, l_net); @@ -2775,6 +2863,9 @@ int s_net_load(dap_chain_net_t *a_net) dap_config_close(l_cfg); + if (l_target_state != l_net_pvt->state_target) + dap_chain_net_state_go_to(l_net, l_target_state); + return 0; } @@ -2803,6 +2894,11 @@ dap_chain_net_t **dap_chain_net_list(uint16_t *a_size) *a_size = HASH_COUNT(s_net_items); if(*a_size){ dap_chain_net_t **l_net_list = DAP_NEW_SIZE(dap_chain_net_t *, (*a_size) * sizeof(dap_chain_net_t *)); + if (!l_net_list) { + log_it(L_ERROR, "Memory allocation error in dap_chain_net_list"); + pthread_rwlock_unlock(&s_net_items_rwlock); + return NULL; + } dap_chain_net_item_t *l_current_item, *l_tmp; int i = 0; HASH_ITER(hh, s_net_items, l_current_item, l_tmp) { @@ -2810,8 +2906,8 @@ dap_chain_net_t **dap_chain_net_list(uint16_t *a_size) if(i > *a_size) break; } - return l_net_list; pthread_rwlock_unlock(&s_net_items_rwlock); + return l_net_list; } else { pthread_rwlock_unlock(&s_net_items_rwlock); return NULL; @@ -3067,10 +3163,15 @@ dap_list_t* dap_chain_net_get_link_node_list(dap_chain_net_t * l_net, bool a_is_ dap_chain_node_info_t *l_remote_node_info = dap_chain_node_info_read(l_net, l_remote_address); if(!l_remote_node_info || l_remote_node_info->hdr.cell_id.uint64 != l_cur_node_info->hdr.cell_id.uint64) l_is_add = false; - DAP_DELETE(l_remote_node_info); + if (l_remote_node_info) + DAP_DELETE(l_remote_node_info); } if(l_is_add) { dap_chain_node_addr_t *l_address = DAP_NEW(dap_chain_node_addr_t); + if (!l_address) { + log_it(L_ERROR, "Memory allocation error in dap_chain_net_get_link_node_list"); + return NULL; + } l_address->uint64 = l_cur_node_info->links[i].uint64; l_node_list = dap_list_append(l_node_list, l_address); } @@ -3105,6 +3206,10 @@ dap_list_t* dap_chain_net_get_node_list(dap_chain_net_t * l_net) for(size_t i = 0; i < l_nodes_count; i++) { dap_chain_node_info_t *l_node_info = (dap_chain_node_info_t *) l_objs[i].value; dap_chain_node_addr_t *l_address = DAP_NEW(dap_chain_node_addr_t); + if (!l_address) { + log_it(L_ERROR, "Memory allocation error in dap_chain_net_get_node_list"); + return NULL; + } l_address->uint64 = l_node_info->hdr.address.uint64; l_node_list = dap_list_append(l_node_list, l_address); } @@ -3213,18 +3318,15 @@ int dap_chain_net_verify_datum_for_add(dap_chain_t *a_chain, dap_chain_datum_t * char *dap_chain_net_verify_datum_err_code_to_str(dap_chain_datum_t *a_datum, int a_code){ switch (a_datum->header.type_id) { - case DAP_CHAIN_DATUM_TX: - return dap_chain_ledger_tx_check_err_str(a_code); - case DAP_CHAIN_DATUM_TOKEN_DECL: - return dap_chain_ledger_token_decl_add_err_code_to_str(a_code); - case DAP_CHAIN_DATUM_TOKEN_EMISSION: - return dap_chain_ledger_token_emission_err_code_to_str(a_code); - default: - if (a_code == 0) { - return dap_strdup("DAP_CHAIN_DATUM_VERIFY_OK"); - } else { - return dap_strdup_printf("Error code: %d", a_code); - } + case DAP_CHAIN_DATUM_TX: + return dap_chain_ledger_tx_check_err_str(a_code); + case DAP_CHAIN_DATUM_TOKEN_DECL: + return dap_chain_ledger_token_decl_add_err_code_to_str(a_code); + case DAP_CHAIN_DATUM_TOKEN_EMISSION: + return dap_chain_ledger_token_emission_err_code_to_str(a_code); + default: + return !a_code ? "DAP_CHAIN_DATUM_VERIFY_OK" : dap_itoa(a_code); + } } @@ -3240,8 +3342,7 @@ static bool s_net_check_acl(dap_chain_net_t *a_net, dap_chain_hash_fast_t *a_pke { const char l_path[] = "network/"; char l_cfg_path[strlen(a_net->pub.name) + strlen(l_path) + 1]; - strcpy(l_cfg_path, l_path); - strcat(l_cfg_path, a_net->pub.name); + dap_snprintf(l_cfg_path, sizeof(l_cfg_path), "%s%s", l_path, a_net->pub.name); dap_config_t *l_cfg = dap_config_open(l_cfg_path); const char *l_auth_type = dap_config_get_item_str(l_cfg, "auth", "type"); bool l_authorized = true; @@ -3308,6 +3409,11 @@ static uint8_t *s_net_set_acl(dap_chain_hash_fast_t *a_pkey_hash) dap_chain_net_t **l_net_list = dap_chain_net_list(&l_net_count); if (l_net_count && l_net_list) { uint8_t *l_ret = DAP_NEW_SIZE(uint8_t, l_net_count); + if (!l_ret) { + log_it(L_ERROR, "Memory allocation error in s_net_set_acl"); + DAP_DELETE(l_net_list); + return NULL; + } for (uint16_t i = 0; i < l_net_count; i++) { l_ret[i] = s_net_check_acl(l_net_list[i], a_pkey_hash); } @@ -3358,7 +3464,12 @@ dap_list_t* dap_chain_datum_list(dap_chain_net_t *a_net, dap_chain_t *a_chain, d */ l_sz = sizeof(dap_chain_datum_t) + l_datum->header.data_size + 16; l_datum2 = DAP_NEW_Z_SIZE(dap_chain_datum_t, l_sz); - assert ( l_datum2 ); + if (!l_datum2) { + log_it(L_ERROR, "Memory allocation in dap_chain_datum_list"); + DAP_DEL_Z(l_datums); + dap_list_free(l_list); + return NULL; + } memcpy(l_datum2, l_datum, l_sz); /* Add new entry into the list */ diff --git a/modules/net/dap_chain_net_balancer.c b/modules/net/dap_chain_net_balancer.c index b21a20d888ac507973645740b8642c05545fa5d4..50aefc9b428a99a76569ef8f66299112c3a3d381 100644 --- a/modules/net/dap_chain_net_balancer.c +++ b/modules/net/dap_chain_net_balancer.c @@ -81,6 +81,11 @@ dap_chain_node_info_t *dap_chain_net_balancer_get_node(const char *a_net_name) l_node_num = rand() % l_nodes_count; l_node_candidate = (dap_chain_node_info_t *)dap_list_nth_data(l_objs_list,l_node_num); dap_chain_node_info_t *l_node_info = DAP_NEW_Z(dap_chain_node_info_t); + if (!l_node_info) { + log_it(L_ERROR, "Memory allocation error in dap_chain_net_balancer_get_node"); + dap_list_free(l_objs_list); + return NULL; + } memcpy(l_node_info, l_node_candidate, sizeof(dap_chain_node_info_t)); dap_list_free(l_objs_list); return l_node_info; diff --git a/modules/net/dap_chain_net_decree.c b/modules/net/dap_chain_net_decree.c index a334887a54080d69e104c230cd89a922880f2d64..5ffef5faec7836da640164d993588a70278f5808 100644 --- a/modules/net/dap_chain_net_decree.c +++ b/modules/net/dap_chain_net_decree.c @@ -265,11 +265,15 @@ int dap_chain_net_decree_apply(dap_hash_fast_t *a_decree_hash, dap_chain_datum_d return -110; } if (l_decree_hh->is_applied) { - log_it(L_WARNING,"Decree already applyed"); + log_it(L_WARNING,"Decree already applied"); return -111; } } else { l_decree_hh = DAP_NEW_Z(struct decree_hh); + if (!l_decree_hh) { + log_it(L_ERROR, "Memory allocation error in dap_chain_net_decree_apply"); + return -1; + } l_decree_hh->decree = DAP_DUP_SIZE(a_decree, dap_chain_datum_decree_get_size(a_decree)); l_decree_hh->key = *a_decree_hash; HASH_ADD(hh, s_decree_hh, key, sizeof(dap_hash_fast_t), l_decree_hh); @@ -386,6 +390,10 @@ static int s_common_decree_handler(dap_chain_datum_decree_t * a_decree, dap_chai } } else{ dap_chain_addr_t *l_decree_addr = DAP_NEW_Z_SIZE(dap_chain_addr_t, sizeof(dap_chain_addr_t)); + if (!l_decree_addr) { + log_it(L_ERROR, "Memory allocation error in s_common_decree_handler"); + return -1; + } memcpy(l_decree_addr, &l_addr, sizeof(dap_chain_addr_t)); l_net->pub.decree->fee_addr = l_decree_addr; } diff --git a/modules/net/dap_chain_net_tx.c b/modules/net/dap_chain_net_tx.c index a3e7548543344b46b2066a04b520a9258aa5e748..40973efac8d31a1213bf8335ee351f625781cb3d 100644 --- a/modules/net/dap_chain_net_tx.c +++ b/modules/net/dap_chain_net_tx.c @@ -45,6 +45,10 @@ dap_chain_datum_tx_spends_items_t * dap_chain_net_get_tx_cond_all_with_spends_by { dap_ledger_t * l_ledger = a_net->pub.ledger; dap_chain_datum_tx_spends_items_t * l_ret = DAP_NEW_Z(dap_chain_datum_tx_spends_items_t); + if (!l_ret) { + log_it(L_ERROR, "Memory allocation error in dap_chain_net_get_tx_cond_all_with_spends_by_srv_uid"); + return NULL; + } switch (a_search_type) { case TX_SEARCH_TYPE_NET: @@ -113,6 +117,11 @@ dap_chain_datum_tx_spends_items_t * dap_chain_net_get_tx_cond_all_with_spends_by if (l_tx_prev_out_item){ // we found previous out_cond with target srv_uid dap_chain_datum_tx_spends_item_t *l_item_in = DAP_NEW_Z(dap_chain_datum_tx_spends_item_t); + if (!l_item_in) { + log_it(L_ERROR, "Memory allocation error in dap_chain_net_get_tx_cond_all_with_spends_by_srv_uid"); + DAP_DEL_Z(l_datums); + return NULL; + } size_t l_tx_size = dap_chain_datum_tx_get_size(l_tx); dap_chain_datum_tx_t * l_tx_dup = DAP_DUP_SIZE(l_tx,l_tx_size); dap_hash_fast(l_tx_dup,l_tx_size, &l_item_in->tx_hash); @@ -130,6 +139,11 @@ dap_chain_datum_tx_spends_items_t * dap_chain_net_get_tx_cond_all_with_spends_by dap_chain_tx_out_cond_t * l_tx_out_cond = (dap_chain_tx_out_cond_t *)l_item; if(l_tx_out_cond->header.srv_uid.uint64 == a_srv_uid.uint64){ dap_chain_datum_tx_spends_item_t * l_item = DAP_NEW_Z(dap_chain_datum_tx_spends_item_t); + if (!l_item) { + log_it(L_ERROR, "Memory allocation error in dap_chain_net_get_tx_cond_all_with_spends_by_srv_uid"); + DAP_DEL_Z(l_datums); + return NULL; + } size_t l_tx_size = dap_chain_datum_tx_get_size(l_tx); dap_chain_datum_tx_t * l_tx_dup = DAP_DUP_SIZE(l_tx,l_tx_size); dap_hash_fast(l_tx,l_tx_size, &l_item->tx_hash); @@ -316,6 +330,10 @@ static void s_get_tx_cond_chain_callback(dap_chain_net_t* a_net, dap_chain_datum dap_list_t * dap_chain_net_get_tx_cond_chain(dap_chain_net_t * a_net, dap_hash_fast_t * a_tx_hash, dap_chain_net_srv_uid_t a_srv_uid) { struct get_tx_cond_all_from_tx * l_args = DAP_NEW_Z(struct get_tx_cond_all_from_tx); + if (!l_args) { + log_it (L_ERROR, "Memory allocation error in dap_chain_net_get_tx_cond_all_for_addr"); + return NULL; + } l_args->tx_begin_hash = a_tx_hash; l_args->srv_uid = a_srv_uid; dap_chain_net_get_tx_all(a_net,TX_SEARCH_TYPE_NET,s_get_tx_cond_chain_callback, l_args); @@ -430,6 +448,10 @@ static void s_get_tx_cond_all_for_addr_callback(dap_chain_net_t* a_net, dap_chai dap_list_t * dap_chain_net_get_tx_cond_all_for_addr(dap_chain_net_t * a_net, dap_chain_addr_t * a_addr, dap_chain_net_srv_uid_t a_srv_uid) { struct get_tx_cond_all_for_addr * l_args = DAP_NEW_Z(struct get_tx_cond_all_for_addr); + if (!l_args) { + log_it (L_ERROR, "Memory allocation error in dap_chain_net_get_tx_cond_all_for_addr"); + return NULL; + } l_args->addr = a_addr; l_args->srv_uid = a_srv_uid; dap_chain_net_get_tx_all(a_net,TX_SEARCH_TYPE_NET,s_get_tx_cond_all_for_addr_callback, l_args); diff --git a/modules/net/dap_chain_node.c b/modules/net/dap_chain_node.c index b7eabde8dc274e538785639794edc1f723b85291..b646c2bf116cf3f8f940ac2884e78566ca6c0055 100644 --- a/modules/net/dap_chain_node.c +++ b/modules/net/dap_chain_node.c @@ -55,6 +55,10 @@ dap_chain_node_addr_t* dap_chain_node_gen_addr(dap_chain_net_id_t a_net_id) { dap_chain_node_addr_t *l_addr = DAP_NEW_Z(dap_chain_node_addr_t); + if (!l_addr) { + log_it(L_ERROR, "Memory allocation error in dap_chain_node_gen_addr"); + return NULL; + } dap_chain_hash_fast_t l_hash; dap_hash_fast(&a_net_id, sizeof(dap_chain_net_id_t), &l_hash); // first 4 bytes is last 4 bytes of shard id hash @@ -257,19 +261,25 @@ void dap_chain_node_mempool_process_all(dap_chain_t *a_chain, bool a_force) if (l_datum->header.type_id == DAP_CHAIN_DATUM_TX && a_chain->callback_get_minimum_fee){ uint256_t l_tx_fee = {}; - if (dap_chain_datum_tx_get_fee_value ((dap_chain_datum_tx_t*)l_datum->data, &l_tx_fee)) { - log_it(L_WARNING, "Can't get fee value from tx"); - continue; - } - uint256_t l_min_fee = a_chain->callback_get_minimum_fee(a_chain); - if (compare256(l_tx_fee, l_min_fee) < 0) { - char *l_tx_fee_str = dap_chain_balance_to_coins(l_tx_fee); - char *l_min_fee_str = dap_chain_balance_to_coins(l_min_fee); - log_it(L_WARNING, "Fee %s is lower than minimum fee %s for tx %s", - l_tx_fee_str, l_min_fee_str, l_objs[i].key); - DAP_DELETE(l_tx_fee_str); - DAP_DELETE(l_min_fee_str); - continue; + dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *)l_datum->data; + if (dap_chain_datum_tx_get_fee_value (l_tx, &l_tx_fee) || + IS_ZERO_256(l_tx_fee)) { + if (!dap_chain_ledger_tx_poa_signed(l_net->pub.ledger, l_tx)) { + log_it(L_WARNING, "Can't get fee value from tx %s", l_objs[i].key); + continue; + } else + log_it(L_DEBUG, "Process service tx without fee"); + } else { + uint256_t l_min_fee = a_chain->callback_get_minimum_fee(a_chain); + if (compare256(l_tx_fee, l_min_fee) < 0) { + char *l_tx_fee_str = dap_chain_balance_to_coins(l_tx_fee); + char *l_min_fee_str = dap_chain_balance_to_coins(l_min_fee); + log_it(L_WARNING, "Fee %s is lower than minimum fee %s for tx %s", + l_tx_fee_str, l_min_fee_str, l_objs[i].key); + DAP_DELETE(l_tx_fee_str); + DAP_DELETE(l_min_fee_str); + continue; + } } } diff --git a/modules/net/dap_chain_node_cli.c b/modules/net/dap_chain_node_cli.c index 314bd2dcedd970e0103ee1c936d7da709ba74af7..401368f0ef9f664e157490eaa195098ff62314f9 100644 --- a/modules/net/dap_chain_node_cli.c +++ b/modules/net/dap_chain_node_cli.c @@ -87,6 +87,9 @@ int dap_chain_node_cli_init(dap_config_t * g_config) "global_db write -group <group_name> -key <key_name> -value <value>" "global_db read -group <group_name> -key <key_name>" "global_db delete -group <group_name> -key <key_name>" + "global_db drop_table -group <group_name>\n" + "global_db get_keys -group <group name>" + // "global_db wallet_info set -addr <wallet address> -cell <cell id> \n\n" ); dap_cli_server_cmd_add("mempool", com_signer, "Sign operations", @@ -123,7 +126,7 @@ int dap_chain_node_cli_init(dap_config_t * g_config) ); dap_cli_server_cmd_add ("wallet", com_tx_wallet, "Wallet operations", "wallet list\n" - "wallet new -w <wallet_name> [-sign <sign_type>] [-restore <hex_value>] [-net <net_name>] [-force] [-password <password>] [-restore <hash>]\n" + "wallet new -w <wallet_name> [-sign <sign_type>] [-restore <hex_value> | -restore_legacy <restore_string>] [-net <net_name>] [-force] [-password <password>]\n" "wallet info {-addr <addr> | -w <wallet_name>} -net <net_name>\n" "wallet activate -w <wallet_name> -password <password> [-ttl <password_ttl_in_minutes>]\n" "wallet deactivate -w <wallet_name> -password <password>\n" @@ -273,7 +276,7 @@ int dap_chain_node_cli_init(dap_config_t * g_config) // Transaction commands dap_cli_server_cmd_add ("tx_create", com_tx_create, "Make transaction", "tx_create -net <net_name> -chain <chain_name> -value <value> -token <token_ticker> -to_addr <addr>" - "{-from_wallet <wallet_name> | -from_emission <emission_hash> {-certs <cert list> | -wallet_fee <wallet_name>}} -fee <value>\n"); + "{-from_wallet <wallet_name> | -from_emission <emission_hash> {-cert <cert_name> | -wallet_fee <wallet_name>}} -fee <value>\n"); dap_cli_server_cmd_add ("tx_create_json", com_tx_create_json, "Make transaction", "tx_create_json -net <net_name> -chain <chain_name> -json <json_file_path>\n" ); dap_cli_server_cmd_add ("tx_cond_create", com_tx_cond_create, "Make cond transaction", diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c index a8e1cb47ec395a0294dd945b0959ba2623b09ba7..f6668b1cf5984cde97583233b0aa600051d08fd8 100644 --- a/modules/net/dap_chain_node_cli_cmd.c +++ b/modules/net/dap_chain_node_cli_cmd.c @@ -187,6 +187,10 @@ static dap_chain_node_addr_t* s_node_info_get_addr(dap_chain_net_t * a_net, dap_ } if(a_addr->uint64) { l_address = DAP_NEW(dap_chain_node_addr_t); + if (!l_address) { + log_it(L_ERROR, "Memory allocation error in s_node_info_get_addr"); + return NULL; + } l_address->uint64 = a_addr->uint64; } return l_address; @@ -536,19 +540,20 @@ static int node_info_dump_with_reply(dap_chain_net_t * a_net, dap_chain_node_add dap_chain_node_addr_t *l_addr = NULL; if(a_addr && a_addr->uint64) { l_addr = DAP_NEW(dap_chain_node_addr_t); + if(!l_addr) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "addr not valid"); + dap_string_free(l_string_reply, true); + return -1; + } l_addr->uint64 = a_addr->uint64; } else if(a_alias) { l_addr = dap_chain_node_alias_find(a_net, a_alias); } - if(!l_addr) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "addr not valid"); - dap_string_free(l_string_reply, true); - return -1; - } + // read node dap_chain_node_info_t *node_info_read = node_info_read_and_reply(a_net, l_addr, a_str_reply); if(!node_info_read) { - DAP_DELETE(l_addr); + DAP_DEL_Z(l_addr); dap_string_free(l_string_reply, true); return -2; } @@ -730,7 +735,7 @@ static int node_info_dump_with_reply(dap_chain_net_t * a_net, dap_chain_node_add int com_global_db(int a_argc, char ** a_argv, char **a_str_reply) { enum { - CMD_NONE, CMD_NAME_CELL, CMD_ADD, CMD_FLUSH, CMD_RECORD, CMD_WRITE, CMD_READ, CMD_DELETE + CMD_NONE, CMD_NAME_CELL, CMD_ADD, CMD_FLUSH, CMD_RECORD, CMD_WRITE, CMD_READ, CMD_DELETE, CMD_DROP, CMD_GET_KEYS }; int arg_index = 1; int cmd_name = CMD_NONE; @@ -747,6 +752,11 @@ int com_global_db(int a_argc, char ** a_argv, char **a_str_reply) cmd_name = CMD_READ; else if(dap_cli_server_cmd_find_option_val(a_argv, arg_index, MIN(a_argc, arg_index + 1), "delete", NULL)) cmd_name = CMD_DELETE; + else if(dap_cli_server_cmd_find_option_val(a_argv, arg_index, min(a_argc, arg_index + 1), "drop_table", NULL)) + cmd_name = CMD_DROP; + else if(dap_cli_server_cmd_find_option_val(a_argv, arg_index, min(a_argc, arg_index + 1), "get_keys", NULL)) + cmd_name = CMD_GET_KEYS; + switch (cmd_name) { case CMD_NAME_CELL: { @@ -930,100 +940,164 @@ int com_global_db(int a_argc, char ** a_argv, char **a_str_reply) return l_ret; } case CMD_WRITE: - { - const char *l_group_str = NULL; - const char *l_key_str = NULL; - const char *l_value_str = NULL; + { + const char *l_group_str = NULL; + const char *l_key_str = NULL; + const char *l_value_str = NULL; - dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-group", &l_group_str); - dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-key", &l_key_str); - dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-value", &l_value_str); + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-group", &l_group_str); + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-key", &l_key_str); + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-value", &l_value_str); - if(!l_group_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "%s requires parameter 'group' to be valid", a_argv[0]); - return -120; - } + if(!l_group_str) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "%s requires parameter 'group' to be valid", a_argv[0]); + return -120; + } - if(!l_key_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "%s requires parameter 'key' to be valid", a_argv[0]); - return -121; - } + if(!l_key_str) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "%s requires parameter 'key' to be valid", a_argv[0]); + return -121; + } - if(!l_value_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "%s requires parameter 'value' to be valid", a_argv[0]); - return -122; - } + if(!l_value_str) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "%s requires parameter 'value' to be valid", a_argv[0]); + return -122; + } - if (dap_global_db_set(l_group_str, l_key_str, l_value_str, strlen(l_value_str), false, NULL, NULL)) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Data has been successfully written to the database"); - return 0; - } else { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Data writing is failed"); - return -124; - } + if (!dap_global_db_set_sync(l_group_str, l_key_str, l_value_str, strlen(l_value_str) +1 , false)) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Data has been successfully written to the database"); + return 0; + } else { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Data writing is failed"); + return -124; + } + + } + case CMD_READ: + { + const char *l_group_str = NULL; + const char *l_key_str = NULL; + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-group", &l_group_str); + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-key", &l_key_str); + + if(!l_group_str) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "%s requires parameter 'group' to be valid", a_argv[0]); + return -120; + } + + if(!l_key_str) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "%s requires parameter 'key' to be valid", a_argv[0]); + return -122; } - case CMD_READ: + + size_t l_out_len = 0; + uint8_t *l_value_out = dap_global_db_get_sync(l_group_str, l_key_str, &l_out_len, NULL, NULL); + + if (!l_value_out || !l_out_len) { - const char *l_group_str = NULL; - const char *l_key_str = NULL; + dap_cli_server_cmd_set_reply_text(a_str_reply, "Record with key %s in group %s not found", l_key_str, l_group_str); + return -121; + } - dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-group", &l_group_str); - dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-key", &l_key_str); + dap_cli_server_cmd_set_reply_text(a_str_reply, "Group %s, key %s, data:\n %s", l_group_str, l_key_str, (char*)l_value_out); + return 0; + } + case CMD_DELETE: + { + const char *l_group_str = NULL; + const char *l_key_str = NULL; - if(!l_group_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "%s requires parameter 'group' to be valid", a_argv[0]); - return -120; - } + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-group", &l_group_str); + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-key", &l_key_str); - if(!l_key_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "%s requires parameter 'key' to be valid", a_argv[0]); - return -122; - } + if(!l_group_str) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "%s requires parameter 'group' to be valid", a_argv[0]); + return -120; + } - size_t l_out_len = 0; - uint8_t *l_value_out = dap_global_db_get_sync(l_group_str, l_key_str, &l_out_len, NULL, NULL); + if(!l_key_str) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "No key provided, entire table %s will be altered", l_group_str); + size_t l_objs_count = 0; + dap_global_db_obj_t* l_obj = dap_global_db_get_all_sync(l_group_str, &l_objs_count); - if (!l_value_out || !l_out_len) + if (!l_obj || !l_objs_count) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Record with key %s in group %s not found", l_key_str, l_group_str); - return -121; + dap_cli_server_cmd_set_reply_text(a_str_reply, "No data in group %s.", l_group_str); + return -124; + } + size_t i, j = 0; + for (i = 0; i < l_objs_count; ++i) { + if (!l_obj[i].key) + continue; + if (!dap_global_db_del_sync(l_group_str, l_obj[i].key)) { + ++j; + } } + dap_global_db_objs_delete(l_obj, l_objs_count); + dap_cli_server_cmd_set_reply_text(a_str_reply, "Removed %lu of %lu records in table %s", j, i, l_group_str); + return 0; + } - dap_cli_server_cmd_set_reply_text(a_str_reply, "Group %s, key %s, data:\n %s", l_group_str, l_key_str, (char*)l_value_out); + if (dap_global_db_del(l_group_str, l_key_str, NULL, NULL)) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Record with key %s in group %s was deleted successfuly", l_key_str, l_group_str); return 0; + } else { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Record with key %s in group %s deleting failed", l_group_str, l_key_str); + return -122; } - case CMD_DELETE: - { - const char *l_group_str = NULL; - const char *l_key_str = NULL; + } + case CMD_DROP: + { + const char *l_group_str = NULL; + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-group", &l_group_str); - dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-group", &l_group_str); - dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-key", &l_key_str); + if(!l_group_str) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "%s requires parameter 'group' to be valid", a_argv[0]); + return -120; + } - if(!l_group_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "%s requires parameter 'group' to be valid", a_argv[0]); - return -120; - } + if (!dap_global_db_del_sync(l_group_str, NULL)) + { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Dropped table %s", l_group_str); + return 0; + } else { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Failed to drop table %s", l_group_str); + return -122; + } + } + case CMD_GET_KEYS: + { + const char *l_group_str = NULL; + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-group", &l_group_str); - if(!l_key_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "%s requires parameter 'key' to be valid", a_argv[0]); - return -121; - } + if(!l_group_str) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "%s requires parameter 'group' to be valid", a_argv[0]); + return -120; + } - if (dap_global_db_del(l_group_str, l_key_str, NULL, NULL)) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Record with key %s in group %s was deleted successfuly", l_key_str, l_group_str); - return 0; - } else { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Record with key %s in group %s deleting failed", l_group_str, l_key_str); - return -122; - } - } + size_t l_objs_count = 0; + dap_global_db_obj_t* l_obj = dap_global_db_get_all_sync(l_group_str, &l_objs_count); + + if (!l_obj || !l_objs_count) + { + dap_cli_server_cmd_set_reply_text(a_str_reply, "No data in group %s.", l_group_str); + return -124; + } + + dap_string_t *l_ret_str = dap_string_new(NULL); + for(size_t i = 0; i < l_objs_count; i++){ + dap_string_append_printf(l_ret_str, "%s\n", l_obj[i].key); + } + + dap_cli_server_cmd_set_reply_text(a_str_reply, "Keys list for group %s:\n%s\n", l_group_str, l_ret_str->str); + dap_string_free(l_ret_str, true); + return 0; + } default: dap_cli_server_cmd_set_reply_text(a_str_reply, "parameters are not valid"); return -1; } - return -555; } /** @@ -1924,7 +1998,10 @@ char l_buf[1024]; case CMD_WALLET_NEW: { dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-password", &l_pass_str); dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-sign", &l_sign_type_str); - dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-restore", &l_restore_str); + int l_restore_opt = dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-restore", &l_restore_str); + int l_restore_legacy_opt = 0; + if (!l_restore_str) + l_restore_legacy_opt = dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-restore_legacy", &l_restore_str); // rewrite existing wallet int l_is_force = dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-force", NULL); @@ -1969,9 +2046,26 @@ char l_buf[1024]; if (l_sign_type.type == SIG_TYPE_TESLA) return dap_cli_server_cmd_set_reply_text(a_str_reply, "Tesla algorithm is no longer supported, please, use another variant"), -1; + uint8_t *l_seed = NULL; + size_t l_seed_size = 0, l_restore_str_size = dap_strlen(l_restore_str); + + if(l_restore_opt || l_restore_legacy_opt) { + if (l_restore_str_size > 3 && !dap_strncmp(l_restore_str, "0x", 2) && (!dap_is_hex_string(l_restore_str + 2, l_restore_str_size - 2) || l_restore_legacy_opt)) { + l_seed_size = (l_restore_str_size - 2) / 2; + l_seed = DAP_NEW_SIZE(uint8_t, l_seed_size); + dap_hex2bin(l_seed, l_restore_str + 2, l_restore_str_size - 2); + if (l_restore_legacy_opt) { + dap_string_append_printf(l_l_string_ret, "CAUTION!!! CAUTION!!! CAUTION!!!\nYour wallet has a low level of protection. Please create a new wallet again with the option -restore\n"); + } + } else { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Restored hash is invalid or too short, wallet is not created. Please use -restore 0x<hex_value> or -restore_legacy 0x<restore_string>"); + return -1; + } + } + // Creates new wallet dap_chain_wallet_t *l_wallet = dap_chain_wallet_create_with_seed(l_wallet_name, c_wallets_path, l_sign_type, - l_restore_str, dap_strlen(l_restore_str), l_pass_str); + l_seed, l_seed_size, l_pass_str); if (!l_wallet) return dap_cli_server_cmd_set_reply_text(a_str_reply, "Wallet is not created because of internal error"), -1; @@ -2937,37 +3031,62 @@ int com_mempool_check(int a_argc, char **a_argv, char ** a_str_reply) l_datum_hash_hex_str = dap_enc_base58_to_hex_str_from_str(l_datum_hash_str); } else l_datum_hash_hex_str = dap_strdup(l_datum_hash_str); - if (l_chain) { - dap_chain_datum_t *l_datum = s_com_mempool_check_datum_in_chain(l_chain, l_datum_hash_hex_str); - DAP_DELETE(l_datum_hash_hex_str); - if (l_datum) { - dap_string_t *l_str_reply = dap_string_new(""); - dap_string_append_printf(l_str_reply, "Datum %s is present in mempool\n", l_datum_hash_str); - dap_chain_datum_dump(l_str_reply, l_datum, l_hash_out_type); - DAP_DELETE(l_datum); - *a_str_reply = l_str_reply->str; - dap_string_free(l_str_reply, false); - return 0; - } else { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find datum %s in %s.%s", l_datum_hash_str, l_net->pub.name, l_chain->name); + dap_chain_datum_t *l_datum = NULL; + char *l_chain_name = l_chain ? l_chain->name : NULL; + bool l_found_in_chains = false; + int l_ret_code = 0; + dap_hash_fast_t l_atom_hash = {}; + if (l_chain) + l_datum = s_com_mempool_check_datum_in_chain(l_chain, l_datum_hash_hex_str); + else { + dap_chain_t *it = NULL; + DL_FOREACH(l_net->pub.chains, it) { + l_datum = s_com_mempool_check_datum_in_chain(it, l_datum_hash_hex_str); + if (l_datum) { + l_chain_name = it->name; + break; + } + } + } + if (!l_datum) { + l_found_in_chains = true; + dap_hash_fast_t l_datum_hash; + if (dap_chain_hash_fast_from_hex_str(l_datum_hash_hex_str, &l_datum_hash)) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Incorrect hash string %s", l_datum_hash_str); return -4; } - } else { - DL_FOREACH(l_net->pub.chains, l_chain) { - dap_chain_datum_t *l_datum = s_com_mempool_check_datum_in_chain(l_chain, l_datum_hash_hex_str); - if (l_datum) { - DAP_DELETE(l_datum_hash_hex_str); - dap_string_t *l_str_reply = dap_string_new(""); - dap_string_append_printf(l_str_reply, "Datum %s is present in mempool\n", l_datum_hash_str); - dap_chain_datum_dump(l_str_reply, l_datum, l_hash_out_type); - DAP_DELETE(l_datum); - *a_str_reply = l_str_reply->str; - dap_string_free(l_str_reply, false); - return 0; + if (l_chain) + l_datum = l_chain->callback_datum_find_by_hash(l_chain, &l_datum_hash, &l_atom_hash, &l_ret_code); + else { + dap_chain_t *it = NULL; + DL_FOREACH(l_net->pub.chains, it) { + l_datum = it->callback_datum_find_by_hash(it, &l_datum_hash, &l_atom_hash, &l_ret_code); + if (l_datum) { + l_chain_name = it->name; + break; + } } } - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find datum %s in net %s", l_datum_hash_str, l_net->pub.name); - DAP_DEL_Z(l_datum_hash_hex_str); + } + DAP_DELETE(l_datum_hash_hex_str); + if (l_datum) { + dap_string_t *l_str_reply = dap_string_new(""); + dap_string_append_printf(l_str_reply, "Datum %s is present in %s.%s\n", l_datum_hash_str, + l_found_in_chains ? "chains" : "mempool", l_chain_name); + if (l_found_in_chains) { + char l_atom_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; + dap_chain_hash_fast_to_str(&l_atom_hash, l_atom_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE); + dap_string_append_printf(l_str_reply, "Atom hash is %s return code is %d (%s)\n", + l_atom_hash_str, l_ret_code, dap_chain_ledger_tx_check_err_str(l_ret_code)); + } + dap_chain_datum_dump(l_str_reply, l_datum, l_hash_out_type); + if (!l_found_in_chains) + DAP_DELETE(l_datum); + *a_str_reply = l_str_reply->str; + dap_string_free(l_str_reply, false); + return 0; + } else { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find datum %s in %s.%s", l_datum_hash_str, l_net->pub.name, l_chain ? l_chain->name : ""); return -4; } } else { @@ -3067,10 +3186,8 @@ int com_mempool_proc(int a_argc, char **a_argv, char **a_str_reply) dap_ctime_r(&l_ts_create, buf), l_datum->header.data_size); int l_verify_datum = dap_chain_net_verify_datum_for_add(l_chain, l_datum, &l_datum_hash) ; if (l_verify_datum != 0){ - char *l_err_verify_datum_str = dap_chain_net_verify_datum_err_code_to_str(l_datum, l_verify_datum); dap_string_append_printf(l_str_tmp, "Error! Datum doesn't pass verifications (%s) examine node log files", - l_err_verify_datum_str); - DAP_DELETE(l_err_verify_datum_str); + dap_chain_net_verify_datum_err_code_to_str(l_datum, l_verify_datum)); ret = -9; } else { if (l_chain->callback_add_datums) { @@ -5112,9 +5229,9 @@ int com_tx_create(int a_argc, char **a_argv, char **a_str_reply) const char * l_emission_chain_name = NULL; const char * l_tx_num_str = NULL; const char *l_emission_hash_str = NULL; - const char *l_certs_str = NULL; - dap_cert_t **l_certs = NULL; - size_t l_certs_count = 0; + const char *l_cert_str = NULL; + dap_cert_t *l_cert = NULL; + dap_enc_key_t *l_priv_key = NULL; dap_chain_hash_fast_t l_emission_hash = {}; size_t l_tx_num = 0; dap_chain_wallet_t * l_wallet_fee = NULL; @@ -5139,7 +5256,7 @@ int com_tx_create(int a_argc, char **a_argv, char **a_str_reply) dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-net", &l_net_name); dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-chain", &l_chain_name); dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-tx_num", &l_tx_num_str); - dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-certs", &l_certs_str); + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-cert", &l_cert_str); if(l_tx_num_str) l_tx_num = strtoul(l_tx_num_str, NULL, 10); @@ -5152,9 +5269,9 @@ int com_tx_create(int a_argc, char **a_argv, char **a_str_reply) } // Validator's fee - if(dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-fee", &str_tmp)) + if (dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-fee", &str_tmp)) l_value_fee = dap_chain_balance_scan(str_tmp); - if (IS_ZERO_256(l_value_fee)) { + if (IS_ZERO_256(l_value_fee) && (!l_emission_hash_str || (str_tmp && strcmp(str_tmp, "0")))) { dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_create requires parameter '-fee' to be valid uint256"); return -5; @@ -5211,36 +5328,24 @@ int com_tx_create(int a_argc, char **a_argv, char **a_str_reply) return -9; } - const char *l_native_ticker = l_net->pub.native_ticker; - bool not_native = dap_strcmp(l_token_ticker, l_native_ticker); - - if (not_native) { - if (l_wallet_fee_name){ - l_wallet_fee = dap_chain_wallet_open(l_wallet_fee_name, c_wallets_path); - if (!l_wallet_fee) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "wallet %s does not exist", l_wallet_fee_name); - return -12; - } - } else { - dap_cli_server_cmd_set_reply_text(a_str_reply, "To create a basic transaction with a " - "non-native ticker, you must specify the '-wallet_fee' " - "parameter. It is required to pay a commission for the " - "transaction."); - return -11; + if (l_wallet_fee_name){ + l_wallet_fee = dap_chain_wallet_open(l_wallet_fee_name, c_wallets_path); + if (!l_wallet_fee) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Wallet %s does not exist", l_wallet_fee_name); + return -12; } - } else { - if (l_certs_str) { - dap_cert_parse_str_list(l_certs_str, &l_certs, &l_certs_count); - if (!l_certs_count) { - dap_cli_server_cmd_set_reply_text(a_str_reply, - "tx_create requires at least one valid certificate to sign the basic transaction of emission"); - return -5; - } - } else { - dap_cli_server_cmd_set_reply_text(a_str_reply, - "tx_create requires parameter '-certs' for create base tx for emission in native token"); - return -10; + l_priv_key = dap_chain_wallet_get_key(l_wallet_fee, 0); + } else if (l_cert_str) { + l_cert = dap_cert_find_by_name(l_cert_str); + if (!l_cert) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Certificate %s is invalid", l_cert_str); + return -5; } + l_priv_key = l_cert->enc_key; + } else { + dap_cli_server_cmd_set_reply_text(a_str_reply, + "tx_create requires parameter '-cert' or '-wallet' for create base tx for emission"); + return -10; } } @@ -5266,17 +5371,15 @@ int com_tx_create(int a_argc, char **a_argv, char **a_str_reply) dap_string_t *l_string_ret = dap_string_new(NULL); int res = 0; if (l_emission_hash_str) { - bool not_native = dap_strcmp(l_token_ticker, l_net->pub.native_ticker); char *l_tx_hash_str = NULL; - if (not_native) { - l_tx_hash_str = dap_chain_mempool_base_tx_create(l_chain, &l_emission_hash, l_emission_chain->id, - l_value, l_token_ticker,dap_chain_wallet_get_key(l_wallet_fee, 0), l_addr_to, NULL, - 0, l_hash_out_type,l_value_fee); - } else { - l_tx_hash_str = dap_chain_mempool_base_tx_create(l_chain, &l_emission_hash, l_emission_chain->id, - l_value, l_token_ticker,NULL, l_addr_to, l_certs, - l_certs_count, l_hash_out_type,l_value_fee); - } + if (!l_priv_key) { + dap_string_append_printf(l_string_ret, "No private key defined for creating the underlying " + "transaction no '-wallet_fee' or ' -cert' parameter specified."); + res = -10; + } + l_tx_hash_str = dap_chain_mempool_base_tx_create(l_chain, &l_emission_hash, l_emission_chain->id, + l_value, l_token_ticker, l_addr_to, l_priv_key, + l_hash_out_type, l_value_fee); if (l_tx_hash_str) { dap_string_append_printf(l_string_ret, "\nDatum %s with 256bit TX is placed in datum pool\n", l_tx_hash_str); DAP_DELETE(l_tx_hash_str); @@ -5288,6 +5391,7 @@ int com_tx_create(int a_argc, char **a_argv, char **a_str_reply) dap_string_free(l_string_ret, true); DAP_DELETE(l_addr_to); dap_chain_wallet_close(l_wallet_fee); + DAP_DEL_Z(l_cert); return res; } @@ -5957,6 +6061,11 @@ int cmd_remove(int a_argc, char **a_argv, char ** a_str_reply) for (uint16_t i = 0; i < l_net_count; i++) { size_t l_aliases_count = 0; _pvt_net_aliases_list_t *l_gdb_groups = DAP_NEW(_pvt_net_aliases_list_t); + if (!l_gdb_groups) { + log_it(L_ERROR, "Memory allocation error in cmd_remove"); + dap_list_free(l_net_returns); + return -1; + } l_gdb_groups->net = l_net_list[i]; l_gdb_groups->group_aliases = dap_global_db_get_all_sync(l_gdb_groups->net->pub.gdb_nodes_aliases, &l_gdb_groups->count_aliases); l_gdb_groups->group_nodes = dap_global_db_get_all_sync(l_gdb_groups->net->pub.gdb_nodes, &l_gdb_groups->count_nodes); @@ -6311,6 +6420,11 @@ static char **s_parse_items(const char *a_str, char a_delimiter, int *a_count, c } char **lines = DAP_CALLOC(l_count_temp, sizeof (void *)); + if (!lines) { + log_it(L_ERROR, "Memoru allocation error in s_parse_items"); + DAP_FREE(l_temp_str); + return NULL; + } for (int i = 0; i < l_count_temp; i++) { while (*s == 0) s++; lines[i] = strdup(s); @@ -6556,7 +6670,10 @@ static byte_t *s_concat_meta (dap_list_t *a_meta, size_t *a_fullsize) if (l_counter >= l_part_power) { l_part_power = l_part * l_power++; l_buf = (byte_t *) DAP_REALLOC(l_buf, l_part_power); - + if (!l_buf) { + log_it(L_ERROR, "Memory allocation error in s_concat_meta"); + return NULL; + } } memcpy (&l_buf[l_index], l_tsd->data, strlen((char *)l_tsd->data)); } @@ -6576,6 +6693,10 @@ static uint8_t *s_concat_hash_and_mimetypes (dap_chain_hash_fast_t *a_chain_hash size_t l_len_meta_buf = *a_fullsize; *a_fullsize += sizeof (a_chain_hash->raw) + 1; uint8_t *l_fullbuf = DAP_CALLOC(*a_fullsize, 1); + if (!l_fullbuf) { + log_it(L_ERROR, "Memory allocation error in s_concat_hash_and_mimetypes"); + return NULL; + } uint8_t *l_s = l_fullbuf; memcpy(l_s, a_chain_hash->raw, sizeof(a_chain_hash->raw)); @@ -6590,6 +6711,10 @@ static uint8_t *s_concat_hash_and_mimetypes (dap_chain_hash_fast_t *a_chain_hash static char *s_strdup_by_index (const char *a_file, const int a_index) { char *l_buf = DAP_CALLOC(a_index + 1, 1); + if (!l_buf) { + log_it(L_ERROR, "Memory allocation error in s_strdup_by_index"); + return NULL; + } strncpy (l_buf, a_file, a_index); return l_buf; } diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c index 96a764ff535fc83fa9d7487b09acac6f313c1df3..e2c9cf73700c544bbff0f203ab6c5a741677c009 100644 --- a/modules/net/dap_chain_node_cli_cmd_tx.c +++ b/modules/net/dap_chain_node_cli_cmd_tx.c @@ -170,6 +170,10 @@ static void s_tx_header_print(dap_string_t *a_str_out, dap_chain_tx_hash_process l_declined = true; else { l_tx_data = DAP_NEW_Z(dap_chain_tx_hash_processed_ht_t); + if (!l_tx_data) { + log_it(L_ERROR, "Memory allocation error in s_tx_header_print"); + return; + } l_tx_data->hash = *a_tx_hash; HASH_ADD(hh, *a_tx_data_ht, hash, sizeof(*a_tx_hash), l_tx_data); const char *l_token_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(a_ledger, a_tx_hash); @@ -550,6 +554,10 @@ static char* dap_db_history_filter(dap_chain_t * a_chain, dap_ledger_t *a_ledger break; } l_sht = DAP_NEW_Z(dap_chain_tx_hash_processed_ht_t); + if (!l_sht) { + log_it(L_ERROR, "Memory allocation error in dap_db_history_filter"); + return NULL; + } l_sht->hash = l_tx_hash; HASH_ADD(hh, a_tx_hash_processed, hash, sizeof(dap_chain_hash_fast_t), l_sht); l_tx_num++; @@ -676,6 +684,11 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) dap_chain_addr_t *l_addr_tmp = (dap_chain_addr_t *) dap_chain_wallet_get_addr(l_wallet, l_net->pub.id); l_addr = DAP_NEW_SIZE(dap_chain_addr_t, sizeof(dap_chain_addr_t)); + if (!l_addr) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Out of memory!"); + log_it(L_ERROR, "Memory allocation error in com_ledger"); + return -1; + } memcpy(l_addr, l_addr_tmp, sizeof(dap_chain_addr_t)); dap_chain_wallet_close(l_wallet); } @@ -1326,6 +1339,11 @@ int cmd_decree(int a_argc, char **a_argv, char ** a_str_reply) }else{ l_total_tsd_size += sizeof(dap_tsd_t) + sizeof(dap_chain_addr_t); l_tsd = DAP_NEW_Z_SIZE(dap_tsd_t, l_total_tsd_size); + if (!l_tsd) { + log_it(L_ERROR, "Memory allocation error in cmd_decree"); + dap_list_free_full(l_tsd_list, NULL); + return -1; + } l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE_WALLET; l_tsd->size = sizeof(dap_chain_addr_t); dap_chain_addr_t *l_addr = dap_chain_addr_from_str(l_param_addr_str); @@ -1335,6 +1353,11 @@ int cmd_decree(int a_argc, char **a_argv, char ** a_str_reply) l_total_tsd_size += sizeof(dap_tsd_t) + sizeof(uint256_t); l_tsd = DAP_NEW_Z_SIZE(dap_tsd_t, l_total_tsd_size); + if (!l_tsd) { + log_it(L_ERROR, "Memory allocation error in cmd_decree"); + dap_list_free_full(l_tsd_list, NULL); + return -1; + } l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE; l_tsd->size = sizeof(uint256_t); *(uint256_t*)(l_tsd->data) = dap_cvt_str_to_uint256(l_param_value_str); @@ -1387,6 +1410,11 @@ int cmd_decree(int a_argc, char **a_argv, char ** a_str_reply) l_total_tsd_size = sizeof(dap_tsd_t) + sizeof(uint256_t); l_tsd = DAP_NEW_Z_SIZE(dap_tsd_t, l_total_tsd_size); + if (!l_tsd) { + log_it(L_ERROR, "Memory allocation error in cmd_decree"); + dap_list_free_full(l_tsd_list, NULL); + return -1; + } l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_MIN_OWNER; l_tsd->size = sizeof(uint256_t); *(uint256_t*)(l_tsd->data) = l_new_num_of_owners; diff --git a/modules/net/dap_chain_node_client.c b/modules/net/dap_chain_node_client.c index e96fdc788f6509a88c6c7a491807cd0c719de003..3b2a56925986f93f236bed3509048e5a87449394 100644 --- a/modules/net/dap_chain_node_client.c +++ b/modules/net/dap_chain_node_client.c @@ -685,6 +685,10 @@ dap_chain_node_client_t *dap_chain_node_client_create(dap_chain_net_t *a_net, return NULL; } dap_chain_node_client_t *l_node_client = DAP_NEW_Z(dap_chain_node_client_t); + if (!l_node_client) { + log_it(L_ERROR, "Memory allocation error in dap_chain_node_client_create"); + return NULL; + } l_node_client->state = NODE_CLIENT_STATE_DISCONNECTED; l_node_client->callbacks_arg = a_callback_arg; diff --git a/modules/net/dap_chain_node_dns_client.c b/modules/net/dap_chain_node_dns_client.c index 3b8ed6a71547e60a53d1a653daacc1576b92be76..641f11bedc5e2b3af54703a923c9e8c41a6dafa0 100644 --- a/modules/net/dap_chain_node_dns_client.c +++ b/modules/net/dap_chain_node_dns_client.c @@ -171,6 +171,10 @@ static void s_dns_client_esocket_worker_assign_callback(dap_events_socket_t * a_ dap_events_socket_write_unsafe(a_esocket,l_dns_client->dns_request.data, l_dns_client->dns_request.size ); dap_events_socket_uuid_t * l_es_uuid_ptr = DAP_NEW_Z(dap_events_socket_uuid_t); + if (!l_es_uuid_ptr) { + log_it(L_ERROR, "Memory allocation error in s_dns_client_esocket_worker_assign_callback"); + return; + } *l_es_uuid_ptr = a_esocket->uuid; dap_timerfd_start_on_worker(a_worker, dap_config_get_item_uint64_default(g_config,"dns_client","request_timeout",10)*1000, s_dns_client_esocket_timeout_callback,l_es_uuid_ptr); diff --git a/modules/net/dap_chain_node_dns_server.c b/modules/net/dap_chain_node_dns_server.c index 7ed8fea2822e41a1262efc404947b15571961a7f..da023392eccdd15a656232dce62bb6bb550802b4 100644 --- a/modules/net/dap_chain_node_dns_server.c +++ b/modules/net/dap_chain_node_dns_server.c @@ -53,6 +53,10 @@ int dap_dns_zone_register(char *zone, dap_dns_zone_callback_t callback) { HASH_FIND_STR(s_dns_server->hash_table, zone, new_zone); if (new_zone == NULL) { // zone is not present new_zone = DAP_NEW(dap_dns_zone_hash_t); + if (!new_zone) { + log_it(L_ERROR, "Memory allocation error in dap_dns_zone_register"); + return DNS_ERROR_FAILURE; + } new_zone->zone = dap_strdup(zone); HASH_ADD_KEYPTR(hh, s_dns_server->hash_table, new_zone->zone, strlen(new_zone->zone), new_zone); } // if zone present, just reassign callback @@ -112,8 +116,20 @@ void dap_dns_client_read(dap_events_socket_t *a_es, void *a_arg) { return; } dap_dns_buf_t *dns_message = DAP_NEW(dap_dns_buf_t); + if (!dns_message) { + log_it(L_ERROR, "Memory allocation error in dap_dns_client_read"); + return; + } dap_dns_buf_t *dns_reply = DAP_NEW(dap_dns_buf_t); + if (!dns_reply) { + log_it(L_ERROR, "Memory allocation error in dap_dns_client_read"); + return; + } dns_message->data = DAP_NEW_SIZE(char, a_es->buf_in_size + 1); + if (!dns_message->data) { + log_it(L_ERROR, "Memory allocation error in dap_dns_client_read"); + return; + } dns_message->data[a_es->buf_in_size] = 0; dap_events_socket_pop_from_buf_in(a_es, dns_message->data, a_es->buf_in_size); dns_message->size = 0; @@ -121,6 +137,10 @@ void dap_dns_client_read(dap_events_socket_t *a_es, void *a_arg) { // Parse incoming DNS message int block_len = DNS_HEADER_SIZE; dns_reply->data = DAP_NEW_SIZE(char, block_len); + if (!dns_reply->data) { + log_it(L_ERROR, "Memory allocation error in dap_dns_client_read"); + return; + } dns_reply->size = 0; uint16_t val = dap_dns_buf_get_uint16(dns_message); // ID dap_dns_buf_put_uint16(dns_reply, val); @@ -260,6 +280,10 @@ cleanup: void dap_dns_server_start( uint16_t a_port) { s_dns_server = DAP_NEW_Z(dap_dns_server_t); + if (!s_dns_server) { + log_it(L_ERROR, "Memory allocation error in dap_dns_server_start"); + return; + } dap_events_socket_callbacks_t l_cb = {}; l_cb.read_callback = dap_dns_client_read; s_dns_server->instance = dap_server_new( NULL, a_port, SERVER_UDP, &l_cb); diff --git a/modules/net/dap_chain_node_ping.c b/modules/net/dap_chain_node_ping.c index f40d10edec1a5ee7b21b8b0f15555a323fa6f837..10d65ae03abab2465e77f3af56dc2539077def3a 100644 --- a/modules/net/dap_chain_node_ping.c +++ b/modules/net/dap_chain_node_ping.c @@ -87,6 +87,10 @@ static void* node_ping_proc(void *a_arg) DAP_DELETE(a_arg); char *host4 = DAP_NEW_SIZE(char, INET_ADDRSTRLEN); + if (!host4) { + log_it(L_ERROR, "Memory allocation error in node_ping_proc"); + return NULL; + } struct sockaddr_in sa4 = { .sin_family = AF_INET, .sin_addr = l_addr }; const char* str_ip4 = inet_ntop(AF_INET, &(((struct sockaddr_in *) &sa4)->sin_addr), host4, INET_ADDRSTRLEN); if(!str_ip4){ @@ -156,6 +160,10 @@ static void* node_ping_proc(void *a_arg) int start_node_ping(pthread_t *a_thread, struct in_addr a_addr, int a_port, int a_count) { uint8_t *l_data = DAP_NEW_Z_SIZE(uint8_t, sizeof(struct in_addr) + 2 * sizeof(int)); + if (!l_data) { + log_it(L_ERROR, "Memory allocation error in start_node_ping"); + return -1; + } memcpy(l_data, &a_count, sizeof(int)); memcpy(l_data + sizeof(int), &a_port, sizeof(int)); memcpy(l_data + 2 * sizeof(int), &a_addr, sizeof(struct in_addr)); @@ -265,6 +273,12 @@ static void* node_ping_background_proc(void *a_arg) // allocate memory for best node addresses dap_chain_node_addr_t *l_node_addr_tmp; l_node_addr_tmp = DAP_NEW(dap_chain_node_addr_t); + if (!l_node_addr_tmp) { + log_it(L_ERROR, "Memory allocation error in node_ping_background_proc"); + dap_list_free_full(l_node_list0, NULL); + DAP_DEL_Z(s_node_addr_ping); + return 0; + } memcpy(l_node_addr_tmp, s_node_addr_tr, sizeof(dap_chain_node_addr_t)); DAP_DELETE(s_node_addr_tr); s_node_addr_tr = l_node_addr_tmp; @@ -292,12 +306,22 @@ int dap_chain_node_ping_background_start(dap_chain_net_t *a_net, dap_list_t *a_n dap_list_t *l_node_list_tmp = a_node_list; while(l_node_list_tmp) { dap_chain_node_addr_t *l_addr = DAP_NEW(dap_chain_node_addr_t); + if (!l_addr) { + log_it(L_ERROR, "Memory allocation error in dap_chain_node_ping_background_start"); + dap_list_free_full(l_node_list, NULL); + return -1; + } memcpy(l_addr, l_node_list_tmp->data, sizeof(dap_chain_node_addr_t)); l_node_list = dap_list_append(l_node_list, l_addr); l_node_list_tmp = dap_list_next(l_node_list_tmp); } // start searching for better nodes uint8_t *l_arg = DAP_NEW_SIZE(uint8_t, sizeof(dap_chain_net_t*) + sizeof(dap_list_t*)); + if (!l_arg) { + log_it(L_ERROR, "Memory allocation error in dap_chain_node_ping_background_start"); + dap_list_free_full(l_node_list, NULL); + return -1; + } memcpy(l_arg, &a_net, sizeof(dap_chain_net_t*)); memcpy(l_arg + sizeof(dap_chain_net_t*), &l_node_list, sizeof(dap_list_t*)); pthread_create(&s_thread, NULL, node_ping_background_proc, l_arg); diff --git a/modules/net/srv/dap_chain_net_srv.c b/modules/net/srv/dap_chain_net_srv.c index d5ad5708f222ddc953507b2cfd76efb42fa6fbac..5c4843ada1f5e2e450b29fc1875c9bec5eb6ce19 100644 --- a/modules/net/srv/dap_chain_net_srv.c +++ b/modules/net/srv/dap_chain_net_srv.c @@ -247,14 +247,14 @@ static int s_cli_net_srv( int argc, char **argv, char **a_str_reply) const char* l_region_str = NULL; dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-region", &l_region_str); + const char* l_continent_str = NULL; dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-continent", &l_continent_str); + int8_t l_continent_num = dap_chain_net_srv_order_continent_to_num(l_continent_str); const char *l_units_str = NULL; dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-units", &l_units_str); - int8_t l_continent_num = dap_chain_net_srv_order_continent_to_num(l_continent_str); - char *l_order_hash_hex_str; char *l_order_hash_base58_str; // datum hash may be in hex or base58 format @@ -651,10 +651,12 @@ static bool s_fee_verificator_callback(dap_ledger_t *a_ledger, UNUSED_ARG dap_ch return false; if (dap_hash_fast_is_blank(&l_tx_in_cond->header.tx_prev_hash)) return false; - const dap_chain_block_cache_t *l_block_cache = l_chain->callback_block_find_by_tx_hash(l_chain, &l_tx_in_cond->header.tx_prev_hash); - if (!l_block_cache) + size_t l_block_size = 0; + dap_chain_block_t *l_block = (dap_chain_block_t *)l_chain->callback_block_find_by_tx_hash( + l_chain, &l_tx_in_cond->header.tx_prev_hash, &l_block_size); + if (!l_block) continue; - dap_sign_t *l_sign_block = dap_chain_block_sign_get(l_block_cache->block, l_block_cache->block_size, 0); + dap_sign_t *l_sign_block = dap_chain_block_sign_get(l_block, l_block_size, 0); if (!l_sign_block) return false; @@ -808,6 +810,10 @@ int dap_chain_net_srv_parse_pricelist(dap_chain_net_srv_t *a_srv, const char *a_ char **l_pricelist = dap_config_get_array_str(g_config, a_config_section, "pricelist", &l_pricelist_count); for (uint16_t i = 0; i < l_pricelist_count; i++) { dap_chain_net_srv_price_t *l_price = DAP_NEW_Z(dap_chain_net_srv_price_t); + if (!l_price) { + log_it(L_ERROR, "Memory allocation error in dap_chain_net_srv_parse_pricelist"); + return ret; + } short l_iter = 0; char *l_ctx; for (char *l_price_token = strtok_r(l_pricelist[i], ":", &l_ctx); l_price_token || l_iter == 6; l_price_token = strtok_r(NULL, ":", &l_ctx), ++l_iter) { @@ -903,16 +909,30 @@ dap_chain_net_srv_t* dap_chain_net_srv_add(dap_chain_net_srv_uid_t a_uid, HASH_FIND(hh, s_srv_list, &l_uid, sizeof(l_uid), l_sdata); if(l_sdata == NULL) { l_srv = DAP_NEW_Z(dap_chain_net_srv_t); + if (!l_srv) { + log_it(L_ERROR, "Memory allocation error in dap_chain_net_srv_add"); + pthread_mutex_unlock(&s_srv_list_mutex); + return NULL; + } l_srv->uid.uint64 = a_uid.uint64; if (a_callbacks) l_srv->callbacks = *a_callbacks; pthread_mutex_init(&l_srv->banlist_mutex, NULL); l_sdata = DAP_NEW_Z(service_list_t); + if (!l_sdata) { + log_it(L_ERROR, "Memory allocation error in dap_chain_net_srv_add"); + DAP_DEL_Z(l_srv); + pthread_mutex_unlock(&s_srv_list_mutex); + return NULL; + } l_sdata->uid = l_uid; strncpy(l_sdata->name, a_config_section, sizeof(l_sdata->name) - 1); l_sdata->srv = l_srv; dap_chain_net_srv_price_apply_from_my_order(l_srv, a_config_section); +// dap_chain_net_srv_parse_pricelist(l_srv, a_config_section); HASH_ADD(hh, s_srv_list, uid, sizeof(l_srv->uid), l_sdata); + if (l_srv->pricelist) + dap_chain_ledger_tx_add_notify(l_srv->pricelist->net->pub.ledger, dap_stream_ch_chain_net_srv_tx_cond_added_cb, NULL); }else{ log_it(L_ERROR, "Already present service with 0x%016"DAP_UINT64_FORMAT_X, a_uid.uint64); } diff --git a/modules/net/srv/dap_chain_net_srv_client.c b/modules/net/srv/dap_chain_net_srv_client.c index 90259de8c283a9acb95c40e29b25ef05e653c6ad..16f080dc106747ed390e4bfe98f73303e4f9510e 100644 --- a/modules/net/srv/dap_chain_net_srv_client.c +++ b/modules/net/srv/dap_chain_net_srv_client.c @@ -41,6 +41,10 @@ dap_chain_net_srv_client_t *dap_chain_net_srv_client_create_n_connect(dap_chain_ void *a_callbacks_arg) { dap_chain_net_srv_client_t *l_ret = DAP_NEW_Z(dap_chain_net_srv_client_t); + if (!l_ret) { + log_it(L_ERROR, "Memory allocation error in dap_chain_net_srv_client_create_n_connect"); + return NULL; + } if (a_callbacks) l_ret->callbacks = *a_callbacks; l_ret->callbacks_arg = a_callbacks_arg; @@ -50,6 +54,11 @@ dap_chain_net_srv_client_t *dap_chain_net_srv_client_create_n_connect(dap_chain_ .delete = s_srv_client_callback_deleted }; dap_chain_node_info_t *l_info = DAP_NEW_Z(dap_chain_node_info_t); + if (!l_ret) { + log_it(L_ERROR, "Memory allocation error in dap_chain_net_srv_client_create_n_connect"); + DAP_DEL_Z(l_ret); + return NULL; + } inet_pton(AF_INET, a_addr, &l_info->hdr.ext_addr_v4); l_info->hdr.ext_port = a_port; const char l_channels[] = {dap_stream_ch_chain_net_srv_get_id(), '\0'}; diff --git a/modules/net/srv/dap_chain_net_srv_geoip.c b/modules/net/srv/dap_chain_net_srv_geoip.c index 84bc1c133e7be6705740c11b850df59fdd6bc92f..ad6fa6542588cd5c59a7e64fd0ba39c837535fdf 100644 --- a/modules/net/srv/dap_chain_net_srv_geoip.c +++ b/modules/net/srv/dap_chain_net_srv_geoip.c @@ -175,17 +175,21 @@ geoip_info_t *chain_net_geoip_get_ip_info_by_local_db(const char *a_ip_str, cons //char *l_file_db_name = dap_strdup_printf("%s/share/geoip/GeoLite2-City.mmdb", g_sys_dir_path); if(!dap_file_test(s_geoip_db_file_path)) { //DAP_DELETE(l_file_db_name); - return NULL ; + return NULL; } MMDB_s mmdb; int l_status = MMDB_open(s_geoip_db_file_path, MMDB_MODE_MMAP, &mmdb); if(MMDB_SUCCESS != l_status) { log_it(L_WARNING, "geoip file %s opened with errcode=%d", s_geoip_db_file_path, l_status); - return NULL ; + return NULL; } //DAP_DELETE(l_file_db_name); geoip_info_t *l_ret = DAP_NEW_Z(geoip_info_t); + if (!l_ret) { + log_it(L_ERROR, "Memory allocation error in chain_net_geoip_get_ip_info_by_local_db"); + return NULL; + } int gai_error, mmdb_error; MMDB_lookup_result_s result = MMDB_lookup_string(&mmdb, a_ip_str, &gai_error, &mmdb_error); diff --git a/modules/net/srv/dap_chain_net_srv_order.c b/modules/net/srv/dap_chain_net_srv_order.c index 00c9494de16aabfefbe9ce322f1352c7bf3fae44..eacda3cf4f9bff2b54853fee217ff30c6bd3f312 100644 --- a/modules/net/srv/dap_chain_net_srv_order.c +++ b/modules/net/srv/dap_chain_net_srv_order.c @@ -67,11 +67,11 @@ static dap_list_t *s_order_notify_callbacks = NULL; static void s_srv_order_callback_notify(dap_global_db_context_t *a_context, dap_store_obj_t *a_obj, void *a_arg); static dap_timerfd_t *s_timer_order_check_decree_sign = NULL; -static void s_srv_order_check_decree_sign_timer(){ +static void s_srv_order_check_decree_sign_timer() { uint32_t l_unverified_orders_lifetime = dap_config_get_item_uint32_default(g_config, "srv", "unverified_orders_lifetime", 21600); dap_time_t l_time_cut_off = dap_time_now(); l_time_cut_off -= l_unverified_orders_lifetime; // 6 Hours; - size_t l_net_count = 0; + uint16_t l_net_count = 0; dap_chain_net_t **l_net_list = dap_chain_net_list(&l_net_count); for (uint16_t i = 0; i < l_net_count; i++) { if (dap_chain_net_get_role(l_net_list[i]).enums == NODE_ROLE_MASTER) { @@ -217,6 +217,10 @@ bool dap_chain_net_srv_order_get_continent_region(dap_chain_net_srv_order_t *a_o size_t l_size = a_order_static->ext_size - sizeof(uint8_t) - 1; if(l_size > 0) { *a_region = DAP_NEW_SIZE(char, l_size); + if (!a_region) { + log_it(L_ERROR, "Memory allocation error in dap_chain_net_srv_order_get_continent_region"); + return false; + } memcpy(*a_region, a_order_static->ext_n_sign + 1 + sizeof(uint8_t), l_size); } else @@ -348,11 +352,19 @@ dap_chain_net_srv_order_t *dap_chain_net_srv_order_compose(dap_chain_net_t *a_ne dap_chain_net_srv_order_t *l_order; if (a_ext_size) { l_order = (dap_chain_net_srv_order_t *)DAP_NEW_Z_SIZE(void, sizeof(dap_chain_net_srv_order_t) + a_ext_size); + if (!l_order) { + log_it(L_ERROR, "Memory allocation error in dap_chain_net_srv_order_compose"); + return NULL; + } memcpy(l_order->ext_n_sign, a_ext, a_ext_size); l_order->ext_size = a_ext_size; } else { l_order = DAP_NEW_Z(dap_chain_net_srv_order_t); + if (!l_order) { + log_it(L_ERROR, "Memory allocation error in dap_chain_net_srv_order_compose"); + return NULL; + } dap_chain_net_srv_order_set_continent_region(&l_order, a_continent_num, a_region); } @@ -407,6 +419,10 @@ char *dap_chain_net_srv_order_save(dap_chain_net_t *a_net, dap_chain_net_srv_ord dap_chain_net_srv_order_t *dap_chain_net_srv_order_read(byte_t *a_order, size_t a_order_size) { + if (NULL == a_order) { + log_it(L_ERROR, "Argumets are NULL for dap_chain_net_srv_order_read"); + return NULL; + } dap_chain_net_srv_order_t *l_order = (dap_chain_net_srv_order_t *)a_order; size_t l_order_size = dap_chain_net_srv_order_get_size((dap_chain_net_srv_order_t *)a_order); if (l_order->version > 3 || l_order->direction > SERV_DIR_SELL || l_order_size != a_order_size) @@ -615,12 +631,12 @@ void dap_chain_net_srv_order_dump_to_string(dap_chain_net_srv_order_t *a_order,d } else dap_string_append_printf(a_str_out, " ext: 0x0\n"); - dap_string_append_printf(a_str_out, " units: %zu\n", a_order->units); dap_sign_t *l_sign = (dap_sign_t*)((byte_t*)a_order->ext_n_sign + a_order->ext_size); dap_hash_fast_t l_sign_pkey = {0}; dap_sign_get_pkey_hash(l_sign, &l_sign_pkey); char *l_sign_pkey_hash_str = dap_hash_fast_to_str_new(&l_sign_pkey); dap_string_append_printf(a_str_out, " pkey: %s\n", l_sign_pkey_hash_str); + dap_string_append_printf(a_str_out, " units: %zu\n", a_order->units); DAP_DELETE(l_sign_pkey_hash_str); // order state /* { @@ -660,7 +676,6 @@ static void s_srv_order_callback_notify(dap_global_db_context_t *a_context, dap_ } } bool l_allow_unsigned_orders = dap_config_get_item_bool_default(g_config, "srv", "allow_unsigned_orders", false); -// bool l_allow_unverified_orders = dap_config_get_item_bool_default(g_config, "srv", "allow_unverified_orders", false); if (a_obj->value && a_obj->type == DAP_DB$K_OPTYPE_ADD) { dap_chain_net_srv_order_t *l_order = (dap_chain_net_srv_order_t *)a_obj->value; if (l_order->version != 3) { @@ -688,6 +703,10 @@ static void s_srv_order_callback_notify(dap_global_db_context_t *a_context, dap_ void dap_chain_net_srv_order_add_notify_callback(dap_chain_net_t *a_net, dap_store_obj_callback_notify_t a_callback, void *a_cb_arg) { struct dap_order_notify *l_notifier = DAP_NEW(struct dap_order_notify); + if (!l_notifier) { + log_it(L_ERROR, "Memory allocation error in dap_chain_net_srv_order_add_notify_callback"); + return; + } l_notifier->net = a_net; l_notifier->callback = a_callback; l_notifier->cb_arg = a_cb_arg; diff --git a/modules/net/srv/dap_chain_net_srv_stream_session.c b/modules/net/srv/dap_chain_net_srv_stream_session.c index 34128a0d38f0abfb4c01c3c734d90449b470ae0d..445a8eddb854fef906454c15ffeca7fe88738487 100644 --- a/modules/net/srv/dap_chain_net_srv_stream_session.c +++ b/modules/net/srv/dap_chain_net_srv_stream_session.c @@ -41,12 +41,32 @@ dap_chain_net_srv_stream_session_t * dap_chain_net_srv_stream_session_create( da return NULL; } dap_chain_net_srv_stream_session_t * l_session_srv= DAP_NEW_Z(dap_chain_net_srv_stream_session_t); + if (!l_session_srv) { + log_it(L_ERROR, "Memory allocation error in dap_chain_net_srv_stream_session_create"); + return NULL; + } a_session->_inheritor = l_session_srv; l_session_srv->parent = a_session; log_it(L_NOTICE, "created service session"); return l_session_srv; } +/** + * @brief dap_chain_net_srv_stream_session_create + * @param a_session + * @return + */ +void dap_chain_net_srv_stream_session_delete( dap_stream_session_t * a_session) +{ + if (!a_session){ + log_it (L_ERROR, "Session is NULL!"); + return; + } + dap_chain_net_srv_stream_session_t * l_session_srv = a_session->_inheritor; + dap_chain_net_srv_usage_delete(l_session_srv); +} + + /** * @brief dap_chain_net_srv_usage_add * @param a_srv_session @@ -59,6 +79,10 @@ dap_chain_net_srv_usage_t* dap_chain_net_srv_usage_add (dap_chain_net_srv_stream { if ( a_srv_session && a_net && a_srv ){ dap_chain_net_srv_usage_t * l_ret = DAP_NEW_Z(dap_chain_net_srv_usage_t); + if (!l_ret) { + log_it(L_ERROR, "Memory allocation error in dap_chain_net_srv_usage_add"); + return NULL; + } randombytes(&l_ret->id, sizeof(l_ret->id)); l_ret->net = a_net; l_ret->service = a_srv; @@ -78,21 +102,23 @@ dap_chain_net_srv_usage_t* dap_chain_net_srv_usage_add (dap_chain_net_srv_stream * @param a_usage * @return */ -void dap_chain_net_srv_usage_delete (dap_chain_net_srv_stream_session_t * a_srv_session, - dap_chain_net_srv_usage_t* a_usage) +void dap_chain_net_srv_usage_delete (dap_chain_net_srv_stream_session_t * a_srv_session) { - if ( a_usage->receipt ) - DAP_DELETE( a_usage->receipt ); - if ( a_usage->client ){ - for (dap_chain_net_srv_client_remote_t * l_srv_client = a_usage->client, * tmp = NULL; l_srv_client; ){ + if (!a_srv_session || !a_srv_session->usage_active) + return; + + if ( a_srv_session->usage_active->receipt ) + DAP_DEL_Z( a_srv_session->usage_active->receipt ); + if ( a_srv_session->usage_active->receipt_next ) + DAP_DEL_Z( a_srv_session->usage_active->receipt_next); + if ( a_srv_session->usage_active->client ){ + for (dap_chain_net_srv_client_remote_t * l_srv_client = a_srv_session->usage_active->client, * tmp = NULL; l_srv_client; ){ tmp = l_srv_client; l_srv_client = l_srv_client->next; DAP_DELETE( tmp); } - - } - DAP_DELETE( a_usage ); + DAP_DEL_Z(a_srv_session->usage_active); } /** diff --git a/modules/net/srv/include/dap_chain_net_srv.h b/modules/net/srv/include/dap_chain_net_srv.h index 05e1644b3e6198759dba4ad2887e5963e9b52e0c..6756d30a9e1b79867cefcb83298c953588c2a645 100755 --- a/modules/net/srv/include/dap_chain_net_srv.h +++ b/modules/net/srv/include/dap_chain_net_srv.h @@ -186,6 +186,7 @@ typedef struct dap_chain_net_srv_grace { dap_stream_worker_t *stream_worker; dap_stream_ch_uuid_t ch_uuid; dap_chain_net_srv_usage_t *usage; + dap_events_socket_uuid_t timer_es_uuid; dap_stream_ch_chain_net_srv_pkt_request_t *request; size_t request_size; } dap_chain_net_srv_grace_t; @@ -303,7 +304,8 @@ dap_chain_datum_tx_receipt_t * dap_chain_net_srv_issue_receipt(dap_chain_net_srv const void * a_ext, size_t a_ext_size); uint8_t dap_stream_ch_chain_net_srv_get_id(); -//int dap_chain_net_srv_parse_pricelist(dap_chain_net_srv_t *a_srv, const char *a_config_section); +int dap_chain_net_srv_parse_pricelist(dap_chain_net_srv_t *a_srv, const char *a_config_section); + int dap_chain_net_srv_price_apply_from_my_order(dap_chain_net_srv_t *a_srv, const char *a_config_section); DAP_STATIC_INLINE const char * dap_chain_net_srv_price_unit_uid_to_str( dap_chain_net_srv_price_unit_uid_t a_uid ) diff --git a/modules/net/srv/include/dap_chain_net_srv_stream_session.h b/modules/net/srv/include/dap_chain_net_srv_stream_session.h index 6f7a7b0dda5c930ca9557af4378dab2a708c8756..af8bb938713a95f508ce0d14c06441e5276c0d37 100644 --- a/modules/net/srv/include/dap_chain_net_srv_stream_session.h +++ b/modules/net/srv/include/dap_chain_net_srv_stream_session.h @@ -55,6 +55,7 @@ typedef struct dap_chain_net_srv_usage{ bool is_active; bool is_free; bool is_grace; + bool is_waiting_new_tx_cond; // UT_hash_handle hh; // } dap_chain_net_srv_usage_t; @@ -91,9 +92,9 @@ typedef struct dap_chain_net_srv_stream_session { #define DAP_CHAIN_NET_SRV_STREAM_SESSION(a) ((dap_chain_net_srv_stream_session_t *) (a)->_inheritor ) dap_chain_net_srv_stream_session_t * dap_chain_net_srv_stream_session_create( dap_stream_session_t * a_session); +void dap_chain_net_srv_stream_session_delete( dap_stream_session_t * a_session); dap_chain_net_srv_usage_t* dap_chain_net_srv_usage_add (dap_chain_net_srv_stream_session_t * a_srv_session, dap_chain_net_t * a_net, dap_chain_net_srv_t * a_srv); -void dap_chain_net_srv_usage_delete (dap_chain_net_srv_stream_session_t * a_srv_session, - dap_chain_net_srv_usage_t* a_usage); +void dap_chain_net_srv_usage_delete (dap_chain_net_srv_stream_session_t * a_srv_session); dap_chain_net_srv_usage_t* dap_chain_net_srv_usage_find_unsafe (dap_chain_net_srv_stream_session_t * a_srv_session, uint32_t a_usage_id); diff --git a/modules/service/datum/dap_chain_net_srv_datum.c b/modules/service/datum/dap_chain_net_srv_datum.c index 971586fe17c915642433bcc96a7e79e80ac88138..ed5776f87e777b5bd1b2663f672b0a0f4f892167 100644 --- a/modules/service/datum/dap_chain_net_srv_datum.c +++ b/modules/service/datum/dap_chain_net_srv_datum.c @@ -46,6 +46,10 @@ int dap_chain_net_srv_datum_init() "srv_datum -net <net_name> -chain <chain_name> datum load -datum <datum_hash>\n" "\tLoad datum custum from file to mempool.\n\n"); s_srv_datum = DAP_NEW_Z(dap_chain_net_srv_t); + if (!s_srv_datum) { + log_it(L_ERROR, "Memory allocation error in dap_chain_net_srv_datum_init"); + return -1; + } s_srv_datum->uid.uint64 = DAP_CHAIN_NET_SRV_DATUM_ID; dap_chain_net_srv_price_apply_from_my_order(s_srv_datum, "srv_datum"); dap_chain_net_srv_price_t *l_price; diff --git a/modules/service/stake/dap_chain_net_srv_stake_lock.c b/modules/service/stake/dap_chain_net_srv_stake_lock.c index 077330a82c0dcaa13db289006a6a40d2666898a3..a31b7db25426ea1aefccd296785e1f9dc263bcba 100644 --- a/modules/service/stake/dap_chain_net_srv_stake_lock.c +++ b/modules/service/stake/dap_chain_net_srv_stake_lock.c @@ -931,6 +931,15 @@ static bool s_stake_lock_callback_verificator(dap_ledger_t *a_ledger, dap_chain_ if (dap_hash_fast_is_blank(&l_burning_tx_hash)) return false; l_burning_tx = dap_chain_ledger_tx_find_by_hash(a_ledger, &l_burning_tx_hash); + if (!l_burning_tx) { + char l_burning_tx_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE] = { '\0' }; + dap_hash_fast_to_str(&l_burning_tx_hash, l_burning_tx_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE); + char *l_take_tx_hash_str; + dap_get_data_hash_str_static(a_tx_in, dap_chain_datum_tx_get_size(a_tx_in), l_take_tx_hash_str); + log_it(L_ERROR, "[Legacy] Can't find burning tx with hash %s, obtained from the receipt of take tx %s", + l_burning_tx_hash_str, l_take_tx_hash_str); + return false; + } } else l_burning_tx = a_tx_in; 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 5a8d9b359436f45579ad2c2e775c1325282b0c71..b09e976a838d742deafaf717216e63736a551fb1 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 @@ -93,6 +93,10 @@ int dap_chain_net_srv_stake_pos_delegate_init() ); s_srv_stake = DAP_NEW_Z(dap_chain_net_srv_stake_t); + if (!s_srv_stake) { + log_it(L_ERROR, "Memory allocation error in dap_chain_net_srv_stake_pos_delegate_init"); + return -1; + } s_srv_stake->delegate_allowed_min = dap_chain_coins_to_balance("1.0"); return 0; @@ -251,6 +255,19 @@ dap_list_t *dap_chain_net_srv_stake_get_validators(dap_chain_net_id_t a_net_id, return l_ret; } +dap_chain_node_addr_t *dap_chain_net_srv_stake_key_get_node_addr(dap_chain_addr_t *a_signing_addr) +{ + assert(s_srv_stake); + if (!a_signing_addr) + NULL; + + dap_chain_net_srv_stake_item_t *l_stake = NULL; + HASH_FIND(hh, s_srv_stake->itemlist, a_signing_addr, sizeof(dap_chain_addr_t), l_stake); + if (l_stake) // public key delegated for this network + return &l_stake->node_addr; + return NULL; +} + int dap_chain_net_srv_stake_mark_validator_active(dap_chain_addr_t *a_signing_addr, bool a_on_off) { assert(s_srv_stake); @@ -327,6 +344,10 @@ int dap_chain_net_srv_stake_load_cache(dap_chain_net_t *a_net) dap_chain_net_srv_stake_cache_data_t *l_cache_data = (dap_chain_net_srv_stake_cache_data_t *)l_store_obj[i].value; dap_chain_net_srv_stake_cache_item_t *l_cache = DAP_NEW_Z(dap_chain_net_srv_stake_cache_item_t); + if (!l_cache) { + log_it(L_ERROR, "Memory allocation error in dap_chain_net_srv_stake_load_cache"); + return -1; + } l_cache->signing_addr = l_cache_data->signing_addr; l_cache->tx_hash = l_cache_data->tx_hash; HASH_ADD(hh, s_srv_stake->cache, tx_hash, sizeof(dap_hash_fast_t), l_cache); @@ -518,6 +539,10 @@ dap_chain_datum_decree_t *dap_chain_net_srv_stake_decree_approve(dap_chain_net_t l_total_tsd_size += sizeof(dap_tsd_t) + sizeof(dap_hash_fast_t); l_tsd = DAP_NEW_Z_SIZE(dap_tsd_t, l_total_tsd_size); + if (!l_tsd) { + log_it(L_ERROR, "Memory allocation error in dap_chain_net_srv_stake_decree_approve"); + return NULL; + } l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_TX_HASH; l_tsd->size = sizeof(dap_hash_fast_t); *(dap_hash_fast_t*)(l_tsd->data) = *a_stake_tx_hash; @@ -525,6 +550,11 @@ dap_chain_datum_decree_t *dap_chain_net_srv_stake_decree_approve(dap_chain_net_t l_total_tsd_size += sizeof(dap_tsd_t) + sizeof(uint256_t); l_tsd = DAP_NEW_Z_SIZE(dap_tsd_t, l_total_tsd_size); + if (!l_tsd) { + log_it(L_ERROR, "Memory allocation error in dap_chain_net_srv_stake_decree_approve"); + dap_list_free_full(l_tsd_list, NULL); + return NULL; + } l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_VALUE; l_tsd->size = sizeof(uint256_t); *(uint256_t*)(l_tsd->data) = l_tx_out_cond->header.value; @@ -532,6 +562,11 @@ dap_chain_datum_decree_t *dap_chain_net_srv_stake_decree_approve(dap_chain_net_t l_total_tsd_size += sizeof(dap_tsd_t) + sizeof(dap_chain_addr_t); l_tsd = DAP_NEW_Z_SIZE(dap_tsd_t, l_total_tsd_size); + if (!l_tsd) { + log_it(L_ERROR, "Memory allocation error in dap_chain_net_srv_stake_decree_approve"); + dap_list_free_full(l_tsd_list, NULL); + return NULL; + } l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR; l_tsd->size = sizeof(dap_chain_addr_t); *(dap_chain_addr_t*)(l_tsd->data) = l_tx_out_cond->subtype.srv_stake_pos_delegate.signing_addr; @@ -539,12 +574,22 @@ dap_chain_datum_decree_t *dap_chain_net_srv_stake_decree_approve(dap_chain_net_t l_total_tsd_size += sizeof(dap_tsd_t) + sizeof(dap_chain_node_addr_t); l_tsd = DAP_NEW_Z_SIZE(dap_tsd_t, l_total_tsd_size); + if (!l_tsd) { + log_it(L_ERROR, "Memory allocation error in dap_chain_net_srv_stake_decree_approve"); + dap_list_free_full(l_tsd_list, NULL); + return NULL; + } l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNER_NODE_ADDR; l_tsd->size = sizeof(dap_chain_node_addr_t); *(dap_chain_node_addr_t*)(l_tsd->data) = l_tx_out_cond->subtype.srv_stake_pos_delegate.signer_node_addr; l_tsd_list = dap_list_append(l_tsd_list, l_tsd); l_decree = DAP_NEW_Z_SIZE(dap_chain_datum_decree_t, sizeof(dap_chain_datum_decree_t) + l_total_tsd_size); + if (!l_decree) { + log_it(L_ERROR, "Memory allocation error in dap_chain_net_srv_stake_decree_approve"); + dap_list_free_full(l_tsd_list, NULL); + return NULL; + } l_decree->decree_version = DAP_CHAIN_DATUM_DECREE_VERSION; l_decree->header.ts_created = dap_time_now(); l_decree->header.type = DAP_CHAIN_DATUM_DECREE_TYPE_COMMON; @@ -740,12 +785,21 @@ static dap_chain_datum_decree_t *s_stake_decree_invalidate(dap_chain_net_t *a_ne l_total_tsd_size += sizeof(dap_tsd_t) + sizeof(dap_chain_addr_t); l_tsd = DAP_NEW_Z_SIZE(dap_tsd_t, l_total_tsd_size); + if (!l_tsd) { + log_it(L_ERROR, "Memory allocation error in s_stake_decree_invalidate"); + return NULL; + } l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR; l_tsd->size = sizeof(dap_chain_addr_t); *(dap_chain_addr_t*)(l_tsd->data) = l_tx_out_cond->subtype.srv_stake_pos_delegate.signing_addr; l_tsd_list = dap_list_append(l_tsd_list, l_tsd); l_decree = DAP_NEW_Z_SIZE(dap_chain_datum_decree_t, sizeof(dap_chain_datum_decree_t) + l_total_tsd_size); + if (!l_decree) { + log_it(L_ERROR, "Memory allocation error in s_stake_decree_set_min_stake"); + dap_list_free_full(l_tsd_list, NULL); + return NULL; + } l_decree->decree_version = DAP_CHAIN_DATUM_DECREE_VERSION; l_decree->header.ts_created = dap_time_now(); l_decree->header.type = DAP_CHAIN_DATUM_DECREE_TYPE_COMMON; @@ -755,6 +809,7 @@ static dap_chain_datum_decree_t *s_stake_decree_invalidate(dap_chain_net_t *a_ne l_chain = dap_chain_net_get_chain_by_chain_type(a_net, CHAIN_TYPE_ANCHOR); if (!l_chain) { log_it(L_ERROR, "No chain supported anchor datum type"); + dap_list_free_full(l_tsd_list, NULL); return NULL; } l_decree->header.common_decree_params.chain_id = l_chain->id; @@ -805,12 +860,21 @@ static dap_chain_datum_decree_t *s_stake_decree_set_min_stake(dap_chain_net_t *a l_total_tsd_size += sizeof(dap_tsd_t) + sizeof(uint256_t); l_tsd = DAP_NEW_Z_SIZE(dap_tsd_t, l_total_tsd_size); + if (!l_tsd) { + log_it(L_ERROR, "Memory allocation error in s_stake_decree_set_min_stake"); + return NULL; + } l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_VALUE; l_tsd->size = sizeof(uint256_t); *(uint256_t*)(l_tsd->data) = a_value; l_tsd_list = dap_list_append(l_tsd_list, l_tsd); l_decree = DAP_NEW_Z_SIZE(dap_chain_datum_decree_t, sizeof(dap_chain_datum_decree_t) + l_total_tsd_size); + if (!l_decree) { + log_it(L_ERROR, "Memory allocation error in s_stake_decree_set_min_stake"); + dap_list_free_full(l_tsd_list, NULL); + return NULL; + } l_decree->decree_version = DAP_CHAIN_DATUM_DECREE_VERSION; l_decree->header.ts_created = dap_time_now(); l_decree->header.type = DAP_CHAIN_DATUM_DECREE_TYPE_COMMON; @@ -820,6 +884,7 @@ static dap_chain_datum_decree_t *s_stake_decree_set_min_stake(dap_chain_net_t *a l_chain = dap_chain_net_get_chain_by_chain_type(a_net, CHAIN_TYPE_ANCHOR); if (!l_chain) { log_it(L_ERROR, "No chain supported anchor datum type"); + dap_list_free_full(l_tsd_list, NULL); return NULL; } l_decree->header.common_decree_params.chain_id = l_chain->id; @@ -1141,8 +1206,11 @@ static void s_srv_stake_print(dap_chain_net_srv_stake_item_t *a_stake, dap_strin dap_string_append_printf(a_string, "Pkey hash: %s\n" "\tStake value: %s\n" "\tTx hash: %s\n" - "\tNode addr: "NODE_ADDR_FP_STR"\n\n", - l_pkey_hash_str, l_balance, l_tx_hash_str, NODE_ADDR_FP_ARGS_S(a_stake->node_addr)); + "\tNode addr: "NODE_ADDR_FP_STR"\n" + "\tActive: %s\n" + "\n", + l_pkey_hash_str, l_balance, l_tx_hash_str, NODE_ADDR_FP_ARGS_S(a_stake->node_addr), + a_stake->is_active ? "true" : "false"); DAP_DELETE(l_balance); } @@ -1562,7 +1630,7 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, char **a_str_reply) dap_cli_server_cmd_set_reply_text(a_str_reply, "Network %s not found", l_net_str); return -4; } - dap_chain_net_srv_stake_item_t *l_stake = NULL, *l_tmp; + dap_chain_net_srv_stake_item_t *l_stake = NULL; dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-cert", &l_cert_str); if (l_cert_str) { dap_cert_t *l_cert = dap_cert_find_by_name(l_cert_str); @@ -1582,18 +1650,27 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, char **a_str_reply) } } dap_string_t *l_reply_str = dap_string_new(""); + size_t l_inactive_count = 0, l_total_count = 0; if (l_stake) s_srv_stake_print(l_stake, l_reply_str); else - HASH_ITER(hh, s_srv_stake->itemlist, l_stake, l_tmp) { - if (l_stake->net->pub.id.uint64 != l_net->pub.id.uint64) { + for (l_stake = s_srv_stake->itemlist; l_stake; l_stake = l_stake->hh.next) { + if (l_stake->net->pub.id.uint64 != l_net->pub.id.uint64) continue; - } + l_total_count++; + if (!l_stake->is_active) + l_inactive_count++; s_srv_stake_print(l_stake, l_reply_str); } if (!HASH_CNT(hh, s_srv_stake->itemlist)) { dap_string_append(l_reply_str, "No keys found\n"); + } else { + dap_string_append_printf(l_reply_str, "Total keys count: %zu\n", l_total_count); + dap_string_append_printf(l_reply_str, "Inactive keys count: %zu\n", l_inactive_count); } + + + char *l_delegate_min_str = dap_chain_balance_to_coins(s_srv_stake->delegate_allowed_min); char l_delegated_ticker[DAP_CHAIN_TICKER_SIZE_MAX]; dap_chain_datum_token_get_delegated_ticker(l_delegated_ticker, l_net->pub.native_ticker); @@ -1615,6 +1692,11 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, char **a_str_reply) return -4; } struct get_tx_cond_pos_del_from_tx * l_args = DAP_NEW_Z(struct get_tx_cond_pos_del_from_tx); + if(!l_args) { + log_it(L_ERROR, "Memory allocation error in s_cli_srv_stake"); + dap_cli_server_cmd_set_reply_text(a_str_reply, "Out of memory"); + return -1; + } dap_string_t * l_str_tmp = dap_string_new(NULL); dap_hash_fast_t l_datum_hash; dap_chain_datum_tx_t *l_datum_tx = NULL; diff --git a/modules/service/stake/include/dap_chain_net_srv_stake_pos_delegate.h b/modules/service/stake/include/dap_chain_net_srv_stake_pos_delegate.h index 820ad2a8caba1908bffeb51bb78cbbb7ab95bb77..418e7aaa7c58f614387e44c9d3c52b641a2874df 100644 --- a/modules/service/stake/include/dap_chain_net_srv_stake_pos_delegate.h +++ b/modules/service/stake/include/dap_chain_net_srv_stake_pos_delegate.h @@ -73,6 +73,7 @@ uint256_t dap_chain_net_srv_stake_get_allowed_min_value(); int dap_chain_net_srv_stake_key_delegated(dap_chain_addr_t *a_addr); int dap_chain_net_srv_stake_verify_key_and_node(dap_chain_addr_t* a_signing_addr, dap_chain_node_addr_t* a_node_addr); dap_list_t *dap_chain_net_srv_stake_get_validators(dap_chain_net_id_t a_net_id, bool a_is_active); +dap_chain_node_addr_t *dap_chain_net_srv_stake_key_get_node_addr(dap_chain_addr_t *a_signing_addr); bool dap_chain_net_srv_stake_get_fee_validators(dap_chain_net_t *a_net, uint256_t *a_max_fee, uint256_t *a_average_fee, uint256_t *a_min_fee); diff --git a/modules/service/vpn/dap_chain_net_srv_vpn.c b/modules/service/vpn/dap_chain_net_srv_vpn.c index 05683727900ab216fb5522df9842d7ff5f38d032..a50285aa9e9c427dc4d660605d86ec01cb0e225c 100644 --- a/modules/service/vpn/dap_chain_net_srv_vpn.c +++ b/modules/service/vpn/dap_chain_net_srv_vpn.c @@ -319,6 +319,10 @@ static bool s_tun_client_send_data(dap_chain_net_srv_ch_vpn_info_t * l_ch_vpn_in } else { /* Shift it to other worker context */ tun_socket_msg_t* l_msg = DAP_NEW_Z(tun_socket_msg_t); + if (!l_msg) { + log_it(L_ERROR, "Memory allocation error in s_tun_client_send_data"); + return false; + } l_msg->type = TUN_SOCKET_MSG_CH_VPN_SEND; l_msg->ch_vpn = l_ch_vpn_info->ch_vpn; l_msg->esocket = l_ch_vpn_info->esocket; @@ -394,6 +398,11 @@ static void s_tun_recv_msg_callback(dap_events_socket_t * a_esocket_queue, void log_it(L_WARNING, "Already assigned address %s on tun sock #%u", l_addrbuf, l_tun_sock->worker_id); }else{ l_new_info = DAP_NEW_Z(dap_chain_net_srv_ch_vpn_info_t); + if (!l_new_info) { + log_it (L_ERROR, "Memory allocation error in s_tun_recv_msg_callback"); + DAP_DELETE(l_msg); + return; + } l_new_info->ch_vpn = l_msg->ch_vpn; l_new_info->addr_ipv4 = l_msg->ip_assigment.addr; l_new_info->queue_msg = s_tun_sockets_queue_msg[l_msg->ip_assigment.worker_id]; @@ -467,6 +476,10 @@ static void s_tun_recv_msg_callback(dap_events_socket_t * a_esocket_queue, void static void s_tun_send_msg_ip_assigned(uint32_t a_worker_own_id, uint32_t a_worker_id, dap_chain_net_srv_ch_vpn_t * a_ch_vpn, struct in_addr a_addr ) { struct tun_socket_msg * l_msg = DAP_NEW_Z(struct tun_socket_msg); + if (!l_msg) { + log_it (L_ERROR, "Memory allocation error in s_tun_send_msg_ip_assigned"); + return; + } l_msg->type = TUN_SOCKET_MSG_IP_ASSIGNED; l_msg->ch_vpn = a_ch_vpn; l_msg->esocket = a_ch_vpn->ch->stream->esocket; @@ -504,6 +517,10 @@ static void s_tun_send_msg_ip_assigned_all(uint32_t a_worker_own_id, dap_chain_n static void s_tun_send_msg_ip_unassigned(uint32_t a_worker_own_id, uint32_t a_worker_id, dap_chain_net_srv_ch_vpn_t * a_ch_vpn, struct in_addr a_addr) { struct tun_socket_msg * l_msg = DAP_NEW_Z(struct tun_socket_msg); + if (!l_msg) { + log_it (L_ERROR, "Memory allocation error in s_tun_send_msg_ip_unassigned"); + return; + } l_msg->type = TUN_SOCKET_MSG_IP_UNASSIGNED; l_msg->ch_vpn = a_ch_vpn; l_msg->ip_unassigment.addr = a_addr; @@ -549,6 +566,10 @@ static void s_tun_send_msg_esocket_reassigned_inter(uint32_t a_worker_own_id, da dap_events_socket_uuid_t a_esocket_uuid, struct in_addr a_addr) { struct tun_socket_msg * l_msg = DAP_NEW_Z(struct tun_socket_msg); + if (!l_msg) { + log_it (L_ERROR, "Memory allocation error in s_tun_send_msg_esocket_reassigned_inter"); + return; + } l_msg->type = TUN_SOCKET_MSG_ESOCKET_REASSIGNED ; l_msg->ch_vpn = a_ch_vpn; l_msg->esocket_reassigment.addr = a_addr; @@ -801,6 +822,10 @@ lb_err: static int s_vpn_tun_init() { s_raw_server=DAP_NEW_Z(vpn_local_network_t); + if (!s_raw_server) { + log_it(L_ERROR, "Memory allocation error in s_vpn_tun_init"); + return -1; + } pthread_rwlock_init(&s_raw_server->rwlock, NULL); pthread_mutex_init(&s_raw_server->pkt_out_mutex,NULL); pthread_mutex_init(&s_tun_sockets_mutex_started, NULL); @@ -826,6 +851,10 @@ static int s_vpn_service_create(dap_config_t * g_config) dap_chain_net_srv_t* l_srv = dap_chain_net_srv_add(l_uid, "srv_vpn", &l_srv_callbacks); dap_chain_net_srv_vpn_t* l_srv_vpn = DAP_NEW_Z( dap_chain_net_srv_vpn_t); + if(!l_srv_vpn) { + log_it(L_ERROR, "Memory allocation error in s_vpn_service_create"); + return -1; + } l_srv->_internal = l_srv_vpn; l_srv_vpn->parent = l_srv; @@ -915,8 +944,17 @@ static int s_callback_response_success(dap_chain_net_srv_t * a_srv, uint32_t a_u usage_client_t * l_usage_client = NULL; l_usage_client = DAP_NEW_Z(usage_client_t); + if (!l_usage_client) { + log_it(L_ERROR, "Memory allocation error in s_callback_response_success"); + return -1; + } l_usage_client->usage_id = a_usage_id; l_usage_client->receipt = DAP_NEW_SIZE(dap_chain_datum_tx_receipt_t,l_receipt_size); + if (!l_usage_client->receipt) { + log_it(L_ERROR, "Memory allocation error in s_callback_response_success"); + DAP_DEL_Z(l_usage_client); + return -1; + } memcpy(l_usage_client->receipt, l_receipt, l_receipt_size); @@ -1076,7 +1114,7 @@ void s_ch_vpn_new(dap_stream_ch_t* a_ch, void* a_arg) dap_chain_net_srv_stream_session_t * l_srv_session = (dap_chain_net_srv_stream_session_t *) a_ch->stream->session->_inheritor; - l_srv_vpn->usage_id = l_srv_session->usage_active? l_srv_session->usage_active->id : 0; + l_srv_vpn->usage_id = l_srv_session->usage_active ? l_srv_session->usage_active->id : 0; if( l_srv_vpn->usage_id) { // So complicated to update usage client to be sure that nothing breaks it @@ -1088,7 +1126,6 @@ void s_ch_vpn_new(dap_stream_ch_t* a_ch, void* a_arg) } pthread_rwlock_unlock(&s_clients_rwlock); } - } @@ -1131,6 +1168,11 @@ static void s_ch_vpn_delete(dap_stream_ch_t* a_ch, void* arg) if ( l_is_unleased ){ // If unleased log_it(L_DEBUG, "Unlease address %s and store in treshold", inet_ntoa(l_ch_vpn->addr_ipv4)); dap_chain_net_srv_vpn_item_ipv4_t * l_item_unleased = DAP_NEW_Z(dap_chain_net_srv_vpn_item_ipv4_t); + if (!l_is_unleased) { + log_it(L_ERROR, "Memory allocation error in s_ch_vpn_delete"); + pthread_rwlock_unlock(&s_clients_rwlock); + return; + } l_item_unleased->addr.s_addr = l_ch_vpn->addr_ipv4.s_addr; l_item_unleased->next = l_srv_vpn->ipv4_unleased; l_srv_vpn->ipv4_unleased = l_item_unleased; @@ -1146,6 +1188,7 @@ static void s_ch_vpn_delete(dap_stream_ch_t* a_ch, void* arg) l_ch_vpn->ch = NULL; l_ch_vpn->net_srv = NULL; l_ch_vpn->is_allowed =false; + DAP_DEL_Z(a_ch->internal); } /** @@ -1162,21 +1205,20 @@ static void s_update_limits(dap_stream_ch_t * a_ch , bool l_issue_new_receipt = false; // Check if there are time limits - if (a_usage->is_free) + if (a_usage->is_free || !a_usage->receipt || !a_usage->is_active) return; if (a_usage->receipt->receipt_info.units_type.enm == SERV_UNIT_DAY || a_usage->receipt->receipt_info.units_type.enm == SERV_UNIT_SEC){ time_t l_current_limit_ts = 0; - if ( a_usage->receipt){ - switch( a_usage->receipt->receipt_info.units_type.enm){ + + switch( a_usage->receipt->receipt_info.units_type.enm){ case SERV_UNIT_DAY:{ l_current_limit_ts = (time_t)a_usage->receipt->receipt_info.units*24*3600; } break; case SERV_UNIT_SEC:{ l_current_limit_ts = (time_t)a_usage->receipt->receipt_info.units; } - } } a_srv_session->limits_ts -= time(NULL) - a_srv_session->last_update_ts; @@ -1189,7 +1231,7 @@ static void s_update_limits(dap_stream_ch_t * a_ch , if( a_srv_session->limits_ts <= 0 && !a_usage->is_grace){ log_it(L_INFO, "Limits by timestamp are over. Switch to the next receipt"); - DAP_DELETE(a_usage->receipt); + DAP_DEL_Z(a_usage->receipt); a_usage->receipt = a_usage->receipt_next; a_usage->receipt_next = NULL; if ( a_usage->receipt){ // If there is next receipt add the time and request the next receipt @@ -1246,7 +1288,7 @@ static void s_update_limits(dap_stream_ch_t * a_ch , if (a_srv_session->limits_bytes <= 0 && !a_usage->is_grace){ log_it(L_INFO, "Limits by traffic is over. Switch to the next receipt"); - DAP_DELETE(a_usage->receipt); + DAP_DEL_Z(a_usage->receipt); a_usage->receipt = a_usage->receipt_next; a_usage->receipt_next = NULL; if ( a_usage->receipt){ // If there is next receipt add the time and request the next receipt @@ -1299,6 +1341,10 @@ static void send_pong_pkt(dap_stream_ch_t* a_ch) { // log_it(L_DEBUG,"---------------------------------- PONG!"); ch_vpn_pkt_t *pkt_out = (ch_vpn_pkt_t*) calloc(1, sizeof(pkt_out->header)); + if (!pkt_out) { + log_it(L_ERROR, "Memory allocation error in send_pong_pkt"); + return; + } pkt_out->header.op_code = VPN_PACKET_OP_CODE_PONG; dap_stream_ch_pkt_write_unsafe(a_ch, 'd', pkt_out, @@ -1323,6 +1369,10 @@ static void s_ch_packet_in_vpn_address_request(dap_stream_ch_t* a_ch, dap_chain_ if ( l_ch_vpn->addr_ipv4.s_addr ) { log_it(L_WARNING, "IP address is already leased"); ch_vpn_pkt_t* pkt_out = DAP_NEW_STACK_SIZE(ch_vpn_pkt_t, sizeof(pkt_out->header)); + if (!pkt_out) { + log_it(L_ERROR, "Memory allocation error in send_pong_pkt"); + return; + } pkt_out->header.op_code = VPN_PACKET_OP_CODE_PROBLEM; pkt_out->header.sock_id = s_raw_server->tun_fd; pkt_out->header.usage_id = a_usage->id; diff --git a/modules/service/vpn/dap_chain_net_vpn_client.c b/modules/service/vpn/dap_chain_net_vpn_client.c index 9366297ade46dc374ce44f514ba391a4495fe0e1..b7b3337c677db8a39b1220354160d3abf74201c3 100644 --- a/modules/service/vpn/dap_chain_net_vpn_client.c +++ b/modules/service/vpn/dap_chain_net_vpn_client.c @@ -181,6 +181,10 @@ static int s_callback_client_success(dap_chain_net_srv_t * a_srv, uint32_t a_usa if(l_ch) { // Is present in hash table such destination address size_t l_ipv4_str_len = 0; //dap_strlen(a_ipv4_str); ch_vpn_pkt_t *pkt_out = (ch_vpn_pkt_t*) calloc(1, sizeof(pkt_out->header) + l_ipv4_str_len); + if (!pkt_out) { + log_it(L_ERROR, "Memory allocation error in s_callback_client_success"); + return -1; + } pkt_out->header.op_code = VPN_PACKET_OP_CODE_VPN_ADDR_REQUEST; //pkt_out->header.sock_id = l_stream->stream->events_socket->socket; diff --git a/modules/service/vpn/dap_chain_net_vpn_client_tun.c b/modules/service/vpn/dap_chain_net_vpn_client_tun.c index 801422a282b49dca80c6d51f57f8927bb0e0714b..6f77ec4eed63eb8a3b5e39f7db0505461520c873 100644 --- a/modules/service/vpn/dap_chain_net_vpn_client_tun.c +++ b/modules/service/vpn/dap_chain_net_vpn_client_tun.c @@ -638,7 +638,7 @@ static void ch_sf_pkt_send(dap_stream_ch_t * a_ch, void * a_data, size_t a_data_ // ,inet_ntoa(in_daddr), read_ret); if(!a_ch) { log_it(L_ERROR, "Try to send to NULL channel"); -// return; + return; } l_pkt_out = DAP_NEW_SIZE(ch_vpn_pkt_t, l_pkt_out_size); memset(&l_pkt_out->header,0,sizeof(l_pkt_out->header)); @@ -685,6 +685,14 @@ void ch_sf_tun_client_send(dap_chain_net_srv_ch_vpn_t * ch_sf, void * pkt_data, log_it(L_ERROR, "write() returned error %d : '%s'", ret, strerror(errno)); //log_it(ERROR,"raw socket ring buffer overflowed"); ch_vpn_pkt_t *pkt_out = (ch_vpn_pkt_t*) calloc(1, sizeof(pkt_out->header)); + if (!pkt_out) { + log_it(L_ERROR, "Memory allocation error in ch_sf_tun_client_send"); + if(in_daddr_str) + free(in_daddr_str); + if(in_saddr_str) + free(in_saddr_str); + return; + } pkt_out->header.op_code = VPN_PACKET_OP_CODE_PROBLEM; pkt_out->header.op_problem.code = VPN_PROBLEM_CODE_PACKET_LOST; pkt_out->header.sock_id = s_fd_tun; @@ -697,9 +705,9 @@ void ch_sf_tun_client_send(dap_chain_net_srv_ch_vpn_t * ch_sf, void * pkt_data, } if(in_daddr_str) - free(in_daddr_str); + free(in_daddr_str); if(in_saddr_str) - free(in_saddr_str); + free(in_saddr_str); } /** diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c index 47b9fcaf51a361f43d5c50f14e4edd85d5f13120..c7173809ebf11fb40fea3d62509f168b0492ed92 100644 --- a/modules/service/xchange/dap_chain_net_srv_xchange.c +++ b/modules/service/xchange/dap_chain_net_srv_xchange.c @@ -130,6 +130,10 @@ int dap_chain_net_srv_xchange_init() dap_chain_net_srv_t* l_srv = dap_chain_net_srv_add(l_uid, "srv_xchange", &l_srv_callbacks); s_srv_xchange = DAP_NEW_Z(dap_chain_net_srv_xchange_t); + if (!s_srv_xchange) { + log_it(L_ERROR, "Memory allocation error in dap_chain_net_srv_xchange_init"); + return -1; + } l_srv->_internal = s_srv_xchange; s_srv_xchange->parent = l_srv; s_srv_xchange->enabled = false; @@ -329,6 +333,10 @@ static dap_chain_datum_tx_receipt_t *s_xchange_receipt_create(dap_chain_net_srv_ { uint32_t l_ext_size = sizeof(uint256_t) + DAP_CHAIN_TICKER_SIZE_MAX; uint8_t *l_ext = DAP_NEW_STACK_SIZE(uint8_t, l_ext_size); + if (!l_ext) { + log_it(L_ERROR, "Memory allocation error in s_xchange_receipt_create"); + return NULL; + } memcpy(l_ext, &a_datoshi_buy, sizeof(uint256_t)); strcpy((char *)&l_ext[sizeof(uint256_t)], a_price->token_buy); dap_chain_net_srv_price_unit_uid_t l_unit = { .uint32 = SERV_UNIT_UNDEFINED}; @@ -915,6 +923,10 @@ char *s_xchange_order_create(dap_chain_net_srv_xchange_price_t *a_price, dap_cha dap_chain_net_srv_xchange_price_t *s_xchange_price_from_order(dap_chain_net_t *a_net, dap_chain_net_srv_order_t *a_order, bool a_ret_is_invalid) { dap_chain_net_srv_xchange_price_t *l_price = DAP_NEW_Z(dap_chain_net_srv_xchange_price_t); + if (!l_price) { + log_it(L_ERROR, "Memory allocation error in s_xchange_price_from_order"); + return NULL; + } dap_srv_xchange_order_ext_t *l_ext = (dap_srv_xchange_order_ext_t *)a_order->ext_n_sign; strcpy(l_price->token_buy, l_ext->token_buy); l_price->datoshi_buy = l_ext->datoshi_buy; @@ -1071,6 +1083,12 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, c } // Create the price dap_chain_net_srv_xchange_price_t *l_price = DAP_NEW_Z(dap_chain_net_srv_xchange_price_t); + if (!l_price) { + log_it(L_ERROR, "Memory allocation error in s_cli_srv_xchange_order"); + dap_cli_server_cmd_set_reply_text(a_str_reply, "Out of memory"); + dap_chain_wallet_close(l_wallet); + return -1; + } l_price->wallet_str = dap_strdup(l_wallet_str); dap_stpcpy(l_price->token_sell, l_token_sell_str); l_price->net = l_net; diff --git a/modules/type/blocks/dap_chain_block.c b/modules/type/blocks/dap_chain_block.c index 15083cccb2d62f0e7feb2bc1294fa10f95899ebf..8c7379149acbb66d04189d3252e96bfe3115b44c 100644 --- a/modules/type/blocks/dap_chain_block.c +++ b/modules/type/blocks/dap_chain_block.c @@ -460,6 +460,10 @@ dap_chain_block_meta_t** dap_chain_block_get_meta(dap_chain_block_t * a_block, s size_t l_offset = 0; dap_chain_block_meta_t * l_meta=NULL; dap_chain_block_meta_t ** l_ret = DAP_NEW_Z_SIZE(dap_chain_block_meta_t *,sizeof (dap_chain_block_meta_t *)* a_block->hdr.meta_count ); + if (!l_ret) { + log_it(L_ERROR, "Memory allocation error in dap_chain_block_get_meta"); + return NULL; + } for( size_t i = 0; i< a_block->hdr.meta_count && l_offset < (a_block_size-sizeof (a_block->hdr)) && sizeof (l_meta->hdr) <= (a_block_size-sizeof (a_block->hdr)) - l_offset ; i++){ diff --git a/modules/type/blocks/dap_chain_block_cache.c b/modules/type/blocks/dap_chain_block_cache.c index b374fc923cd6158b03e6c671f56cd43854d146a6..1182d280d8ede50973d10f586062b3db49255736 100644 --- a/modules/type/blocks/dap_chain_block_cache.c +++ b/modules/type/blocks/dap_chain_block_cache.c @@ -61,6 +61,10 @@ dap_chain_block_cache_t *dap_chain_block_cache_new(dap_chain_cs_blocks_t *a_bloc return NULL; dap_chain_block_cache_t * l_block_cache = DAP_NEW_Z(dap_chain_block_cache_t); + if (!l_block_cache) { + log_it(L_ERROR, "Memory allocation error in dap_chain_block_cache_new"); + return NULL; + } l_block_cache->block = a_block; l_block_cache->block_size= a_block_size; l_block_cache->_inheritor = a_blocks; @@ -83,6 +87,10 @@ dap_chain_block_cache_t *dap_chain_block_cache_new(dap_chain_cs_blocks_t *a_bloc dap_chain_block_cache_t * dap_chain_block_cache_dup(dap_chain_block_cache_t * a_block) { dap_chain_block_cache_t * l_ret = DAP_NEW_Z(dap_chain_block_cache_t); + if (!l_ret) { + log_it(L_ERROR, "Memory allocation error in dap_chain_block_cache_dup"); + return NULL; + } memcpy(l_ret,a_block, sizeof (*a_block)); memset(&l_ret->hh,0, sizeof (l_ret->hh)); // Drop hash handle to prevent its usage return l_ret; @@ -172,6 +180,12 @@ dap_list_t * dap_chain_block_get_list_tx_cond_outs_with_val(dap_ledger_t *a_ledg dap_hash_fast_t *l_tx_hash = a_block_cache->datum_hash + i; if (!dap_chain_ledger_tx_hash_is_used_out_item (a_ledger, l_tx_hash, l_out_idx_tmp)) { dap_chain_tx_used_out_item_t *l_item = DAP_NEW_Z(dap_chain_tx_used_out_item_t); + if (!l_item) { + log_it(L_ERROR, "Memory allocation error in dap_chain_block_get_list_tx_cond_outs_with_val"); + if (l_list_used_out) + dap_list_free_full(l_list_used_out, NULL); + return NULL; + } l_item->tx_hash_fast = *l_tx_hash; l_item->num_idx_out = l_out_idx_tmp; l_item->value = l_tx_out_cond->header.value; diff --git a/modules/type/blocks/dap_chain_block_chunk.c b/modules/type/blocks/dap_chain_block_chunk.c index 4aeef8db3858af8afa04f3741d109510ffa79892..c8b15c24ba44cfce927bd031b2acb4f8760c5926 100644 --- a/modules/type/blocks/dap_chain_block_chunk.c +++ b/modules/type/blocks/dap_chain_block_chunk.c @@ -37,6 +37,10 @@ dap_chain_block_chunks_t * dap_chain_block_chunks_create(dap_chain_cs_blocks_t * assert(a_blocks); assert(a_blocks->chain); dap_chain_block_chunks_t * l_ret = DAP_NEW_Z(dap_chain_block_chunks_t); + if (!l_ret) { + log_it(L_ERROR, "Memory allocation error in dap_chain_block_chunks_create"); + return NULL; + } l_ret->blocks = a_blocks; l_ret->gdb_group = dap_strdup_printf("local.%s.%s.block.chunks",a_blocks->chain->net_name, a_blocks->chain->name ); @@ -106,6 +110,10 @@ void dap_chain_block_chunks_add(dap_chain_block_chunks_t * a_chunks,dap_chain_bl if(dap_hash_fast_compare(&l_chunk->block_cache_top->block_hash, &a_block_cache->prev_hash ) ){ // Init cache-hash object l_chunk_cache_hash = DAP_NEW_Z(dap_chain_block_cache_hash_t); + if (!l_chunk_cache_hash) { + log_it(L_ERROR, "Memory allocation error in dap_chain_block_chunks_add"); + return; + } l_chunk_cache_hash->block_cache=a_block_cache; l_chunk_cache_hash->ts_created = time(NULL); l_chunk_cache_hash->block_hash = a_block_cache->block_hash; @@ -128,6 +136,10 @@ void dap_chain_block_chunks_add(dap_chain_block_chunks_t * a_chunks,dap_chain_bl // Init cache-hash object l_chunk_cache_hash = DAP_NEW_Z(dap_chain_block_cache_hash_t); + if (!l_chunk_cache_hash) { + log_it(L_ERROR, "Memory allocation error in dap_chain_block_chunks_add"); + return; + } l_chunk_cache_hash->block_cache=a_block_cache; l_chunk_cache_hash->ts_created = time(NULL); l_chunk_cache_hash->block_hash = a_block_cache->block_hash; @@ -156,6 +168,10 @@ void dap_chain_block_chunks_add(dap_chain_block_chunks_t * a_chunks,dap_chain_bl dap_chain_block_chunk_t * dap_chain_block_chunk_create(dap_chain_block_chunks_t * a_chunks) { dap_chain_block_chunk_t * l_chunk = DAP_NEW_Z(dap_chain_block_chunk_t); + if (!l_chunk) { + log_it(L_ERROR, "Memory allocation error in dap_chain_block_chunk_create "); + return NULL; + } // Add in tail l_chunk->prev = a_chunks->chunks_first; if (a_chunks->chunks_first){ diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c index 04dcbcd786eadb01f9e6bec9af14ca7d6e4d7945..36a723f9e35034c6f741b7e2624591f95c417e80 100644 --- a/modules/type/blocks/dap_chain_cs_blocks.c +++ b/modules/type/blocks/dap_chain_cs_blocks.c @@ -47,6 +47,11 @@ typedef struct dap_chain_block_datum_index { UT_hash_handle hh; } dap_chain_block_datum_index_t; +struct cs_blocks_hal_item { + dap_chain_hash_fast_t hash; + UT_hash_handle hh; +}; + typedef struct dap_chain_cs_blocks_pvt { pthread_rwlock_t rwlock; @@ -78,6 +83,7 @@ typedef struct dap_chain_cs_blocks_pvt pthread_rwlock_t datums_lock; uint64_t fill_timeout; + struct cs_blocks_hal_item *hal; } dap_chain_cs_blocks_pvt_t; #define PVT(a) ((dap_chain_cs_blocks_pvt_t *)(a)->_pvt ) @@ -107,7 +113,7 @@ static dap_chain_atom_ptr_t s_callback_atom_iter_find_by_hash(dap_chain_atom_ite 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); -static dap_chain_atom_ptr_t s_callback_block_find_by_tx_hash(dap_chain_t * a_chain, dap_chain_hash_fast_t * a_tx_hash); +static dap_chain_atom_ptr_t s_callback_block_find_by_tx_hash(dap_chain_t * a_chain, dap_chain_hash_fast_t * a_tx_hash, size_t *a_block_size); static dap_chain_datum_t** s_callback_atom_get_datums(dap_chain_atom_ptr_t a_atom, size_t a_atom_size, size_t * a_datums_count); static dap_time_t s_chain_callback_atom_get_timestamp(dap_chain_atom_ptr_t a_atom) { return ((dap_chain_block_t *)a_atom)->hdr.ts_created; } @@ -202,6 +208,10 @@ void dap_chain_cs_blocks_deinit() int dap_chain_cs_blocks_new(dap_chain_t * a_chain, dap_config_t * a_chain_config) { dap_chain_cs_blocks_t * l_cs_blocks = DAP_NEW_Z(dap_chain_cs_blocks_t); + if (!l_cs_blocks) { + log_it(L_ERROR, "Memory allocation error in dap_chain_cs_blocks_new"); + return -1; + } a_chain->_inheritor = l_cs_blocks; l_cs_blocks->chain = a_chain; @@ -244,6 +254,10 @@ int dap_chain_cs_blocks_new(dap_chain_t * a_chain, dap_config_t * a_chain_config l_cs_blocks->callback_new_block_move = s_new_block_move; dap_chain_cs_blocks_pvt_t *l_cs_blocks_pvt = DAP_NEW_Z(dap_chain_cs_blocks_pvt_t); + if (!l_cs_blocks_pvt) { + log_it(L_ERROR, "Memory allocation error in dap_chain_cs_blocks_new"); + return -1; + } l_cs_blocks->_pvt = l_cs_blocks_pvt; pthread_rwlock_init(&l_cs_blocks_pvt->rwlock,NULL); pthread_rwlock_init(&l_cs_blocks_pvt->datums_lock, NULL); @@ -268,6 +282,21 @@ int dap_chain_cs_blocks_new(dap_chain_t * a_chain, dap_config_t * a_chain_config l_cs_blocks_pvt->fill_timeout = dap_config_get_item_uint64_default(a_chain_config, "blocks", "fill_timeout", 60) * 1000; // 1 min l_cs_blocks_pvt->blocks_count = 0; + uint16_t l_list_len = 0; + char **l_hard_accept_list = dap_config_get_array_str(a_chain_config, "blocks", "hard_accept_list", &l_list_len); + log_it(L_MSG, "HAL for blocks contains %d whitelisted events", l_list_len); + for (uint16_t i = 0; i < l_list_len; i++) { + struct cs_blocks_hal_item *l_hal_item = DAP_NEW_Z(struct cs_blocks_hal_item); + if (!l_hal_item){ + log_it(L_ERROR, "Memory allocation error in dap_chain_cs_dag_new"); + DAP_DEL_Z(l_cs_blocks_pvt); + DAP_DELETE(l_cs_blocks); + return -10; + } + dap_chain_hash_fast_from_str(l_hard_accept_list[i], &l_hal_item->hash); + HASH_ADD(hh, l_cs_blocks_pvt->hal, hash, sizeof(l_hal_item->hash), l_hal_item); + } + return 0; } @@ -460,6 +489,11 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply) char * l_gdb_group_mempool = dap_chain_net_get_gdb_group_mempool_new(l_chain); dap_chain_datum_t ** l_datums = DAP_NEW_Z_SIZE(dap_chain_datum_t*, sizeof(dap_chain_datum_t*)*l_datums_count); + if (!l_datums) { + log_it(L_ERROR, "Memory allocation error in s_cli_blocks"); + dap_cli_server_cmd_set_reply_text(a_str_reply,"Out of memory in s_cli_blocks"); + return -1; + } size_t l_datum_size = 0; dap_chain_datum_t * l_datum = (dap_chain_datum_t*) dap_global_db_get_sync(l_gdb_group_mempool, l_subcmd_str_arg , @@ -891,6 +925,10 @@ static int s_add_atom_datums(dap_chain_cs_blocks_t *a_blocks, dap_chain_block_ca l_ret++; // Save datum hash -> block_hash link in hash table dap_chain_block_datum_index_t *l_datum_index = DAP_NEW_Z(dap_chain_block_datum_index_t); + if (!l_datum_index) { + log_it(L_ERROR, "Memory allocation error in s_add_atom_datums"); + return 1; + } l_datum_index->ts_added = time(NULL); l_datum_index->block_cache = a_block_cache; l_datum_index->datum_hash = *l_datum_hash; @@ -1034,8 +1072,10 @@ static dap_chain_atom_verify_res_t s_callback_atom_add(dap_chain_t * a_chain, da // verify hashes and consensus dap_chain_atom_verify_res_t ret = s_callback_atom_verify (a_chain, a_atom, a_atom_size); - if (ret == ATOM_MOVE_TO_THRESHOLD) + if (ret == ATOM_MOVE_TO_THRESHOLD) { + //log_it(L_ATT, "Booo!"); ret = ATOM_REJECT; // TODO remove it when threshold will work + } if( ret == ATOM_ACCEPT){ int l_consensus_check = s_add_atom_to_blocks(l_blocks, l_block_cache); @@ -1082,11 +1122,23 @@ static dap_chain_atom_verify_res_t s_callback_atom_verify(dap_chain_t * a_chain, dap_chain_cs_blocks_pvt_t * l_blocks_pvt = PVT(l_blocks); assert(l_blocks_pvt); dap_chain_block_t * l_block = (dap_chain_block_t *) a_atom; + dap_chain_hash_fast_t l_block_hash; if(sizeof (l_block->hdr) >= a_atom_size){ log_it(L_WARNING,"Size of block is %zd that is equal or less then block's header size %zd",a_atom_size,sizeof (l_block->hdr)); return ATOM_REJECT; } + + // Hard accept list + if (l_blocks_pvt->hal) { + dap_hash_fast(l_block, a_atom_size, &l_block_hash); + struct cs_blocks_hal_item *l_hash_found = NULL; + HASH_FIND(hh, l_blocks_pvt->hal, &l_block_hash, sizeof(l_block_hash), l_hash_found); + if (l_hash_found) { + return ATOM_ACCEPT; + } + } + size_t l_meta_count = 0; dap_chain_block_meta_t ** l_meta= dap_chain_block_get_meta(l_block, a_atom_size, & l_meta_count); // Parse metadata @@ -1095,7 +1147,6 @@ static dap_chain_atom_verify_res_t s_callback_atom_verify(dap_chain_t * a_chain, dap_chain_hash_fast_t l_block_anchor_hash = {0}; uint64_t l_nonce = 0; uint64_t l_nonce2 = 0; - dap_chain_hash_fast_t l_block_hash; dap_chain_block_meta_extract(l_meta, l_meta_count, &l_block_prev_hash, @@ -1124,7 +1175,9 @@ static dap_chain_atom_verify_res_t s_callback_atom_verify(dap_chain_t * a_chain, &&!dap_hash_fast_is_blank(&l_block_hash)) log_it(L_NOTICE, "Accepting static genesis block"); else{ - log_it(L_WARNING,"Cant accept genesis block: seed mode not enabled or hash mismatch with static genesis block in configuration"); + char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE] = { '\0' }; + dap_hash_fast_to_str(&l_block_hash, l_hash_str, sizeof(l_hash_str)); + log_it(L_WARNING,"Cant accept genesis block: seed mode not enabled or hash mismatch with static genesis block %s in configuration", l_hash_str); return ATOM_REJECT; } } else { @@ -1154,6 +1207,10 @@ 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, bool a_with_treshold) { dap_chain_atom_iter_t * l_atom_iter = DAP_NEW_Z(dap_chain_atom_iter_t); + if (!l_atom_iter) { + log_it(L_ERROR, "Memory allocation error in s_callback_atom_iter_create"); + return NULL; + } l_atom_iter->chain = a_chain; l_atom_iter->cell_id = a_cell_id; l_atom_iter->with_treshold = a_with_treshold; @@ -1246,7 +1303,7 @@ static dap_chain_datum_t *s_callback_datum_find_by_hash(dap_chain_t *a_chain, da * @param a_tx_hash * @return atom_ptr */ -static dap_chain_atom_ptr_t s_callback_block_find_by_tx_hash(dap_chain_t * a_chain, dap_chain_hash_fast_t * a_tx_hash) +static dap_chain_atom_ptr_t s_callback_block_find_by_tx_hash(dap_chain_t * a_chain, dap_chain_hash_fast_t * a_tx_hash, size_t *a_block_size) { dap_chain_cs_blocks_t * l_cs_blocks = DAP_CHAIN_CS_BLOCKS(a_chain); dap_chain_block_datum_index_t *l_datum_index = NULL; @@ -1255,7 +1312,9 @@ static dap_chain_atom_ptr_t s_callback_block_find_by_tx_hash(dap_chain_t * a_cha pthread_rwlock_unlock(&PVT(l_cs_blocks)->datums_rwlock); if (!l_datum_index) return NULL; - return l_datum_index->block_cache; + if (a_block_size) + *a_block_size = l_datum_index->block_cache->block_size; + return l_datum_index->block_cache->block; } /** @@ -1377,9 +1436,21 @@ static dap_chain_atom_ptr_t *s_callback_atom_iter_get_lasts( dap_chain_atom_iter *a_links_size = 1; if (a_lasts_size_ptr) { *a_lasts_size_ptr = DAP_NEW_Z(size_t); + if (!a_lasts_size_ptr) { + log_it(L_ERROR, "Memory allocation error in s_callback_atom_iter_get_lasts"); + return NULL; + } (*a_lasts_size_ptr)[0] = l_block_cache_last->block_size; } dap_chain_atom_ptr_t *l_ret = DAP_NEW_Z(dap_chain_atom_ptr_t); + if (!l_ret) { + log_it(L_ERROR, "Memory allocation error in s_callback_atom_iter_get_lasts"); + return NULL; + } + if (!l_ret) { + log_it(L_ERROR, "Memory allocation error in s_callback_atom_iter_get_lasts"); + return NULL; + } l_ret[0] = l_block_cache_last->block; return l_ret; } @@ -1408,6 +1479,10 @@ static void s_callback_atom_iter_delete(dap_chain_atom_iter_t * a_atom_iter) static dap_chain_datum_iter_t *s_chain_callback_datum_iter_create(dap_chain_t *a_chain) { dap_chain_datum_iter_t *l_ret = DAP_NEW_Z(dap_chain_datum_iter_t); + if (!l_ret) { + log_it(L_ERROR, "Memory allocation error in s_chain_callback_datum_iter_create"); + return NULL; + } l_ret->chain = a_chain; return l_ret; } diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c index dffba69ad8fdccfdca9b5aaf69a36d5d0bb050be..f113ca6fa37658a60fa9ce8103bfb915bf2bf374 100644 --- a/modules/type/dag/dap_chain_cs_dag.c +++ b/modules/type/dag/dap_chain_cs_dag.c @@ -226,7 +226,16 @@ static void s_timer_process_callback(void *a_arg) int dap_chain_cs_dag_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg) { dap_chain_cs_dag_t * l_dag = DAP_NEW_Z(dap_chain_cs_dag_t); + if (!l_dag){ + log_it(L_ERROR, "Memory allocation error in dap_chain_cs_dag_new"); + return -1; + } l_dag->_pvt = DAP_NEW_Z(dap_chain_cs_dag_pvt_t); + if (!l_dag->_pvt){ + log_it(L_ERROR, "Memory allocation error in dap_chain_cs_dag_new"); + DAP_DELETE(l_dag); + return -1; + } l_dag->chain = a_chain; pthread_mutexattr_t l_mutex_attr; @@ -288,9 +297,16 @@ int dap_chain_cs_dag_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg) } } uint16_t l_list_len = 0; - char **l_hard_accept_list = dap_config_get_array_str(a_chain_cfg, "dag", "hard_accept_list", &l_list_len); + char **l_hard_accept_list = dap_config_get_array_str(a_chain_cfg, "dag-poa", "hard_accept_list", &l_list_len); + log_it(L_MSG, "HAL contains %d whitelisted events", l_list_len); for (uint16_t i = 0; i < l_list_len; i++) { dap_chain_cs_dag_hal_item_t *l_hal_item = DAP_NEW_Z(dap_chain_cs_dag_hal_item_t); + if (!l_hal_item){ + log_it(L_ERROR, "Memory allocation error in dap_chain_cs_dag_new"); + DAP_DEL_Z(l_dag->_pvt); + DAP_DELETE(l_dag); + return -1; + } dap_chain_hash_fast_from_str(l_hard_accept_list[i], &l_hal_item->hash); HASH_ADD(hh, l_dag->hal, hash, sizeof(l_hal_item->hash), l_hal_item); } @@ -335,6 +351,11 @@ static void s_dap_chain_cs_dag_threshold_free(dap_chain_cs_dag_t *a_dag) { HASH_ITER(hh, l_pvt->events_treshold, l_current, l_tmp) { if (l_current->ts_added < l_time_cut_off) { dap_chain_cs_dag_blocked_t *l_el = DAP_NEW(dap_chain_cs_dag_blocked_t); + if (!l_el) { + log_it(L_ERROR, "Memory allocation error in s_dap_chain_cs_dag_threshold_free"); + pthread_mutex_unlock(&l_pvt->events_mutex); + return; + } l_el->hash = l_current->hash; HASH_ADD(hh, l_pvt->removed_events_from_treshold, hash, sizeof(dap_chain_hash_fast_t), l_el); char *l_hash_dag = dap_hash_fast_to_str_new(&l_current->hash); @@ -477,6 +498,10 @@ static dap_chain_atom_verify_res_t s_chain_callback_atom_add(dap_chain_t * a_cha dap_chain_cs_dag_event_t * l_event = (dap_chain_cs_dag_event_t *) a_atom; dap_chain_cs_dag_event_item_t * l_event_item = DAP_NEW_Z(dap_chain_cs_dag_event_item_t); + if (!l_event_item) { + log_it(L_ERROR, "Memory allocation error in s_chain_callback_atom_add"); + return ATOM_REJECT; + } pthread_mutex_t *l_events_mutex = &PVT(l_dag)->events_mutex; l_event_item->event = l_event; l_event_item->event_size = a_atom_size; @@ -486,10 +511,10 @@ static dap_chain_atom_verify_res_t s_chain_callback_atom_add(dap_chain_t * a_cha dap_chain_cs_dag_event_calc_hash(l_event, a_atom_size, &l_event_hash); l_event_item->hash = l_event_hash; - char * l_event_hash_str = NULL; if(s_debug_more) { - l_event_hash_str = dap_chain_hash_fast_to_str_new(&l_event_item->hash); - log_it(L_DEBUG, "Processing event: %s... (size %zd)", l_event_hash_str,a_atom_size); + char l_event_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE] = { '\0' }; + dap_chain_hash_fast_to_str(&l_event_item->hash, l_event_hash_str, sizeof(l_event_hash_str)); + log_it(L_DEBUG, "Processing event: %s ... (size %zd)", l_event_hash_str,a_atom_size); } pthread_mutex_lock(l_events_mutex); @@ -511,7 +536,6 @@ static dap_chain_atom_verify_res_t s_chain_callback_atom_add(dap_chain_t * a_cha case ATOM_PASS: if(s_debug_more) { log_it(L_DEBUG, "Atom already present"); - DAP_DELETE(l_event_hash_str); } DAP_DELETE(l_event_item); return ret; @@ -573,8 +597,6 @@ static dap_chain_atom_verify_res_t s_chain_callback_atom_add(dap_chain_t * a_cha DAP_DELETE(l_event_item); // Neither added, nor freed break; } - if(s_debug_more) - DAP_DELETE(l_event_hash_str); return ret; } @@ -616,8 +638,10 @@ static size_t s_callback_add_datums(dap_chain_t *a_chain, dap_chain_datum_t **a_ } static bool s_chain_callback_datums_pool_proc(dap_chain_t *a_chain, dap_chain_datum_t *a_datum) { - if (!a_datum || !a_chain) - log_it(L_ERROR, "Datum or chain in mempool processing comes NULL"); + if (!a_datum || !a_chain){ + log_it(L_ERROR, "Datum or chain in mempool processing comes NULL in s_chain_callback_datums_pool_proc"); + return false; + } dap_chain_cs_dag_t * l_dag = DAP_CHAIN_CS_DAG(a_chain); /* If datum passes thru rounds, let's check if it wasn't added before */ @@ -785,11 +809,7 @@ static dap_chain_atom_verify_res_t s_chain_callback_atom_verify(dap_chain_t * a_ log_it(L_WARNING, "Event from another chain, possible corrupted event"); return ATOM_REJECT; } - if (!s_event_verify_size(l_event, a_atom_size)) { - if (s_debug_more) - log_it(L_WARNING,"Event size not equal to expected"); - return ATOM_REJECT; - } + // Hard accept list if (l_dag->hal) { dap_chain_hash_fast_t l_event_hash = { }; @@ -802,6 +822,12 @@ static dap_chain_atom_verify_res_t s_chain_callback_atom_verify(dap_chain_t * a_ return ATOM_ACCEPT; } } + if (!s_event_verify_size(l_event, a_atom_size)) { + if (s_debug_more) + log_it(L_WARNING,"Event size not equal to expected"); + return ATOM_REJECT; + } + // genesis or seed mode if (l_event->header.hash_count == 0){ if(s_seed_mode && !PVT(l_dag)->events){ @@ -896,6 +922,10 @@ void s_dag_events_lasts_process_new_last_event(dap_chain_cs_dag_t * a_dag, dap_c //add self dap_chain_cs_dag_event_item_t * l_event_last= DAP_NEW_Z(dap_chain_cs_dag_event_item_t); + if (!l_event_last) { + log_it(L_ERROR, "Memory allocation error in s_dag_events_lasts_process_new_last_event"); + return; + } l_event_last->ts_added = a_event_item->ts_added; l_event_last->event = a_event_item->event; l_event_last->event_size = a_event_item->event_size; @@ -1012,6 +1042,10 @@ static dap_chain_atom_iter_t* s_chain_callback_atom_iter_create_from(dap_chain_t dap_chain_atom_ptr_t a_atom, size_t a_atom_size) { dap_chain_atom_iter_t * l_atom_iter = DAP_NEW_Z(dap_chain_atom_iter_t); + if (!l_atom_iter) { + log_it(L_ERROR, "Memory allocation error in s_chain_callback_atom_iter_create_from"); + return NULL; + } l_atom_iter->chain = a_chain; l_atom_iter->cur = a_atom; l_atom_iter->cur_size = a_atom_size; @@ -1037,6 +1071,10 @@ static dap_chain_atom_iter_t* s_chain_callback_atom_iter_create_from(dap_chain_t static dap_chain_atom_iter_t *s_chain_callback_atom_iter_create(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id, bool a_with_treshold) { dap_chain_atom_iter_t * l_atom_iter = DAP_NEW_Z(dap_chain_atom_iter_t); + if (!l_atom_iter) { + log_it(L_ERROR, "Memory allocation error in s_chain_callback_atom_iter_create"); + return NULL; + } l_atom_iter->chain = a_chain; l_atom_iter->cell_id = a_cell_id; l_atom_iter->with_treshold = a_with_treshold; @@ -1063,6 +1101,10 @@ static dap_chain_datum_t **s_chain_callback_atom_get_datum(dap_chain_atom_ptr_t return NULL; dap_chain_datum_t **l_datums = DAP_NEW_Z(dap_chain_datum_t*); + if (!l_datums) { + log_it(L_ERROR, "Memory allocation error in s_chain_callback_atom_get_datum"); + return NULL; + } if (a_datums_count) *a_datums_count = 1; l_datums[0] = l_datum; @@ -1174,9 +1216,18 @@ static dap_chain_atom_ptr_t* s_chain_callback_atom_iter_get_links( dap_chain_ato if ( l_event->header.hash_count > 0){ dap_chain_atom_ptr_t * l_ret = DAP_NEW_Z_SIZE(dap_chain_atom_ptr_t, sizeof (dap_chain_atom_ptr_t) * l_event->header.hash_count ); + if (!l_ret) { + log_it(L_ERROR, "Memory allocation error in s_chain_callback_atom_iter_get_links"); + return NULL; + } if( a_links_size) *a_links_size = l_event->header.hash_count; *a_links_size_array = DAP_NEW_Z_SIZE(size_t, l_event->header.hash_count*sizeof (size_t)); + if (!a_links_size_array) { + log_it(L_ERROR, "Memory allocation error in s_chain_callback_atom_iter_get_links"); + DAP_DEL_Z(l_ret); + return NULL; + } for (uint16_t i = 0; i < l_event->header.hash_count; i++){ dap_chain_cs_dag_event_item_t * l_link_item = NULL; dap_chain_hash_fast_t * l_link_hash = (dap_chain_hash_fast_t *) @@ -1319,6 +1370,10 @@ static void s_chain_callback_atom_iter_delete(dap_chain_atom_iter_t * a_atom_ite static dap_chain_datum_iter_t *s_chain_callback_datum_iter_create(dap_chain_t *a_chain) { dap_chain_datum_iter_t *l_ret = DAP_NEW_Z(dap_chain_datum_iter_t); + if (!l_ret) { + log_it(L_ERROR, "Memory allocation error in s_chain_callback_datum_iter_create"); + return NULL; + } l_ret->chain = a_chain; return l_ret; } diff --git a/modules/type/dag/dap_chain_cs_dag_event.c b/modules/type/dag/dap_chain_cs_dag_event.c index c1600428d4bf37a469bbe5f7c8f6f1c7b2231f7b..9e5360fd37dbf253ca8154402cce791df6ec4326 100644 --- a/modules/type/dag/dap_chain_cs_dag_event.c +++ b/modules/type/dag/dap_chain_cs_dag_event.c @@ -230,6 +230,10 @@ static bool s_event_broadcast_send(dap_chain_cs_dag_event_round_broadcast_t *a_a void dap_chain_cs_dag_event_broadcast(dap_chain_cs_dag_t *a_dag, dap_store_obj_t *a_obj, dap_global_db_context_t *a_context) { dap_chain_cs_dag_event_round_broadcast_t *l_arg = DAP_NEW(dap_chain_cs_dag_event_round_broadcast_t); + if (!l_arg) { + log_it(L_ERROR, "Memory allocation error in dap_chain_cs_dag_event_broadcast"); + return; + } l_arg->dag = a_dag; l_arg->obj = dap_store_obj_copy(a_obj, 1); l_arg->context = a_context; diff --git a/modules/wallet/dap_chain_wallet.c b/modules/wallet/dap_chain_wallet.c index b3dbc6749120c8137ac7ca2153619e306bddb20d..d23c3681dec9fc86d859b7dc1e78f80bff1c716b 100644 --- a/modules/wallet/dap_chain_wallet.c +++ b/modules/wallet/dap_chain_wallet.c @@ -125,6 +125,10 @@ char *c_wallets_path; if ( !l_prec ) { l_prec = DAP_NEW_Z(dap_chain_wallet_n_pass_t); /* Get memory for new record */ + if (!l_prec) { + log_it(L_ERROR, "Memory allocation error in dap_chain_wallet_activate"); + return -EINVAL; + } *l_prec = l_rec; /* Fill it by data */ HASH_ADD_STR(s_wallet_n_pass, name, l_prec); /* Add into the hash-table */ }