From d9ff56f1d0bef0182243a0e0f2146dddaf1c8c65 Mon Sep 17 00:00:00 2001 From: cellframe <roman.khlopkov@demlabs.net> Date: Mon, 12 Dec 2022 17:55:54 +0300 Subject: [PATCH] [*] Chains swelling fix --- modules/chain/dap_chain_cell.c | 157 ++++++++++++--------- modules/chain/dap_chain_ledger.c | 2 +- modules/chain/include/dap_chain.h | 2 +- modules/chain/include/dap_chain_cell.h | 12 +- modules/consensus/none/dap_chain_cs_none.c | 2 +- modules/net/dap_chain_node_cli_cmd.c | 12 +- modules/type/blocks/dap_chain_cs_blocks.c | 6 +- modules/type/dag/dap_chain_cs_dag.c | 2 +- 8 files changed, 110 insertions(+), 85 deletions(-) diff --git a/modules/chain/dap_chain_cell.c b/modules/chain/dap_chain_cell.c index ff45cc9fb8..5cb49c37e9 100644 --- a/modules/chain/dap_chain_cell.c +++ b/modules/chain/dap_chain_cell.c @@ -156,7 +156,7 @@ void dap_chain_cell_delete(dap_chain_cell_t *a_cell) pthread_rwlock_unlock(&a_cell->chain->cell_rwlock); } a_cell->chain = NULL; - DAP_DEL_Z(a_cell->file_storage_path) + DAP_DEL_Z(a_cell->file_storage_path); pthread_rwlock_destroy(&a_cell->storage_rwlock); DAP_DEL_Z(a_cell); } @@ -210,7 +210,7 @@ int dap_chain_cell_load(dap_chain_t * a_chain, const char * a_cell_file_path) ret = -5; break; } - unsigned long l_read = fread(l_element, 1, l_el_size, l_f); + unsigned long l_read = fread((void *)l_element, 1, l_el_size, l_f); if(l_read == l_el_size) { dap_chain_atom_verify_res_t l_res = a_chain->callback_atom_add(a_chain, l_element, l_el_size); // !!! blocking GDB call !!! if (l_res == ATOM_PASS || l_res == ATOM_REJECT) { @@ -236,6 +236,50 @@ int dap_chain_cell_load(dap_chain_t * a_chain, const char * a_cell_file_path) } +static bool s_file_write_header(dap_chain_cell_t *a_cell) +{ + fseek(a_cell->file_storage, 0L, SEEK_SET); + dap_chain_cell_file_header_t l_hdr = { + .signature = DAP_CHAIN_CELL_FILE_SIGNATURE, + .version = DAP_CHAIN_CELL_FILE_VERSION, + .type = DAP_CHAIN_CELL_FILE_TYPE_RAW, + .chain_id = { .uint64 = a_cell->id.uint64 }, + .chain_net_id = a_cell->chain->net_id + }; + if(fwrite(&l_hdr, 1, sizeof(l_hdr), a_cell->file_storage) == sizeof(l_hdr)) { + log_it(L_NOTICE, "Initialized file storage for cell 0x%016"DAP_UINT64_FORMAT_X" ( %s )", + a_cell->id.uint64, a_cell->file_storage_path); + } else { + log_it(L_ERROR, "Can't init file storage for cell 0x%016"DAP_UINT64_FORMAT_X" ( %s )", + a_cell->id.uint64, a_cell->file_storage_path); + return false; + } + return true; +} + +static ssize_t s_file_atom_add(dap_chain_cell_t *a_cell, dap_chain_atom_ptr_t a_atom, size_t a_atom_size) +{ + if (fwrite(&a_atom_size, 1, sizeof(a_atom_size), a_cell->file_storage) != sizeof(a_atom_size)) { + log_it (L_ERROR,"Can't write atom data size from cell 0x%016"DAP_UINT64_FORMAT_X" in \"%s\"", + a_cell->id.uint64, + a_cell->file_storage_path); + return -2; + } + if (fwrite(a_atom, 1, a_atom_size, a_cell->file_storage) != a_atom_size) { + log_it (L_ERROR, "Can't write data from cell 0x%016"DAP_UINT64_FORMAT_X" to the file \"%s\"", + a_cell->id.uint64, + a_cell->file_storage_path); + return -3; + } + if(a_cell->chain && a_cell->chain->atom_notifiers ){ + for( dap_list_t * l_iter = a_cell->chain->atom_notifiers;l_iter; l_iter = dap_list_next(l_iter) ){ + dap_chain_atom_notifier_t * i = (dap_chain_atom_notifier_t *) l_iter->data; + i->callback(i->arg, a_cell->chain, a_cell->id, (void *)a_atom, a_atom_size); + } + } + return a_atom_size + sizeof(a_atom_size); +} + /** * @brief s_cell_file_append * add atoms to selected chain @@ -248,7 +292,7 @@ int dap_chain_cell_load(dap_chain_t * a_chain, const char * a_cell_file_path) * @param a_atom_size * @return */ -int dap_chain_cell_file_append( dap_chain_cell_t * a_cell, const void* a_atom, size_t a_atom_size) +int dap_chain_cell_file_append(dap_chain_cell_t *a_cell, const void *a_atom, size_t a_atom_size) { if(!a_cell) return -1; @@ -257,7 +301,9 @@ int dap_chain_cell_file_append( dap_chain_cell_t * a_cell, const void* a_atom, s a_cell->id.uint64, a_cell->file_storage_path); return -1; } - if(!a_cell->file_storage) { + + pthread_rwlock_wrlock(&a_cell->storage_rwlock); + if (!a_cell->file_storage) { char l_file_path[MAX_PATH] = {'\0'}; dap_snprintf(l_file_path, MAX_PATH, "%s/%s", DAP_CHAIN_PVT(a_cell->chain)->file_storage_dir, a_cell->file_storage_path); @@ -265,86 +311,61 @@ int dap_chain_cell_file_append( dap_chain_cell_t * a_cell, const void* a_atom, s if (!a_cell->file_storage) { log_it(L_INFO, "Create chain cell"); a_cell->file_storage = fopen(l_file_path, "w+b"); - } - if (!a_cell->file_storage) { - log_it(L_ERROR, "Chain cell \"%s\" cannot be opened 0x%016"DAP_UINT64_FORMAT_X, - a_cell->file_storage_path, - a_cell->id.uint64); - return -3; + if (!a_cell->file_storage) { + log_it(L_ERROR, "Chain cell \"%s\" (0x%016"DAP_UINT64_FORMAT_X") cannot be created", + a_cell->file_storage_path, + a_cell->id.uint64); + pthread_rwlock_unlock(&a_cell->storage_rwlock); + return -3; + } else if (s_file_write_header(a_cell)) {// fill the header + pthread_rwlock_unlock(&a_cell->storage_rwlock); + return -4; + } } } - pthread_rwlock_wrlock(&a_cell->storage_rwlock); + fseek(a_cell->file_storage, 0L, SEEK_END); - if (ftell(a_cell->file_storage) < (long)sizeof(dap_chain_cell_file_header_t)) { // fill the header - fseek(a_cell->file_storage, 0L, SEEK_SET); - dap_chain_cell_file_header_t l_hdr = { - .signature = DAP_CHAIN_CELL_FILE_SIGNATURE, - .version = DAP_CHAIN_CELL_FILE_VERSION, - .type = DAP_CHAIN_CELL_FILE_TYPE_RAW, - .chain_id = { .uint64 = a_cell->id.uint64 }, - .chain_net_id = a_cell->chain->net_id - }; - if(fwrite(&l_hdr, 1, sizeof(l_hdr), a_cell->file_storage) == sizeof(l_hdr)) { - log_it(L_NOTICE, "Initialized file storage for cell 0x%016"DAP_UINT64_FORMAT_X" ( %s )", - a_cell->id.uint64, a_cell->file_storage_path); - } else { - log_it(L_ERROR, "Can't init file storage for cell 0x%016"DAP_UINT64_FORMAT_X" ( %s )", - a_cell->id.uint64, a_cell->file_storage_path); - dap_chain_cell_close(a_cell); - return -4; + if (ftell(a_cell->file_storage) < (long)sizeof(dap_chain_cell_file_header_t)) { + log_it(L_WARNING, "Corrupted chain file header, rewrite it"); + if (!s_file_write_header(a_cell)) { + pthread_rwlock_unlock(&a_cell->storage_rwlock); + return -5; } } - // if no atom provided in arguments, we flush all the atoms in given chain - size_t l_atom_size = a_atom_size ? a_atom_size : 0; + size_t l_total_wrote_bytes = 0, l_count = 0; - dap_chain_atom_iter_t *l_atom_iter = a_atom ? NULL : a_cell->chain->callback_atom_iter_create(a_cell->chain, a_cell->id, 0); - if (!a_atom) { + if (a_atom && a_atom_size) + l_total_wrote_bytes = s_file_atom_add(a_cell, a_atom, a_atom_size); + else { // if no atom provided in arguments, we flush all the atoms in given chain + size_t l_atom_size = 0; fseek(a_cell->file_storage, sizeof(dap_chain_cell_file_header_t), SEEK_SET); - } - for (dap_chain_atom_ptr_t l_atom = a_atom ? (dap_chain_atom_ptr_t)a_atom : a_cell->chain->callback_atom_iter_get_first(l_atom_iter, &l_atom_size); - l_atom; - l_atom = a_atom ? NULL : a_cell->chain->callback_atom_iter_get_next(l_atom_iter, &l_atom_size), l_count++) - { - if (fwrite(&l_atom_size, 1, sizeof(l_atom_size), a_cell->file_storage) != sizeof(l_atom_size)) { - log_it (L_ERROR,"Can't write atom data size from cell 0x%016"DAP_UINT64_FORMAT_X" in \"%s\"", - a_cell->id.uint64, - a_cell->file_storage_path); - dap_chain_cell_close(a_cell); - l_total_wrote_bytes = -2; - break; - } - l_total_wrote_bytes += sizeof(l_atom_size); - if (fwrite(l_atom, 1, l_atom_size, a_cell->file_storage) != l_atom_size) { - log_it (L_ERROR, "Can't write data from cell 0x%016"DAP_UINT64_FORMAT_X" to the file \"%s\"", - a_cell->id.uint64, - a_cell->file_storage_path); - dap_chain_cell_close(a_cell); - l_total_wrote_bytes = -3; - break; - } - l_total_wrote_bytes += l_atom_size; - - if(a_cell->chain && a_cell->chain->atom_notifiers ){ - for( dap_list_t * l_iter = a_cell->chain->atom_notifiers;l_iter; l_iter = dap_list_next(l_iter) ){ - dap_chain_atom_notifier_t * i = (dap_chain_atom_notifier_t *) l_iter->data; - i->callback(i->arg, a_cell->chain, a_cell->id, (void *)l_atom, l_atom_size); + dap_chain_atom_iter_t *l_atom_iter = a_cell->chain->callback_atom_iter_create(a_cell->chain, a_cell->id, 0); + dap_chain_atom_ptr_t l_atom = a_cell->chain->callback_atom_iter_get_first(l_atom_iter, &l_atom_size); + while (l_atom && l_atom_size && ++l_count) { + ssize_t l_atom_added_size = s_file_atom_add(a_cell, a_atom, a_atom_size); + if (l_atom_added_size < 0) { + l_total_wrote_bytes = l_atom_added_size; + break; } + l_total_wrote_bytes += l_atom_added_size; + l_atom = a_cell->chain->callback_atom_iter_get_next(l_atom_iter, &l_atom_size); } + a_cell->chain->callback_atom_iter_delete(l_atom_iter); } - if (l_total_wrote_bytes > 0) { + + if (l_total_wrote_bytes > 0) fflush(a_cell->file_storage); - if (!a_atom) { + if (!a_atom) { + if (l_total_wrote_bytes > 0) { ftruncate(fileno(a_cell->file_storage), l_total_wrote_bytes + sizeof(dap_chain_cell_file_header_t)); log_it(L_DEBUG, "Saved %zu atoms (total %zu bytes", l_count, l_total_wrote_bytes); + } else { + ftruncate(fileno(a_cell->file_storage), sizeof(dap_chain_cell_file_header_t)); + s_file_write_header(a_cell); + log_it(L_WARNING, "Nothing to save, event table is empty. Rewrite the file header"); } - } else if (!a_atom) { - log_it(L_WARNING, "Nothing to save, event table is empty"); } - pthread_rwlock_unlock(&a_cell->storage_rwlock); - if (l_atom_iter) { - a_cell->chain->callback_atom_iter_delete(l_atom_iter); - } return (int)l_total_wrote_bytes; } diff --git a/modules/chain/dap_chain_ledger.c b/modules/chain/dap_chain_ledger.c index 8e0ccceda4..68692f66be 100644 --- a/modules/chain/dap_chain_ledger.c +++ b/modules/chain/dap_chain_ledger.c @@ -1189,7 +1189,7 @@ static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_ite l_addr_str); DAP_DELETE(l_addr_str); DAP_DELETE(l_addrs); - DAP_DEL_Z(a_token_item->tx_recv_allow) + DAP_DEL_Z(a_token_item->tx_recv_allow); return -11; } } diff --git a/modules/chain/include/dap_chain.h b/modules/chain/include/dap_chain.h index 89d344a732..87567372f6 100644 --- a/modules/chain/include/dap_chain.h +++ b/modules/chain/include/dap_chain.h @@ -41,7 +41,7 @@ typedef struct dap_chain_cell dap_chain_cell_t; typedef struct dap_ledger dap_ledger_t; // Atomic element -typedef void * dap_chain_atom_ptr_t; +typedef const void * dap_chain_atom_ptr_t; // Atomic element iterator typedef struct dap_chain_atom_iter{ diff --git a/modules/chain/include/dap_chain_cell.h b/modules/chain/include/dap_chain_cell.h index 8ca6a758cb..693090f310 100644 --- a/modules/chain/include/dap_chain_cell.h +++ b/modules/chain/include/dap_chain_cell.h @@ -74,11 +74,11 @@ typedef struct dap_chain_cell_decl{ int dap_chain_cell_init(void); -dap_chain_cell_t * dap_chain_cell_create_fill(dap_chain_t * a_chain, dap_chain_cell_id_t a_cell_id); -dap_chain_cell_t * dap_chain_cell_create_fill2(dap_chain_t * a_chain, const char *a_filename); -dap_chain_cell_t * dap_chain_cell_find_by_id(dap_chain_t * a_chain, dap_chain_cell_id_t a_cell_id); +dap_chain_cell_t *dap_chain_cell_create_fill(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id); +dap_chain_cell_t *dap_chain_cell_create_fill2(dap_chain_t *a_chain, const char *a_filename); +dap_chain_cell_t *dap_chain_cell_find_by_id(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id); void dap_chain_cell_close(dap_chain_cell_t *a_cell); void dap_chain_cell_delete(dap_chain_cell_t *a_cell); -int dap_chain_cell_load(dap_chain_t * a_chain, const char * a_cell_file_path); -int dap_chain_cell_file_update( dap_chain_cell_t * a_cell); -int dap_chain_cell_file_append( dap_chain_cell_t * a_cell,const void* a_atom, size_t a_atom_size); +int dap_chain_cell_load(dap_chain_t *a_chain, const char *a_cell_file_path); +int dap_chain_cell_file_update(dap_chain_cell_t *a_cell); +int dap_chain_cell_file_append(dap_chain_cell_t *a_cell,const void *a_atom, size_t a_atom_size); diff --git a/modules/consensus/none/dap_chain_cs_none.c b/modules/consensus/none/dap_chain_cs_none.c index 80faa8c738..38a53b26a5 100644 --- a/modules/consensus/none/dap_chain_cs_none.c +++ b/modules/consensus/none/dap_chain_cs_none.c @@ -596,7 +596,7 @@ static dap_chain_datum_t **s_chain_callback_atom_get_datum(dap_chain_atom_ptr_t { UNUSED(a_atom_size); if (a_atom){ - dap_chain_datum_t * l_datum = a_atom; + 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 (a_datums_count) diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c index 60fa016796..43861b7d3c 100644 --- a/modules/net/dap_chain_node_cli_cmd.c +++ b/modules/net/dap_chain_node_cli_cmd.c @@ -5552,12 +5552,14 @@ static int s_check_cmd(int a_arg_index, int a_argc, char **a_argv, char **a_str_ dap_chain_atom_iter_t *l_iter = NULL; dap_chain_cell_t *l_cell_tmp = NULL; dap_chain_cell_t *l_cell = NULL; - size_t l_size = 0; + size_t l_atom_size = 0, l_datums_count = 0; HASH_ITER(hh, l_chain->cells, l_cell, l_cell_tmp) { l_iter = l_cell->chain->callback_atom_iter_create(l_cell->chain, l_cell->id, 0); - dap_chain_datum_t *l_datum = l_cell->chain->callback_atom_find_by_hash(l_iter, &l_hash_tmp, &l_size); - if (l_datum) { + dap_chain_atom_ptr_t l_atom = l_cell->chain->callback_atom_find_by_hash(l_iter, &l_hash_tmp, &l_atom_size); + dap_chain_datum_t **l_datums = l_cell->chain->callback_atom_get_datums(l_atom, l_atom_size, &l_datums_count); + for (size_t i = 0; i < l_datums_count; i++) { + dap_chain_datum_t *l_datum = l_datums[i]; dap_hash_fast_t l_hash; dap_hash_fast(l_datum->data, l_datum->header.data_size, &l_hash); if (!memcmp(l_hash_tmp.raw, l_hash.raw, DAP_CHAIN_HASH_FAST_SIZE)) { @@ -5566,11 +5568,13 @@ static int s_check_cmd(int a_arg_index, int a_argc, char **a_argv, char **a_str_ break; } } + DAP_DEL_Z(l_datums); + l_cell->chain->callback_atom_iter_delete(l_iter); } end: - if (l_gdb_group) DAP_FREE(l_gdb_group); + DAP_DEL_Z(l_gdb_group); if (!found) { dap_cli_server_cmd_set_reply_text(a_str_reply, "not found!"); diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c index 54c65b26dd..3952e6674d 100644 --- a/modules/type/blocks/dap_chain_cs_blocks.c +++ b/modules/type/blocks/dap_chain_cs_blocks.c @@ -623,8 +623,8 @@ static void s_callback_delete(dap_chain_t * a_chain) pthread_rwlock_unlock(&PVT(l_blocks)->rwlock); pthread_rwlock_destroy(&PVT(l_blocks)->rwlock); pthread_rwlock_destroy(&PVT(l_blocks)->datums_lock); - DAP_DEL_Z(l_blocks->_inheritor) - DAP_DEL_Z(l_blocks->_pvt) + DAP_DEL_Z(l_blocks->_inheritor); + DAP_DEL_Z(l_blocks->_pvt); log_it(L_INFO, "Block destructed"); } @@ -1029,7 +1029,7 @@ static dap_chain_datum_tx_t* s_callback_atom_iter_find_by_tx_hash(dap_chain_t * 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) { assert(a_datums_count); - dap_chain_datum_t ** l_ret = dap_chain_block_get_datums(a_atom, a_atom_size,a_datums_count); + dap_chain_datum_t ** l_ret = dap_chain_block_get_datums((dap_chain_block_t *)a_atom, a_atom_size,a_datums_count); return l_ret; } diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c index f5316eea35..3ee05d0ec7 100644 --- a/modules/type/dag/dap_chain_cs_dag.c +++ b/modules/type/dag/dap_chain_cs_dag.c @@ -1353,7 +1353,7 @@ static int s_cli_dag(int argc, char ** argv, char **a_str_reply) // If not verify only mode we add if ( ! l_verify_only ){ dap_chain_atom_ptr_t l_new_atom = DAP_DUP_SIZE(l_event, l_event_size); // produce deep copy of event; - memcpy(l_new_atom, l_event, l_event_size); + memcpy((void *)l_new_atom, l_event, l_event_size); if(s_chain_callback_atom_add(l_chain, l_new_atom,l_event_size) < 0) { // Add new atom in chain DAP_DELETE(l_new_atom); dap_string_append_printf(l_str_ret_tmp, "Event %s not added in chain\n", l_objs[i].key); -- GitLab