diff --git a/dap-sdk b/dap-sdk index 4625ec3322889dc1ff69be0f45a32cbdff80f749..e66e1b75e024988a9391dc0ba58694af1813c796 160000 --- a/dap-sdk +++ b/dap-sdk @@ -1 +1 @@ -Subproject commit 4625ec3322889dc1ff69be0f45a32cbdff80f749 +Subproject commit e66e1b75e024988a9391dc0ba58694af1813c796 diff --git a/modules/chain/dap_chain.c b/modules/chain/dap_chain.c index 88288bb8d8566b27f791c7dc647c2d61330b4a77..de9f317ff87e7a9213a768a30213d4509e4a8eb4 100644 --- a/modules/chain/dap_chain.c +++ b/modules/chain/dap_chain.c @@ -544,7 +544,7 @@ bool dap_chain_has_file_store(dap_chain_t * a_chain) * @param l_chain * @return */ -int dap_chain_save_all (dap_chain_t * l_chain) +int dap_chain_save_all(dap_chain_t *l_chain) { int l_ret = 0; pthread_rwlock_rdlock(&l_chain->cell_rwlock); @@ -591,8 +591,13 @@ int dap_chain_load_all(dap_chain_t *a_chain) l_ret += dap_chain_cell_load(a_chain, l_cell); if (DAP_CHAIN_PVT(a_chain)->need_reorder) { const char *l_filename_backup = dap_strdup_printf("%s.unsorted", l_cell->file_storage_path); - remove(l_filename_backup); - rename(l_cell->file_storage_path, l_filename_backup); + if (remove(l_filename_backup) == -1) { + log_it(L_ERROR, "File %s doesn't exist", l_filename_backup); + } + if (rename(l_cell->file_storage_path, l_filename_backup)) { + log_it(L_ERROR, "Couldn't rename %s to %s", l_cell->file_storage_path, l_filename_backup); + } + DAP_DELETE(l_filename_backup); } } } @@ -721,8 +726,10 @@ ssize_t dap_chain_atom_save(dap_chain_t *a_chain, const uint8_t *a_atom, size_t size_t l_atom_treshold_size; l_atom_treshold = a_chain->callback_atom_add_from_treshold(a_chain, &l_atom_treshold_size); if (l_atom_treshold) { - dap_chain_cell_file_append(l_cell, l_atom_treshold, l_atom_treshold_size); - log_it(L_INFO, "Added atom from treshold"); + if (dap_chain_cell_file_append(l_cell, l_atom_treshold, l_atom_treshold_size) > 0) + log_it(L_INFO, "Added atom from treshold"); + else + log_it(L_ERROR, "Can't add atom from treshold"); } } while(l_atom_treshold); } diff --git a/modules/chain/dap_chain_cell.c b/modules/chain/dap_chain_cell.c index 623c0eee872cff38532e354cdffa67810d3f7725..d3c4fa308547f847cda956e417ced728ad631632 100644 --- a/modules/chain/dap_chain_cell.c +++ b/modules/chain/dap_chain_cell.c @@ -170,7 +170,21 @@ void dap_chain_cell_delete(dap_chain_cell_t *a_cell) a_cell->chain = NULL; a_cell->file_storage_path[0] = '\0'; pthread_rwlock_destroy(&a_cell->storage_rwlock); - DAP_DEL_Z(a_cell); + DAP_DELETE(a_cell); +} + +void dap_chain_cell_delete_all(dap_chain_t *a_chain) { + if (!a_chain) + return; + pthread_rwlock_wrlock(&a_chain->cell_rwlock); + dap_chain_cell_t *l_cell, *l_tmp; + HASH_ITER(hh, a_chain->cells, l_cell, l_tmp) { + dap_chain_cell_close(l_cell); + HASH_DEL(a_chain->cells, l_cell); + pthread_rwlock_destroy(&l_cell->storage_rwlock); + DAP_DELETE(l_cell); + } + pthread_rwlock_unlock(&a_chain->cell_rwlock); } /** @@ -243,42 +257,46 @@ int dap_chain_cell_load(dap_chain_t *a_chain, dap_chain_cell_t *a_cell) } -static bool s_file_write_header(dap_chain_cell_t *a_cell) +static int 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 + .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)) { + if(fwrite(&l_hdr, sizeof(l_hdr), 1, a_cell->file_storage) == 1) { 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); + fflush(a_cell->file_storage); + return 0; } 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 -1; } - return true; } -static ssize_t s_file_atom_add(dap_chain_cell_t *a_cell, dap_chain_atom_ptr_t a_atom, uint64_t a_atom_size) +static int s_file_atom_add(dap_chain_cell_t *a_cell, dap_chain_atom_ptr_t a_atom, uint64_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\"", + if (!a_atom || !a_atom_size) { + log_it(L_CRITICAL, "Invalid arguments"); + return -1; + } + if (fwrite(&a_atom_size, sizeof(a_atom_size), 1, a_cell->file_storage) != 1) { + 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) { + if (fwrite(a_atom, a_atom_size, 1, a_cell->file_storage) != 1) { 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; } - return a_atom_size + sizeof(a_atom_size); + return 0; } /** @@ -293,7 +311,7 @@ static ssize_t s_file_atom_add(dap_chain_cell_t *a_cell, dap_chain_atom_ptr_t a_ * @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) +ssize_t 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; @@ -302,69 +320,84 @@ int dap_chain_cell_file_append(dap_chain_cell_t *a_cell, const void *a_atom, siz a_cell->id.uint64, a_cell->file_storage_path); return -1; } - + size_t l_total_res = 0, l_count = 0; + bool l_err = false; pthread_rwlock_wrlock(&a_cell->storage_rwlock); - if (!a_cell->file_storage) { - a_cell->file_storage = fopen(a_cell->file_storage_path, "r+b"); + if (!a_atom || !a_atom_size) { + a_cell->file_storage = a_cell->file_storage + ? freopen(a_cell->file_storage_path, "w+b", a_cell->file_storage) + : fopen(a_cell->file_storage_path, "w+b"); if (!a_cell->file_storage) { - log_it(L_INFO, "Create chain cell"); - a_cell->file_storage = fopen(a_cell->file_storage_path, "w+b"); - 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; - } + log_it(L_ERROR, "Chain cell \"%s\" 0x%016"DAP_UINT64_FORMAT_X" cannot be opened", + a_cell->file_storage_path, + a_cell->id.uint64); + pthread_rwlock_unlock(&a_cell->storage_rwlock); + return -3; } - } - - fseek(a_cell->file_storage, 0L, SEEK_END); - 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)) { + if (s_file_write_header(a_cell)) { + log_it(L_ERROR, "Chain cell \"%s\" 0x%016"DAP_UINT64_FORMAT_X": can't fill header", a_cell->file_storage_path, a_cell->id.uint64); pthread_rwlock_unlock(&a_cell->storage_rwlock); - return -5; + return -4; } - } - - size_t l_total_wrote_bytes = 0, l_count = 0; - 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); 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, l_atom, l_atom_size); - if (l_atom_added_size < 0) { - l_total_wrote_bytes = l_atom_added_size; + dap_chain_atom_ptr_t l_atom; + uint64_t l_atom_size = 0; + for (l_atom = a_cell->chain->callback_atom_iter_get_first(l_atom_iter, &l_atom_size); + l_atom && l_atom_size; + l_atom = a_cell->chain->callback_atom_iter_get_next(l_atom_iter, &l_atom_size)) + { + if (s_file_atom_add(a_cell, l_atom, l_atom_size)) { + l_err = true; break; + } else { + l_total_res += l_atom_size + sizeof(uint64_t); + ++l_count; } - 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); + a_cell->file_storage = freopen(a_cell->file_storage_path, "a+b", a_cell->file_storage); + } else { + if (!a_cell->file_storage) + a_cell->file_storage = fopen(a_cell->file_storage_path, "a+b"); + if (!a_cell->file_storage) { + log_it(L_ERROR, "Chain cell \"%s\" 0x%016"DAP_UINT64_FORMAT_X" cannot be opened", + a_cell->file_storage_path, + a_cell->id.uint64); + pthread_rwlock_unlock(&a_cell->storage_rwlock); + return -3; + } else { + fseek(a_cell->file_storage, 0L, SEEK_END); + if (!ftell(a_cell->file_storage)) { // It's not garunteed that header has been yet added or not, regardless the descriptor validity + if (s_file_write_header(a_cell)) { + log_it(L_ERROR, "Chain cell \"%s\" 0x%016"DAP_UINT64_FORMAT_X": can't fill header", a_cell->file_storage_path, a_cell->id.uint64); + pthread_rwlock_unlock(&a_cell->storage_rwlock); + return -4; + } + } + } + if (s_file_atom_add(a_cell, a_atom, a_atom_size)) { + log_it(L_ERROR, "Chain cell \"%s\" 0x%016"DAP_UINT64_FORMAT_X": can't save atom!", + a_cell->file_storage_path, a_cell->id.uint64); + pthread_rwlock_unlock(&a_cell->storage_rwlock); + return -4; + } + ++l_count; + l_total_res = a_atom_size + sizeof(uint64_t); } - if (l_total_wrote_bytes > 0) + if (l_total_res) { fflush(a_cell->file_storage); - 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"); + log_it(L_DEBUG, "Chain cell \"%s\" 0x%016"DAP_UINT64_FORMAT_X": saved %zu atoms (%zu bytes)", + a_cell->file_storage_path, a_cell->id.uint64, l_count, l_total_res); + if (l_err) { + log_it(L_WARNING, "Not all data was saved due to writing error!"); } + } else { + log_it(L_ERROR, "Chain cell \"%s\" 0x%016"DAP_UINT64_FORMAT_X": nothing saved!", + a_cell->file_storage_path, a_cell->id.uint64); } pthread_rwlock_unlock(&a_cell->storage_rwlock); - return (int)l_total_wrote_bytes; + return l_total_res; } /** @@ -373,7 +406,7 @@ int dap_chain_cell_file_append(dap_chain_cell_t *a_cell, const void *a_atom, siz * @param a_cell dap_chain_cell_t * @return */ -int dap_chain_cell_file_update( dap_chain_cell_t * a_cell) +ssize_t dap_chain_cell_file_update(dap_chain_cell_t *a_cell) { return dap_chain_cell_file_append(a_cell, NULL, 0); } diff --git a/modules/chain/include/dap_chain_cell.h b/modules/chain/include/dap_chain_cell.h index c4e16bd2f90210a20cce0edd653a130596cdc523..bf3cc9a7a54e29499f8553c655cf6983953ac1ae 100644 --- a/modules/chain/include/dap_chain_cell.h +++ b/modules/chain/include/dap_chain_cell.h @@ -77,6 +77,7 @@ dap_chain_cell_t *dap_chain_cell_create_fill2(dap_chain_t *a_chain, const char * 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); +void dap_chain_cell_delete_all(dap_chain_t *a_chain); int dap_chain_cell_load(dap_chain_t *a_chain, dap_chain_cell_t *a_cell); -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); +ssize_t dap_chain_cell_file_update(dap_chain_cell_t *a_cell); +ssize_t dap_chain_cell_file_append(dap_chain_cell_t *a_cell,const void *a_atom, size_t a_atom_size); diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c index e9dd348f082d05d886f3adfc9baa511ee3294ffb..8d69af9d5f57689eabf2dd6353a331e716ae160a 100644 --- a/modules/net/dap_chain_net.c +++ b/modules/net/dap_chain_net.c @@ -2898,10 +2898,6 @@ int s_net_load(dap_chain_net_t *a_net) DAP_CHAIN_PVT(l_chain)->need_reorder = false; if (l_chain->callback_purge) { l_chain->callback_purge(l_chain); - pthread_rwlock_wrlock(&l_chain->cell_rwlock); - for (dap_chain_cell_t *it = l_chain->cells; it; it = it->hh.next) - dap_chain_cell_delete(it); - pthread_rwlock_unlock(&l_chain->cell_rwlock); dap_chain_ledger_purge(l_net->pub.ledger, false); dap_chain_ledger_set_fee(l_net->pub.ledger, uint256_0, c_dap_chain_addr_blank); dap_chain_net_decree_purge(l_net); diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c index 7e558f4a3909eba9372c911e794a5216bc66bb16..e56fc0473b75317469c87edf91981a8af84b736e 100644 --- a/modules/net/dap_chain_node_cli_cmd.c +++ b/modules/net/dap_chain_node_cli_cmd.c @@ -829,7 +829,7 @@ int com_global_db(int a_argc, char ** a_argv, char **a_str_reply) return -1; } dap_chain_cell_t *l_cell = dap_chain_cell_create_fill(l_chain, l_cell_id); - int l_ret = dap_chain_cell_file_update(l_cell); + int l_ret = (int)dap_chain_cell_file_update(l_cell); if(l_ret > 0) dap_cli_server_cmd_set_reply_text(a_str_reply, "cell added successfully"); else diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c index e5227ffdbc8c80b71974660a03fdca5b5a8a09cd..9f4f7a121e01c200ae7030596fe6e69edd3bbc46 100644 --- a/modules/type/blocks/dap_chain_cs_blocks.c +++ b/modules/type/blocks/dap_chain_cs_blocks.c @@ -898,10 +898,7 @@ static void s_callback_cs_blocks_purge(dap_chain_t *a_chain) dap_chain_block_chunks_delete(PVT(l_blocks)->chunks); PVT(l_blocks)->block_cache_last = NULL; PVT(l_blocks)->block_cache_first = NULL; - dap_chain_cell_t *l_cell = NULL, *l_cell_tmp = NULL; - HASH_ITER(hh, a_chain->cells, l_cell, l_cell_tmp) { - dap_chain_cell_delete(l_cell); - } + dap_chain_cell_delete_all(a_chain); PVT(l_blocks)->chunks = dap_chain_block_chunks_create(l_blocks); } diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c index 222e9295555555883b61e0ddf652506e331c0a05..9ba85421521b410a8b8a67dfc9de8f360b2eed79 100644 --- a/modules/type/dag/dap_chain_cs_dag.c +++ b/modules/type/dag/dap_chain_cs_dag.c @@ -402,10 +402,7 @@ static void s_dap_chain_cs_dag_purge(dap_chain_t *a_chain) DAP_DELETE(l_event_current); } pthread_mutex_unlock(&l_dag_pvt->events_mutex); - dap_chain_cell_t *l_cell_cur, *l_cell_tmp; - HASH_ITER(hh, a_chain->cells, l_cell_cur, l_cell_tmp) { - dap_chain_cell_close(l_cell_cur); - } + dap_chain_cell_delete_all(a_chain); } /**