From 3cc804a71e23482b6db72707b42a2a8545ee3d17 Mon Sep 17 00:00:00 2001 From: "Constantin P." <papizh.konstantin@demlabs.net> Date: Mon, 9 Dec 2024 12:46:15 +0700 Subject: [PATCH 01/11] v1 --- modules/chain/dap_chain.c | 3 +- modules/chain/dap_chain_cell.c | 12 +- modules/ledger/dap_chain_ledger.c | 88 +++++------- modules/ledger/dap_chain_ledger_token.c | 8 +- modules/ledger/dap_chain_ledger_tx.c | 28 ++-- modules/ledger/include/dap_chain_ledger_pvt.h | 12 +- modules/net/dap_chain_net.c | 130 +++++++----------- .../node-cli/dap_chain_node_cli_cmd_token.c | 39 +++--- modules/node-cli/dap_chain_node_cli_cmd_tx.c | 28 +--- 9 files changed, 144 insertions(+), 204 deletions(-) diff --git a/modules/chain/dap_chain.c b/modules/chain/dap_chain.c index bf407fea20..dd1ed571c4 100644 --- a/modules/chain/dap_chain.c +++ b/modules/chain/dap_chain.c @@ -546,8 +546,7 @@ int dap_chain_load_all(dap_chain_t *a_chain) return -3; } for (struct dirent *l_dir_entry = readdir(l_dir); l_dir_entry != NULL; l_dir_entry = readdir(l_dir)) { - const char * l_filename = l_dir_entry->d_name; - const char l_suffix[] = ".dchaincell"; + const char *l_filename = l_dir_entry->d_name, l_suffix[] = ".dchaincell"; size_t l_suffix_len = strlen(l_suffix); if (!strncmp(l_filename + strlen(l_filename) - l_suffix_len, l_suffix, l_suffix_len)) { uint64_t l_cell_id_uint64 = 0; diff --git a/modules/chain/dap_chain_cell.c b/modules/chain/dap_chain_cell.c index 86f8a43330..4319d582a0 100644 --- a/modules/chain/dap_chain_cell.c +++ b/modules/chain/dap_chain_cell.c @@ -103,8 +103,7 @@ int dap_chain_cell_init(void) } #endif - //s_cells_path = dap_config_get_item_str(g_config,"resources","cells_storage"); - return 0; + return 0; } #ifndef DAP_OS_WINDOWS @@ -147,7 +146,8 @@ DAP_STATIC_INLINE int s_cell_map_new_volume(dap_chain_cell_t *a_cell, size_t a_f NTSTATUS err = pfnNtCreateSection(&hSection, SECTION_MAP_READ|SECTION_EXTEND_SIZE|SECTION_MAP_WRITE, NULL, &SectionSize, PAGE_READWRITE, SEC_RESERVE, (HANDLE)_get_osfhandle(fileno(a_cell->file_storage))); if ( !NT_SUCCESS(err) ) - return log_it(L_ERROR, "NtCreateSection() failed, status %lx", err), -1; + return log_it(L_ERROR, "NtCreateSection() failed, status %lx: \"%s\"", + err, dap_str_ntstatus(err) ), -1; a_cell->map_range_bounds = dap_list_append(a_cell->map_range_bounds, hSection); } #endif @@ -168,7 +168,8 @@ DAP_STATIC_INLINE int s_cell_map_new_volume(dap_chain_cell_t *a_cell, size_t a_f err = pfnNtMapViewOfSection(hSection, GetCurrentProcess(), (HANDLE)&a_cell->map, 0, 0, &Offset, &l_map_size, ViewUnmap, MEM_RESERVE, PAGE_WRITECOPY); if ( !NT_SUCCESS(err) ) - return NtClose(hSection), log_it(L_ERROR, "NtMapViewOfSection() failed, status %lx", err), -1; + return NtClose(hSection), log_it(L_ERROR, "NtMapViewOfSection() failed, status %lx: \"%s\"", + err, dap_str_ntstatus(err) ), -1; #else if (a_load) s_cell_reclaim_cur_volume(a_cell); @@ -658,7 +659,8 @@ ssize_t dap_chain_cell_file_append(dap_chain_cell_t *a_cell, const void *a_atom, HANDLE hSection = (HANDLE)a_cell->map_range_bounds->data; NTSTATUS err = pfnNtExtendSection(hSection, &SectionSize); if ( !NT_SUCCESS(err) ) { - log_it(L_ERROR, "NtExtendSection() failed, status %lx", err); + log_it(L_ERROR, "NtExtendSection() failed, status %lx: \"%s\"", + err, dap_str_ntstatus(err) ); l_err = true; } } diff --git a/modules/ledger/dap_chain_ledger.c b/modules/ledger/dap_chain_ledger.c index 3c81df968e..e6224f2f5d 100644 --- a/modules/ledger/dap_chain_ledger.c +++ b/modules/ledger/dap_chain_ledger.c @@ -244,25 +244,12 @@ void dap_ledger_deinit() */ static dap_ledger_t *dap_ledger_handle_new(void) { - dap_ledger_t *l_ledger = DAP_NEW_Z(dap_ledger_t); - if ( !l_ledger ) { - log_it(L_CRITICAL, "%s", c_error_memory_alloc); - 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_CRITICAL, "%s", c_error_memory_alloc); - 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); - pthread_rwlock_init(&l_ledger_pvt->threshold_txs_rwlock , NULL); - pthread_rwlock_init(&l_ledger_pvt->balance_accounts_rwlock , NULL); - pthread_rwlock_init(&l_ledger_pvt->stake_lock_rwlock, NULL); - pthread_rwlock_init(&l_ledger_pvt->rewards_rwlock, NULL); + dap_ledger_t *l_ledger = DAP_NEW_Z_RET_VAL_IF_FAIL(dap_ledger_t, NULL); + dap_ledger_private_t *l_ledger_pvt = l_ledger->_internal = DAP_NEW_Z_RET_VAL_IF_FAIL(dap_ledger_private_t, NULL, l_ledger); + + l_ledger_pvt->ledger_rwlock = l_ledger_pvt->tokens_rwlock = l_ledger_pvt->threshold_txs_rwlock + = l_ledger_pvt->balance_accounts_rwlock = l_ledger_pvt->stake_lock_rwlock = l_ledger_pvt->rewards_rwlock + = PTHREAD_RWLOCK_INITIALIZER; return l_ledger; } @@ -275,7 +262,6 @@ void dap_ledger_handle_free(dap_ledger_t *a_ledger) { if(!a_ledger) return; - log_it(L_INFO,"Ledger for network %s destroyed", a_ledger->net->pub.name); // Destroy Read/Write Lock pthread_rwlock_destroy(&PVT(a_ledger)->ledger_rwlock); pthread_rwlock_destroy(&PVT(a_ledger)->tokens_rwlock); @@ -283,8 +269,8 @@ void dap_ledger_handle_free(dap_ledger_t *a_ledger) pthread_rwlock_destroy(&PVT(a_ledger)->balance_accounts_rwlock); pthread_rwlock_destroy(&PVT(a_ledger)->stake_lock_rwlock); pthread_rwlock_destroy(&PVT(a_ledger)->rewards_rwlock); - DAP_DELETE(PVT(a_ledger)); - DAP_DELETE(a_ledger); + DAP_DEL_MULTY(PVT(a_ledger), a_ledger); + log_it(L_INFO,"Ledger for network %s destroyed", a_ledger->net->pub.name); } @@ -606,34 +592,36 @@ json_object *dap_ledger_balance_info(dap_ledger_t *a_ledger, size_t a_limit, siz int dap_ledger_pvt_threshold_txs_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash) { - dap_ledger_tx_item_t *l_item_tmp = NULL; + dap_ledger_tx_item_t *l_item = NULL; dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); unsigned l_hash_value = 0; HASH_VALUE(a_tx_hash, sizeof(*a_tx_hash), l_hash_value); - pthread_rwlock_rdlock(&l_ledger_pvt->threshold_txs_rwlock); - HASH_FIND_BYHASHVALUE(hh, l_ledger_pvt->threshold_txs, a_tx_hash, sizeof(*a_tx_hash), l_hash_value, l_item_tmp); + pthread_rwlock_wrlock(&l_ledger_pvt->threshold_txs_rwlock); + HASH_FIND_BYHASHVALUE(hh, l_ledger_pvt->threshold_txs, a_tx_hash, sizeof(*a_tx_hash), l_hash_value, l_item); unsigned long long l_threshold_txs_count = HASH_COUNT(l_ledger_pvt->threshold_txs); - if (!l_item_tmp) { + if (!l_item) { if (l_threshold_txs_count >= s_threshold_txs_max) { + pthread_rwlock_unlock(&l_ledger_pvt->threshold_txs_rwlock); debug_if(g_debug_ledger, L_WARNING, "Threshold for transactions is overfulled (%zu max), dropping down tx %s, added nothing", s_threshold_txs_max, dap_hash_fast_to_str_static(a_tx_hash)); return -2; } - l_item_tmp = DAP_NEW_Z(dap_ledger_tx_item_t); - if ( !l_item_tmp ) { + if (!( l_item = DAP_NEW_Z(dap_ledger_tx_item_t) )) { + pthread_rwlock_unlock(&l_ledger_pvt->threshold_txs_rwlock); log_it(L_CRITICAL, "%s", c_error_memory_alloc); return -1; } - l_item_tmp->tx_hash_fast = *a_tx_hash; - l_item_tmp->tx = l_ledger_pvt->mapped ? a_tx : DAP_DUP_SIZE(a_tx, dap_chain_datum_tx_get_size(a_tx)); - if ( !l_item_tmp->tx ) { - DAP_DELETE(l_item_tmp); + l_item->tx_hash_fast = *a_tx_hash; + l_item->tx = is_ledger_mapped(l_ledger_pvt) ? a_tx : DAP_DUP_SIZE(a_tx, dap_chain_datum_tx_get_size(a_tx)); + if ( !l_item->tx ) { + DAP_DELETE(l_item); + pthread_rwlock_unlock(&l_ledger_pvt->threshold_txs_rwlock); log_it(L_CRITICAL, "%s", c_error_memory_alloc); return -1; } - l_item_tmp->ts_added = dap_nanotime_now(); - l_item_tmp->cache_data.ts_created = a_tx->header.ts_created; - HASH_ADD_BYHASHVALUE(hh, l_ledger_pvt->threshold_txs, tx_hash_fast, sizeof(dap_chain_hash_fast_t), l_hash_value, l_item_tmp); + l_item->ts_added = dap_nanotime_now(); + l_item->cache_data.ts_created = a_tx->header.ts_created; + HASH_ADD_BYHASHVALUE(hh, l_ledger_pvt->threshold_txs, tx_hash_fast, sizeof(dap_chain_hash_fast_t), l_hash_value, l_item); debug_if(g_debug_ledger, L_DEBUG, "Tx %s added to threshold", dap_hash_fast_to_str_static(a_tx_hash)); } pthread_rwlock_unlock(&l_ledger_pvt->threshold_txs_rwlock); @@ -653,7 +641,7 @@ void dap_ledger_pvt_threshold_txs_proc(dap_ledger_t *a_ledger) if (l_res != DAP_CHAIN_CS_VERIFY_CODE_TX_NO_EMISSION && l_res != DAP_CHAIN_CS_VERIFY_CODE_TX_NO_PREVIOUS) { HASH_DEL(l_ledger_pvt->threshold_txs, l_tx_item); - if ( !l_ledger_pvt->mapped ) + if ( !is_ledger_mapped(l_ledger_pvt) ) DAP_DELETE(l_tx_item->tx); DAP_DELETE(l_tx_item); l_success = true; @@ -679,7 +667,7 @@ static void s_threshold_txs_free(dap_ledger_t *a_ledger) HASH_DEL(l_pvt->threshold_txs, l_current); char l_tx_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; dap_chain_hash_fast_to_str(&l_current->tx_hash_fast, l_tx_hash_str, sizeof(l_tx_hash_str)); - if ( !l_pvt->mapped ) + if ( !is_ledger_mapped(l_pvt) ) DAP_DELETE(l_current->tx); DAP_DELETE(l_current); log_it(L_NOTICE, "Removed transaction %s form threshold ledger", l_tx_hash_str); @@ -757,28 +745,18 @@ void dap_ledger_load_cache(dap_ledger_t *a_ledger) * create ledger for specific net * load ledger cache * @param a_check_flags checking flags - * DAP_LEDGER_CHECK_TOKEN_EMISSION - * DAP_LEDGER_CHECK_CELLS_DS - * DAP_LEDGER_CHECK_CELLS_DS * @param a_net_name char * network name, for example "kelvin-testnet" * @return dap_ledger_t* */ dap_ledger_t *dap_ledger_create(dap_chain_net_t *a_net, uint16_t a_flags) { dap_ledger_t *l_ledger = dap_ledger_handle_new(); - if (!l_ledger) { - log_it(L_CRITICAL, "%s", c_error_memory_alloc); - return NULL; - } + dap_return_val_if_fail(l_ledger, NULL); + l_ledger->net = a_net; dap_ledger_private_t *l_ledger_pvt = PVT(l_ledger); - l_ledger_pvt->check_ds = a_flags & DAP_LEDGER_CHECK_LOCAL_DS; - l_ledger_pvt->check_cells_ds = a_flags & DAP_LEDGER_CHECK_CELLS_DS; - l_ledger_pvt->check_token_emission = a_flags & DAP_LEDGER_CHECK_TOKEN_EMISSION; - l_ledger_pvt->cached = a_flags & DAP_LEDGER_CACHE_ENABLED; - l_ledger_pvt->mapped = a_flags & DAP_LEDGER_MAPPED; - l_ledger_pvt->threshold_enabled = a_flags & DAP_LEDGER_THRESHOLD_ENABLED; - if (l_ledger_pvt->threshold_enabled) + l_ledger_pvt->flags = a_flags; + if ( is_ledger_threshld(l_ledger_pvt) ) l_ledger_pvt->threshold_txs_free_timer = dap_interval_timer_create(s_threshold_free_timer_tick, (dap_timer_callback_t)s_threshold_txs_free, l_ledger); pthread_cond_init(&l_ledger_pvt->load_cond, NULL); @@ -801,7 +779,7 @@ dap_ledger_t *dap_ledger_create(dap_chain_net_t *a_net, uint16_t a_flags) } log_it(L_DEBUG, "Chain %s.%s has %d datums in HAL and %d datums in HRL", a_net->pub.name, l_chain->name, l_whitelist_size, l_blacklist_size); } - if ( l_ledger_pvt->cached ) + if ( is_ledger_cached(l_ledger_pvt) ) // load ledger cache from GDB dap_ledger_load_cache(l_ledger); #endif @@ -973,7 +951,7 @@ void dap_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db) char *l_gdb_group; HASH_ITER(hh, l_ledger_pvt->ledger_items , l_item_current, l_item_tmp) { HASH_DEL(l_ledger_pvt->ledger_items, l_item_current); - if (!l_ledger_pvt->mapped) + if (!is_ledger_mapped(l_ledger_pvt)) DAP_DELETE(l_item_current->tx); DAP_DEL_Z(l_item_current); } @@ -1042,7 +1020,7 @@ void dap_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db) /* Delete threshold transactions */ HASH_ITER(hh, l_ledger_pvt->threshold_txs, l_item_current, l_item_tmp) { HASH_DEL(l_ledger_pvt->threshold_txs, l_item_current); - if (!l_ledger_pvt->mapped) + if (!is_ledger_mapped(l_ledger_pvt)) DAP_DELETE(l_item_current->tx); DAP_DEL_Z(l_item_current); } @@ -1531,5 +1509,5 @@ dap_list_t *dap_ledger_get_list_tx_cond_outs(dap_ledger_t *a_ledger, const dap_c bool dap_ledger_cache_enabled(dap_ledger_t *a_ledger) { - return PVT(a_ledger)->cached; + return is_ledger_cached(PVT(a_ledger)); } diff --git a/modules/ledger/dap_chain_ledger_token.c b/modules/ledger/dap_chain_ledger_token.c index a624cd3c90..6c7982a231 100644 --- a/modules/ledger/dap_chain_ledger_token.c +++ b/modules/ledger/dap_chain_ledger_token.c @@ -1075,7 +1075,7 @@ dap_chain_datum_token_t *dap_ledger_token_ticker_check(dap_ledger_t *a_ledger, c */ void s_ledger_token_cache_update(dap_ledger_t *a_ledger, dap_ledger_token_item_t *l_token_item) { - if (!PVT(a_ledger)->cached) + if (! is_ledger_cached(PVT(a_ledger)) ) return; char *l_gdb_group = dap_ledger_get_gdb_group(a_ledger, DAP_LEDGER_TOKENS_STR); size_t l_cache_size = l_token_item->datum_token_size + sizeof(uint256_t); @@ -1389,7 +1389,7 @@ int s_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_ return DAP_LEDGER_CHECK_ALREADY_CACHED; } - if (!PVT(a_ledger)->check_token_emission) + if (! is_ledger_ems_chk(PVT(a_ledger)) ) goto ret_success; // Check emission correctness @@ -1511,7 +1511,7 @@ int dap_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_token_ void dap_ledger_pvt_emission_cache_update(dap_ledger_t *a_ledger, dap_ledger_token_emission_item_t *a_emission_item) { - if (!PVT(a_ledger)->cached) + if (! is_ledger_cached(PVT(a_ledger)) ) return; char *l_gdb_group = dap_ledger_get_gdb_group(a_ledger, DAP_LEDGER_EMISSIONS_STR); size_t l_cache_size = a_emission_item->datum_token_emission_size + sizeof(dap_hash_fast_t); @@ -1578,7 +1578,7 @@ int dap_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emissi l_balance, l_emission->hdr.ticker, dap_chain_addr_to_str_static(&(l_emission->hdr.address))); } - if (PVT(a_ledger)->threshold_enabled) + if ( is_ledger_threshld(PVT(a_ledger)) ) dap_ledger_pvt_threshold_txs_proc(a_ledger); return DAP_LEDGER_CHECK_OK; } diff --git a/modules/ledger/dap_chain_ledger_tx.c b/modules/ledger/dap_chain_ledger_tx.c index 89ffbf2cae..2e99264a79 100644 --- a/modules/ledger/dap_chain_ledger_tx.c +++ b/modules/ledger/dap_chain_ledger_tx.c @@ -1144,7 +1144,7 @@ static struct json_object *s_wallet_info_json_collect(dap_ledger_t *a_ledger, da */ static int s_balance_cache_update(dap_ledger_t *a_ledger, dap_ledger_wallet_balance_t *a_balance) { - if (PVT(a_ledger)->cached) { + if ( is_ledger_cached(PVT(a_ledger)) ) { char *l_gdb_group = dap_ledger_get_gdb_group(a_ledger, DAP_LEDGER_BALANCES_STR); if (dap_global_db_set(l_gdb_group, a_balance->key, &a_balance->balance, sizeof(uint256_t), false, NULL, NULL)) { debug_if(g_debug_ledger, L_WARNING, "Ledger cache mismatch"); @@ -1234,7 +1234,7 @@ int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_ha l_main_token_ticker, &l_tag, &l_action, false))) { if ((l_ret_check == DAP_CHAIN_CS_VERIFY_CODE_TX_NO_PREVIOUS || l_ret_check == DAP_CHAIN_CS_VERIFY_CODE_TX_NO_EMISSION) && - l_ledger_pvt->threshold_enabled && !dap_chain_net_get_load_mode(a_ledger->net)) { + is_ledger_threshld(l_ledger_pvt) && !dap_chain_net_get_load_mode(a_ledger->net)) { if (!l_from_threshold) dap_ledger_pvt_threshold_txs_add(a_ledger, a_tx, a_tx_hash); } else { @@ -1259,7 +1259,7 @@ int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_ha dap_list_t *l_trackers_mover = NULL; dap_store_obj_t *l_cache_used_outs = NULL; char *l_ledger_cache_group = NULL; - if (PVT(a_ledger)->cached) { + if ( is_ledger_cached(l_ledger_pvt) ) { l_cache_used_outs = DAP_NEW_Z_SIZE(dap_store_obj_t, sizeof(dap_store_obj_t) * (l_outs_used + 1)); if ( !l_cache_used_outs ) { log_it(L_CRITICAL, "%s", c_error_memory_alloc); @@ -1367,7 +1367,7 @@ int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_ha l_prev_item_out->out_metadata[l_bound_item->prev_out_idx].trackers, a_tx->header.ts_created); // add a used output l_prev_item_out->cache_data.n_outs_used++; - if (PVT(a_ledger)->cached) { + if ( is_ledger_cached(l_ledger_pvt) ) { // mirror it in the cache size_t l_cache_size = sizeof(l_prev_item_out->cache_data) + l_prev_item_out->cache_data.n_outs * sizeof(dap_chain_hash_fast_t); size_t l_tx_size = dap_chain_datum_tx_get_size(l_prev_item_out->tx); @@ -1511,11 +1511,11 @@ int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_ha } 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 = l_ledger_pvt->mapped ? a_tx : DAP_DUP_SIZE(a_tx, l_tx_size); + l_tx_item->tx = is_ledger_mapped(l_ledger_pvt) ? a_tx : DAP_DUP_SIZE(a_tx, l_tx_size); l_tx_item->cache_data.n_outs = l_outs_count; l_tx_item->cache_data.tag = l_tag; l_tx_item->cache_data.action = l_action; - dap_stpcpy(l_tx_item->cache_data.token_ticker, l_main_token_ticker); + dap_strncpy(l_tx_item->cache_data.token_ticker, l_main_token_ticker, sizeof(l_tx_item->cache_data.token_ticker)); // Moving colour to new outputs size_t i = 0; @@ -1597,7 +1597,7 @@ int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_ha l_notify->callback(a_ledger, a_tx, a_tx_hash, l_notify->arg, DAP_LEDGER_NOTIFY_OPCODE_ADDED); } } - if (PVT(a_ledger)->cached) { + if ( is_ledger_cached(l_ledger_pvt) ) { // Add it to cache size_t l_cache_size = sizeof(l_tx_item->cache_data) + l_tx_item->cache_data.n_outs * sizeof(dap_chain_hash_fast_t); size_t l_tx_cache_sz = l_tx_size + l_cache_size + sizeof(dap_ledger_cache_gdb_record_t); @@ -1616,7 +1616,7 @@ int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_ha if (dap_global_db_set_raw(l_cache_used_outs, l_outs_used + 1, NULL, NULL)) debug_if(g_debug_ledger, L_WARNING, "Ledger cache mismatch"); } - if (!a_from_threshold && l_ledger_pvt->threshold_enabled) + if (!a_from_threshold && is_ledger_threshld(l_ledger_pvt)) dap_ledger_pvt_threshold_txs_proc(a_ledger); FIN: if (l_trackers_mover) @@ -1625,7 +1625,7 @@ FIN: dap_list_free_full(l_list_bound_items, NULL); if (l_list_tx_out) dap_list_free(l_list_tx_out); - if (PVT(a_ledger)->cached) { + if ( is_ledger_cached(l_ledger_pvt) ) { if (l_cache_used_outs) { for (size_t i = 1; i < l_outs_used; ++i) { DAP_DEL_MULTY(l_cache_used_outs[i].key, l_cache_used_outs[i].value); @@ -1680,7 +1680,7 @@ int dap_ledger_tx_remove(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap dap_store_obj_t *l_cache_used_outs = NULL; char *l_ledger_cache_group = NULL; - if (PVT(a_ledger)->cached) { + if ( is_ledger_cached(l_ledger_pvt) ) { l_cache_used_outs = DAP_NEW_Z_COUNT(dap_store_obj_t, l_outs_used); if ( !l_cache_used_outs ) { log_it(L_CRITICAL, "Memory allocation error"); @@ -1770,7 +1770,7 @@ int dap_ledger_tx_remove(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap dap_ledger_tx_item_t *l_prev_item_out = l_bound_item->prev_item; l_prev_item_out->out_metadata[l_bound_item->prev_out_idx].tx_spent_hash_fast = (dap_hash_fast_t){ }; l_prev_item_out->cache_data.n_outs_used--; - if (PVT(a_ledger)->cached) { + if ( is_ledger_cached(l_ledger_pvt) ) { // mirror it in the cache size_t l_tx_size = dap_chain_datum_tx_get_size(l_prev_item_out->tx); size_t l_cache_size = sizeof(l_prev_item_out->cache_data) + l_prev_item_out->cache_data.n_outs * sizeof(dap_chain_hash_fast_t); @@ -1906,7 +1906,7 @@ int dap_ledger_tx_remove(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap dap_list_free_full(l_tx_item->out_metadata[i].trackers, NULL); DAP_DELETE(l_tx_item); - if (PVT(a_ledger)->cached) { + if ( is_ledger_cached(l_ledger_pvt) ) { // Add it to cache dap_global_db_del_sync(l_ledger_cache_group, l_tx_hash_str); // Apply it with single DB transaction @@ -1918,7 +1918,7 @@ FIN: dap_list_free_full(l_list_bound_items, NULL); if (l_list_tx_out) dap_list_free(l_list_tx_out); - if (PVT(a_ledger)->cached) { + if ( is_ledger_cached(l_ledger_pvt) ) { if (l_cache_used_outs) { for (size_t i = 1; i < l_outs_used; i++) { DAP_DELETE(l_cache_used_outs[i].key); @@ -1954,7 +1954,7 @@ int dap_ledger_tx_load(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_c static void s_ledger_stake_lock_cache_update(dap_ledger_t *a_ledger, dap_ledger_stake_lock_item_t *a_stake_lock_item) { - if (!PVT(a_ledger)->cached) + if (!is_ledger_cached(PVT(a_ledger))) return; char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; dap_chain_hash_fast_to_str(&a_stake_lock_item->tx_for_stake_lock_hash, l_hash_str, sizeof(l_hash_str)); diff --git a/modules/ledger/include/dap_chain_ledger_pvt.h b/modules/ledger/include/dap_chain_ledger_pvt.h index 62eb273e50..b94a9fb3ac 100644 --- a/modules/ledger/include/dap_chain_ledger_pvt.h +++ b/modules/ledger/include/dap_chain_ledger_pvt.h @@ -186,12 +186,13 @@ typedef struct dap_ledger_private { dap_ledger_decree_item_t *decrees; dap_ledger_anchor_item_t *anchors; - // Save/load operations condition + // Save/load cache operations condition pthread_mutex_t load_mutex; pthread_cond_t load_cond; bool load_end; // Ledger flags - bool check_ds, check_cells_ds, check_token_emission, cached, mapped, threshold_enabled; + //bool check_ds, check_cells_ds, check_token_emission, cached, mapped, threshold_enabled; + uint16_t flags; //notifiers dap_list_t *bridged_tx_notifiers; dap_list_t *tx_add_notifiers; @@ -202,6 +203,13 @@ typedef struct dap_ledger_private { #define PVT(a) ( (dap_ledger_private_t *) a->_internal ) +#define is_ledger_ds_chk(l) ( l->flags & DAP_LEDGER_CHECK_LOCAL_DS ) +#define is_ledger_cells_ds_chk(l) ( l->flags & DAP_LEDGER_CHECK_CELLS_DS ) +#define is_ledger_ems_chk(l) ( l->flags & DAP_LEDGER_CHECK_TOKEN_EMISSION ) +#define is_ledger_mapped(l) ( l->flags & DAP_LEDGER_MAPPED ) +#define is_ledger_cached(l) ( l->flags & DAP_LEDGER_CACHE_ENABLED ) +#define is_ledger_threshld(l) ( l->flags & DAP_LEDGER_THRESHOLD_ENABLED ) + extern bool g_debug_ledger; bool dap_ledger_pvt_cache_gdb_load_tokens_callback(dap_global_db_instance_t *a_dbi, diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c index f20f69afa4..5e8774bfba 100644 --- a/modules/net/dap_chain_net.c +++ b/modules/net/dap_chain_net.c @@ -541,7 +541,7 @@ int s_link_manager_fill_net_info(dap_link_t *a_link) } } dap_chain_node_info_t *l_node_info = NULL; - if (!l_host || !l_host[0] || !l_port) { + if (!l_host || !*l_host || !l_port) { for (dap_chain_net_t *net = s_nets_by_name; net; net = net->hh.next) { if (( l_node_info = dap_chain_node_info_read(net, &a_link->addr) )) break; @@ -697,10 +697,7 @@ static dap_chain_net_t *s_net_new(const char *a_net_name, dap_config_t *a_cfg) *a_native_ticker= dap_config_get_item_str(a_cfg, "general", "native_ticker"); dap_chain_net_id_t l_net_id; - if(!a_node_role) - return log_it(L_ERROR, "Can't create l_net, can't read node role config"), NULL; - - if(!l_net_name_str || !l_net_id_str || dap_chain_net_id_parse(l_net_id_str, &l_net_id)) + if (!l_net_name_str || !*l_net_name_str || !l_net_id_str || dap_chain_net_id_parse(l_net_id_str, &l_net_id)) return log_it(L_ERROR, "Can't create l_net, can't read name or ID config"), NULL; dap_chain_net_t *l_net_sought = NULL; @@ -715,38 +712,38 @@ static dap_chain_net_t *s_net_new(const char *a_net_name, dap_config_t *a_cfg) l_net_sought->pub.id.uint64); return NULL; } + + if (!a_native_ticker) + return log_it(L_ERROR, "Invalid native ticker, check [general] \"native_ticker\" in %s.cfg", l_net_name_str), NULL; + + uint32_t l_role; + if (!a_node_role) + l_role = NODE_ROLE_FULL; + else if ( !strcmp(a_node_role, "root_master") ) + l_role = NODE_ROLE_ROOT_MASTER; + else if ( !strcmp(a_node_role,"root") ) + l_role = NODE_ROLE_ROOT; + else if ( !strcmp(a_node_role,"archive") ) + l_role = NODE_ROLE_ARCHIVE; + else if ( !strcmp(a_node_role,"cell_master") ) + l_role = NODE_ROLE_CELL_MASTER; + else if ( !strcmp(a_node_role,"master") ) + l_role = NODE_ROLE_MASTER; + else if ( !strcmp(a_node_role,"full") ) + l_role = NODE_ROLE_FULL; + else if ( !strcmp(a_node_role,"light") ) + l_role = NODE_ROLE_LIGHT; + else + return log_it(L_ERROR,"Unknown node role \"%s\" for network '%s'", a_node_role, l_net_name_str), NULL; + dap_chain_net_t *l_ret = DAP_NEW_Z_SIZE_RET_VAL_IF_FAIL(dap_chain_net_t, sizeof(dap_chain_net_t) + sizeof(dap_chain_net_pvt_t), NULL); PVT(l_ret)->node_info = DAP_NEW_Z_SIZE_RET_VAL_IF_FAIL(dap_chain_node_info_t, sizeof(dap_chain_node_info_t) + DAP_HOSTADDR_STRLEN + 1, NULL, l_ret); l_ret->pub.id = l_net_id; - if (strcmp (a_node_role, "root_master")==0){ - PVT(l_ret)->node_role.enums = NODE_ROLE_ROOT_MASTER; - } else if (strcmp( a_node_role,"root") == 0){ - PVT(l_ret)->node_role.enums = NODE_ROLE_ROOT; - } else if (strcmp( a_node_role,"archive") == 0){ - PVT(l_ret)->node_role.enums = NODE_ROLE_ARCHIVE; - } else if (strcmp( a_node_role,"cell_master") == 0){ - PVT(l_ret)->node_role.enums = NODE_ROLE_CELL_MASTER; - }else if (strcmp( a_node_role,"master") == 0){ - PVT(l_ret)->node_role.enums = NODE_ROLE_MASTER; - }else if (strcmp( a_node_role,"full") == 0){ - PVT(l_ret)->node_role.enums = NODE_ROLE_FULL; - }else if (strcmp( a_node_role,"light") == 0){ - PVT(l_ret)->node_role.enums = NODE_ROLE_LIGHT; - }else{ - log_it(L_ERROR,"Unknown node role \"%s\" for network '%s'", a_node_role, l_net_name_str); - DAP_DELETE(l_ret); - return NULL; - } - if (!( l_net_name_str )) - return DAP_DELETE(l_ret), log_it(L_ERROR, "Invalid net name, check [general] \"name\" in netconfig"), NULL; - dap_strncpy(l_ret->pub.name, l_net_name_str, sizeof(l_ret->pub.name)); - if (!( l_ret->pub.native_ticker = a_native_ticker )) - return DAP_DEL_MULTY(l_ret->pub.name, l_ret), - log_it(L_ERROR, "Invalid native ticker, check [general] \"native_ticker\" in %s.cfg", - l_net_name_str), - NULL; + PVT(l_ret)->node_role.enums = l_role; log_it (L_NOTICE, "Node role \"%s\" selected for network '%s'", a_node_role, l_net_name_str); + dap_strncpy(l_ret->pub.name, l_net_name_str, sizeof(l_ret->pub.name)); + l_ret->pub.native_ticker = a_native_ticker; l_ret->pub.config = a_cfg; l_ret->pub.gdb_groups_prefix = dap_config_get_item_str_default( a_cfg, "general", "gdb_groups_prefix", dap_config_get_item_str(a_cfg, "general", "name") ); @@ -784,35 +781,21 @@ bool s_net_disk_load_notify_callback(UNUSED_ARG void *a_arg) */ void dap_chain_net_load_all() { - if ( dap_config_get_item_bool_default(g_config, "server", "enabled", false) ) { - char l_local_ip[INET6_ADDRSTRLEN] = { '\0' }; - uint16_t l_in_port = 0; - const char **l_listening = dap_config_get_array_str(g_config, "server", DAP_CFG_PARAM_LISTEN_ADDRS, NULL); - if ( l_listening ) { - if ( dap_net_parse_config_address(*l_listening, l_local_ip, &l_in_port, NULL, NULL) < 0 ) - log_it(L_ERROR, "Invalid server IP address, check [server] section in cellframe-node.cfg"); - else { - // power of short-circuit - if ( l_in_port || ( l_in_port = dap_config_get_item_int16_default(g_config, "server", DAP_CFG_PARAM_LEGACY_PORT, 8079 ))) { - s_server_enabled = true; - log_it(L_INFO, "Server is enabled on [%s : %u]", l_local_ip, l_in_port); - } - } - } - } - uint16_t l_nets_count = HASH_COUNT(s_nets_by_name); + int l_nets_count = HASH_COUNT(s_nets_by_name), i = 0, l_err; if (!l_nets_count) return log_it(L_ERROR, "No networks initialized!"); pthread_t l_tids[l_nets_count]; - dap_chain_net_t *l_net = s_nets_by_name; dap_timerfd_t *l_load_notify_timer = dap_timerfd_start(5000, (dap_timerfd_callback_t)s_net_disk_load_notify_callback, NULL); - for (int i = 0; i < l_nets_count; ++i) { - pthread_create(&l_tids[i], NULL, s_net_load, l_net); - l_net = l_net->hh.next; - } - for (int i = 0; i < l_nets_count; ++i) { - pthread_join(l_tids[i], NULL); - } + for ( dap_chain_net_t *l_net = s_nets_by_name; l_net && !( l_err = pthread_create(&l_tids[i], NULL, s_net_load, l_net) ); l_net = l_net->hh.next, ++i ); + if ( i < l_nets_count ) { + log_it(L_ERROR, "%s%d of %d nets are loading! Thread creation error %d: \"%s\"", + i ? "Only " : "", i, l_nets_count, l_err, dap_strerror(l_err)); + l_nets_count = i; + } + for ( i = 0; i < l_nets_count; ++i ) { + if (( l_err = pthread_join(l_tids[i], NULL) )) + log_it(L_ERROR, "Thread %d join error %d: \"%s\"", l_err, dap_strerror(l_err)); + } dap_timerfd_delete(l_load_notify_timer->worker, l_load_notify_timer->esocket_uuid); } @@ -1862,15 +1845,17 @@ int s_net_init(const char *a_net_name, const char *a_path, uint16_t a_acl_idx) } l_net->pub.bridged_networks_count = j; if (j < i) - l_net->pub.bridged_networks = DAP_REALLOC_COUNT(l_net->pub.bridged_networks, j); // Can be NULL, it's ok + l_net->pub.bridged_networks = j + ? DAP_REALLOC_COUNT(l_net->pub.bridged_networks, j) + : ( DAP_DELETE(l_net->pub.bridged_networks), NULL ); // No bridged nets is OK } // read nodes addrs and hosts if ( - dap_config_stream_addrs_parse(l_cfg, "general", "permanent_nodes_addrs", &l_net_pvt->permanent_links_addrs, &l_net_pvt->permanent_links_addrs_count) || - s_nodes_hosts_init(l_net, l_cfg, "permanent_nodes_hosts", &l_net_pvt->permanent_links_hosts, &l_net_pvt->permanent_links_hosts_count) || - s_nodes_hosts_init(l_net, l_cfg, "seed_nodes_hosts", &l_net_pvt->seed_nodes_hosts, &l_net_pvt->seed_nodes_count) || - (!l_net_pvt->seed_nodes_count && s_nodes_hosts_init(l_net, l_cfg, "bootstrap_hosts", &l_net_pvt->seed_nodes_hosts, &l_net_pvt->seed_nodes_count) ) + dap_config_stream_addrs_parse(l_cfg, "general", "permanent_nodes_addrs", &l_net_pvt->permanent_links_addrs, &l_net_pvt->permanent_links_addrs_count) + || s_nodes_hosts_init(l_net, l_cfg, "permanent_nodes_hosts", &l_net_pvt->permanent_links_hosts, &l_net_pvt->permanent_links_hosts_count) + || s_nodes_hosts_init(l_net, l_cfg, "seed_nodes_hosts", &l_net_pvt->seed_nodes_hosts, &l_net_pvt->seed_nodes_count) + || ( !l_net_pvt->seed_nodes_count && s_nodes_hosts_init(l_net, l_cfg, "bootstrap_hosts", &l_net_pvt->seed_nodes_hosts, &l_net_pvt->seed_nodes_count) ) ) { dap_chain_net_delete(l_net); dap_config_close(l_cfg); @@ -1882,6 +1867,9 @@ int s_net_init(const char *a_net_name, const char *a_path, uint16_t a_acl_idx) // Get list chains name for enabled debug mode bool is_esbocs_debug = dap_config_get_item_bool_default(l_cfg, "esbocs", "consensus_debug", false); + if ( dap_server_enabled() && ( l_net_pvt->node_info->ext_port = dap_config_get_item_uint16(g_config, "server", "ext_port") )) + log_it(L_INFO, "Set external port %u for adding in node list", l_net_pvt->node_info->ext_port); + struct dirent *l_dir_entry; // Services register & configure dap_chain_srv_start(l_net->pub.id, DAP_CHAIN_NET_SRV_XCHANGE_LITERAL, NULL); // Harcoded core service starting for exchange capability @@ -1950,8 +1938,7 @@ int s_net_init(const char *a_net_name, const char *a_path, uint16_t a_acl_idx) for ( ; i < k; ++i) { if ( l_occupied_default_types[l_types_arr[i]] ) { if ( i < k - 1 ) - l_types_arr[i] = - l_types_arr[k - 1]; + l_types_arr[i] = l_types_arr[k - 1]; --i; --k; } else @@ -2021,18 +2008,10 @@ static void *s_net_load(void *a_arg) } dap_chain_net_pvt_t *l_net_pvt = PVT(l_net); - - // reload ledger cache at once - if (s_chain_net_reload_ledger_cache_once(l_net)) { - log_it(L_WARNING,"Start one time ledger cache reloading"); - dap_ledger_purge(l_net->pub.ledger, false); - dap_chain_srv_purge_all(l_net->pub.id); - } //else dap_chain_net_srv_stake_load_cache(l_net); // TODO rework ledger and staking caches // load chains dap_chain_t *l_chain = l_net->pub.chains; - clock_t l_chain_load_start_time; - l_chain_load_start_time = clock(); + clock_t l_chain_load_start_time = clock(); while (l_chain) { l_net->pub.fee_value = uint256_0; l_net->pub.fee_addr = c_dap_chain_addr_blank; @@ -2193,11 +2172,6 @@ static void *s_net_load(void *a_arg) DL_FOREACH(l_net->pub.chains, l_chain) dap_chain_cs_load(l_chain, l_net->pub.config); - if ( s_server_enabled ) { - if (( l_net_pvt->node_info->ext_port = dap_config_get_item_uint16(g_config, "server", "ext_port") )) - log_it(L_INFO, "Set external port %u for adding in node list", l_net_pvt->node_info->ext_port); - } - l_net_pvt->node_info->address.uint64 = g_node_addr.uint64; log_it(L_NOTICE, "Net load information: node_addr " NODE_ADDR_FP_STR ", seed links %u, cell_id 0x%016"DAP_UINT64_FORMAT_X, diff --git a/modules/node-cli/dap_chain_node_cli_cmd_token.c b/modules/node-cli/dap_chain_node_cli_cmd_token.c index 0ea06e1d4b..985ad2d800 100644 --- a/modules/node-cli/dap_chain_node_cli_cmd_token.c +++ b/modules/node-cli/dap_chain_node_cli_cmd_token.c @@ -426,31 +426,24 @@ static int s_parse_common_token_decl_arg(int a_argc, char ** a_argv, void **a_st */ dap_list_t* s_parse_wallet_addresses(const char *a_tx_address, dap_list_t *l_tsd_list, size_t *l_tsd_total_size, uint32_t flag) { - if (!a_tx_address){ - log_it(L_DEBUG,"a_tx_address is null"); - return l_tsd_list; - } - - char ** l_str_wallet_addr = NULL; - l_str_wallet_addr = dap_strsplit(a_tx_address,",",0xffff); + dap_return_val_if_fail(a_tx_address, l_tsd_list); - if (!l_str_wallet_addr){ - log_it(L_DEBUG,"Error in wallet addresses array parsing in tx_receiver_allowed parameter"); - return l_tsd_list; - } + char **l_str_wallet_addr = dap_strsplit(a_tx_address,",",0xffff); + if (!l_str_wallet_addr) + return log_it(L_ERROR, "Can't split \"%s\" by commas!", a_tx_address), l_tsd_list; - while (l_str_wallet_addr && *l_str_wallet_addr){ - log_it(L_DEBUG,"Processing wallet address: %s", *l_str_wallet_addr); - dap_chain_addr_t *addr_to = dap_chain_addr_from_str(*l_str_wallet_addr); + for (char **l_cur = l_str_wallet_addr; l_cur && *l_cur; ++l_cur) { + log_it(L_DEBUG, "Processing wallet address: %s", *l_cur); + dap_chain_addr_t *addr_to = dap_chain_addr_from_str(*l_cur); if (addr_to){ - dap_tsd_t * l_tsd = dap_tsd_create(flag, addr_to, sizeof(dap_chain_addr_t)); + dap_tsd_t *l_tsd = dap_tsd_create(flag, addr_to, sizeof(dap_chain_addr_t)); l_tsd_list = dap_list_append(l_tsd_list, l_tsd); *l_tsd_total_size += dap_tsd_size(l_tsd); - }else{ - log_it(L_DEBUG,"Error in wallet address parsing"); - } - l_str_wallet_addr++; + DAP_DELETE(addr_to); + } else + log_it(L_ERROR, "Can't convert it to address!"); } + dap_strfreev(l_str_wallet_addr); return l_tsd_list; } @@ -479,15 +472,15 @@ static int s_parse_additional_token_decl_arg(int a_argc, char ** a_argv, void ** if (!a_update_token) { if (a_params->ext.flags){ // Flags l_str_flags = dap_strsplit(a_params->ext.flags,",",0xffff ); - while (l_str_flags && *l_str_flags){ - uint16_t l_flag = dap_chain_datum_token_flag_from_str(*l_str_flags); + for (char **l_cur = l_str_flags; l_cur && *l_cur; ++l_cur) { + uint16_t l_flag = dap_chain_datum_token_flag_from_str(*l_cur); if (l_flag == DAP_CHAIN_DATUM_TOKEN_FLAG_UNDEFINED ){ - dap_cli_server_cmd_set_reply_text(a_str_reply, "Flag can't be \"%s\"",*l_str_flags); + dap_cli_server_cmd_set_reply_text(a_str_reply, "Flag can't be \"%s\"",*l_cur); return -20; } l_flags |= l_flag; // if we have multiple flags - l_str_flags++; } + dap_strfreev(l_str_flags); } } else { const char *l_set_flags = NULL; diff --git a/modules/node-cli/dap_chain_node_cli_cmd_tx.c b/modules/node-cli/dap_chain_node_cli_cmd_tx.c index c3f84f37ca..440cd4ef1c 100644 --- a/modules/node-cli/dap_chain_node_cli_cmd_tx.c +++ b/modules/node-cli/dap_chain_node_cli_cmd_tx.c @@ -2882,9 +2882,7 @@ int com_tx_create(int a_argc, char **a_argv, void **a_json_arr_reply) for (size_t i = 0; i < l_addr_el_count; ++i) { l_addr_to[i] = dap_chain_addr_from_str(l_addr_base58_to_array[i]); if(!l_addr_to[i]) { - for (size_t j = 0; j < i; ++j) { - DAP_DELETE(l_addr_to[j]); - } + DAP_DEL_ARRAY(l_addr_to, i); DAP_DEL_MULTY(l_addr_to, l_addr_base58_to_array, l_value); dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_DESTINATION_ADDRESS_INVALID, "destination address is invalid"); return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_DESTINATION_ADDRESS_INVALID; @@ -2921,9 +2919,7 @@ int com_tx_create(int a_argc, char **a_argv, void **a_json_arr_reply) l_ret = DAP_CHAIN_NODE_CLI_COM_TX_CREATE_CAN_NOT_ADD_DATUM_IN_MEMPOOL; } json_object_array_add(*a_json_arr_reply, l_jobj_emission); - for (size_t i = 0; i < l_addr_el_count; ++i) { - DAP_DELETE(l_addr_to[i]); - } + DAP_DEL_ARRAY(l_addr_to, l_addr_el_count); DAP_DEL_MULTY(l_addr_to, l_value); if (l_wallet_fee) { dap_chain_wallet_close(l_wallet_fee); @@ -2938,9 +2934,7 @@ int com_tx_create(int a_argc, char **a_argv, void **a_json_arr_reply) if(!l_wallet) { dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_WALLET_DOES_NOT_EXIST, "wallet %s does not exist", l_from_wallet_name); - for (size_t i = 0; i < l_addr_el_count; ++i) { - DAP_DELETE(l_addr_to[i]); - } + DAP_DEL_ARRAY(l_addr_to, l_addr_el_count); DAP_DEL_MULTY(l_addr_to, l_value); return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_WALLET_DOES_NOT_EXIST; } else { @@ -2957,9 +2951,7 @@ int com_tx_create(int a_argc, char **a_argv, void **a_json_arr_reply) dap_enc_key_delete(l_priv_key); dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_SOURCE_ADDRESS_INVALID, "source address is invalid"); json_object_put(l_jobj_result); - for (size_t i = 0; i < l_addr_el_count; ++i) { - DAP_DELETE(l_addr_to[i]); - } + DAP_DEL_ARRAY(l_addr_to, l_addr_el_count); DAP_DEL_MULTY(l_addr_to, l_value); return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_SOURCE_ADDRESS_INVALID; } @@ -2970,9 +2962,7 @@ int com_tx_create(int a_argc, char **a_argv, void **a_json_arr_reply) dap_enc_key_delete(l_priv_key); dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_EQ_SOURCE_DESTINATION_ADDRESS, "The transaction cannot be directed to the same address as the source."); json_object_put(l_jobj_result); - for (size_t j = 0; j < l_addr_el_count; ++j) { - DAP_DELETE(l_addr_to[j]); - } + DAP_DEL_ARRAY(l_addr_to, l_addr_el_count); DAP_DEL_MULTY(l_addr_to, l_value); return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_EQ_SOURCE_DESTINATION_ADDRESS; } @@ -3000,9 +2990,7 @@ int com_tx_create(int a_argc, char **a_argv, void **a_json_arr_reply) dap_string_free(l_allowed_list, true); json_object_put(l_jobj_result); - for (size_t j = 0; j < l_addr_el_count; ++j) { - DAP_DELETE(l_addr_to[j]); - } + DAP_DEL_ARRAY(l_addr_to, l_addr_el_count); DAP_DEL_MULTY(l_addr_to, l_value); return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_DESTINATION_NETWORK_IS_UNREACHEBLE; } @@ -3036,9 +3024,7 @@ int com_tx_create(int a_argc, char **a_argv, void **a_json_arr_reply) json_object_array_add(*a_json_arr_reply, l_jobj_result); - for (size_t i = 0; i < l_addr_el_count; ++i) { - DAP_DELETE(l_addr_to[i]); - } + DAP_DEL_ARRAY(l_addr_to, l_addr_el_count); DAP_DEL_MULTY(l_addr_to, l_value); dap_chain_wallet_close(l_wallet); dap_enc_key_delete(l_priv_key); -- GitLab From 25d1e6122065e4825d12b82a062b0a48ee0944f9 Mon Sep 17 00:00:00 2001 From: "Constantin P." <papizh.konstantin@demlabs.net> Date: Wed, 11 Dec 2024 14:45:07 +0700 Subject: [PATCH 02/11] ... --- modules/net/dap_chain_net.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c index 5e8774bfba..c49e31116e 100644 --- a/modules/net/dap_chain_net.c +++ b/modules/net/dap_chain_net.c @@ -792,10 +792,9 @@ void dap_chain_net_load_all() i ? "Only " : "", i, l_nets_count, l_err, dap_strerror(l_err)); l_nets_count = i; } - for ( i = 0; i < l_nets_count; ++i ) { - if (( l_err = pthread_join(l_tids[i], NULL) )) - log_it(L_ERROR, "Thread %d join error %d: \"%s\"", l_err, dap_strerror(l_err)); - } + for ( i = 0; i < l_nets_count; l_err = pthread_join(l_tids[i++], NULL) ) { + debug_if(l_err, L_ERROR, "Thread %d join error %d: \"%s\"", l_err, dap_strerror(l_err)); + } dap_timerfd_delete(l_load_notify_timer->worker, l_load_notify_timer->esocket_uuid); } -- GitLab From 4a358b8b2eac701ced2a4cee74b582443b5d8831 Mon Sep 17 00:00:00 2001 From: "Constantin P." <papizh.konstantin@demlabs.net> Date: Sat, 28 Dec 2024 11:17:57 +0700 Subject: [PATCH 03/11] proceeding.... --- dap-sdk | 2 +- modules/chain/tests/dap_chain_ledger_tests.c | 2 +- .../consensus/dag-poa/dap_chain_cs_dag_poa.c | 12 +- modules/ledger/dap_chain_ledger.c | 3 +- modules/ledger/dap_chain_ledger_decree.c | 29 +-- modules/ledger/include/dap_chain_ledger.h | 3 +- modules/net/dap_chain_net.c | 190 +++++++++--------- modules/net/include/dap_chain_net.h | 3 + 8 files changed, 110 insertions(+), 134 deletions(-) diff --git a/dap-sdk b/dap-sdk index 3b666f271d..ff4ff670a8 160000 --- a/dap-sdk +++ b/dap-sdk @@ -1 +1 @@ -Subproject commit 3b666f271d3f3ecceebcabc091370fbff270e4f6 +Subproject commit ff4ff670a8b221e11dbf9e83d4dee499ada5e5eb diff --git a/modules/chain/tests/dap_chain_ledger_tests.c b/modules/chain/tests/dap_chain_ledger_tests.c index 0d095b8844..1ac7c8d084 100644 --- a/modules/chain/tests/dap_chain_ledger_tests.c +++ b/modules/chain/tests/dap_chain_ledger_tests.c @@ -1027,7 +1027,7 @@ void dap_ledger_test_run(void){ dap_assert_PIF(dap_chain_cs_create(l_chain_main, &l_cfg) == 0, "Chain esbocs cs creating: "); DL_APPEND(l_net->pub.chains, l_chain_main); - dap_assert_PIF(!dap_ledger_decree_create(l_net->pub.ledger), "Decree initialization:"); + dap_assert_PIF(!dap_ledger_decree_init(l_net->pub.ledger), "Decree initialization:"); char *l_seed_ph = "H58i9GJKbn91238937^#$t6cjdf"; size_t l_seed_ph_size = strlen(l_seed_ph); 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 409a5ccf59..9ca644a02f 100644 --- a/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c +++ b/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c @@ -379,11 +379,7 @@ static int s_callback_new(dap_chain_t *a_chain, dap_config_t * a_chain_cfg) l_poa_pvt->auth_certs_count = dap_config_get_item_uint16_default(a_chain_cfg,"dag-poa","auth_certs_number",0); 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_CRITICAL, "%s", c_error_memory_alloc); - return -1; - } + l_poa_pvt->auth_certs = DAP_NEW_Z_COUNT_RET_VAL_IF_FAIL(dap_cert_t*, l_poa_pvt->auth_certs_count, -1); char l_cert_name[MAX_PATH + 1]; int l_pos; for (uint16_t i = 0; i < l_poa_pvt->auth_certs_count ; ++i) { @@ -910,11 +906,9 @@ dap_list_t *dap_chain_cs_dag_poa_get_auth_certs(dap_chain_t *a_chain, size_t *a_ *a_count_verify = l_poa_pvt->auth_certs_count_verify; dap_list_t *l_keys_list = NULL; - for(size_t i = 0; i < l_poa_pvt->auth_certs_count; i++) + for (size_t i = 0; i < l_poa_pvt->auth_certs_count; ++i) { - dap_pkey_t *l_pkey = dap_cert_to_pkey(l_poa_pvt->auth_certs[i]); - l_keys_list = dap_list_append(l_keys_list, l_pkey); + l_keys_list = dap_list_append(l_keys_list, dap_cert_to_pkey(l_poa_pvt->auth_certs[i])); } - return l_keys_list; } diff --git a/modules/ledger/dap_chain_ledger.c b/modules/ledger/dap_chain_ledger.c index e6224f2f5d..ede85c407c 100644 --- a/modules/ledger/dap_chain_ledger.c +++ b/modules/ledger/dap_chain_ledger.c @@ -784,8 +784,7 @@ dap_ledger_t *dap_ledger_create(dap_chain_net_t *a_net, uint16_t a_flags) dap_ledger_load_cache(l_ledger); #endif // Decrees initializing - dap_ledger_decree_create(l_ledger); - + dap_ledger_decree_init(l_ledger); return l_ledger; } diff --git a/modules/ledger/dap_chain_ledger_decree.c b/modules/ledger/dap_chain_ledger_decree.c index 3ecfd2f963..1795c3a26b 100644 --- a/modules/ledger/dap_chain_ledger_decree.c +++ b/modules/ledger/dap_chain_ledger_decree.c @@ -42,31 +42,14 @@ static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain static int s_service_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain_net_t *a_net, bool a_apply); // Public functions -int dap_ledger_decree_create(dap_ledger_t *a_ledger) -{ - dap_return_val_if_fail(a_ledger, -106); - - size_t l_auth_certs_count = 0; - dap_list_t *l_net_keys = NULL; - uint16_t l_count_verify = 0; - for (dap_chain_t *l_chain = a_ledger->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, &l_auth_certs_count, &l_count_verify); - if (l_net_keys) - break; - } - if (!l_net_keys || !l_auth_certs_count) { - log_it(L_WARNING, "Certificates for net %s not found.", a_ledger->net->pub.name); - return -1; - } +void dap_ledger_decree_init(dap_ledger_t *a_ledger) { dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); - l_ledger_pvt->decree_min_num_of_signers = l_count_verify; - l_ledger_pvt->decree_num_of_owners = l_auth_certs_count; - l_ledger_pvt->decree_owners_pkeys = l_net_keys; - - return 0; + l_ledger_pvt->decree_min_num_of_signers = a_ledger->net->pub.keys_min_count; + l_ledger_pvt->decree_num_of_owners = dap_list_length(a_ledger->net->pub.keys); + l_ledger_pvt->decree_owners_pkeys = a_ledger->net->pub.keys; + if ( !l_ledger_pvt->decree_owners_pkeys ) + log_it(L_WARNING, "PoA certificates for net %s not found", a_ledger->net->pub.name); } static int s_decree_clear(dap_ledger_t *a_ledger) diff --git a/modules/ledger/include/dap_chain_ledger.h b/modules/ledger/include/dap_chain_ledger.h index 66be425d77..4055bf5130 100644 --- a/modules/ledger/include/dap_chain_ledger.h +++ b/modules/ledger/include/dap_chain_ledger.h @@ -482,7 +482,8 @@ void dap_ledger_set_cache_tx_check_callback(dap_ledger_t *a_ledger, dap_ledger_c dap_chain_tx_out_cond_t* dap_chain_ledger_get_tx_out_cond_linked_to_tx_in_cond(dap_ledger_t *a_ledger, dap_chain_tx_in_cond_t *a_in_cond); void dap_ledger_load_end(dap_ledger_t *a_ledger); -int dap_ledger_decree_create(dap_ledger_t *a_ledger); +//int dap_ledger_decree_create(dap_ledger_t *a_ledger); +void dap_ledger_decree_init(dap_ledger_t *a_ledger); void dap_ledger_decree_purge(dap_ledger_t *a_ledger); uint16_t dap_ledger_decree_get_min_num_of_signers(dap_ledger_t *a_ledger); diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c index c49e31116e..334bea8d8d 100644 --- a/modules/net/dap_chain_net.c +++ b/modules/net/dap_chain_net.c @@ -217,6 +217,7 @@ static bool s_net_states_proc(void *a_arg); static void s_net_states_notify(dap_chain_net_t * l_net); static void s_nodelist_change_notify(dap_store_obj_t *a_obj, void *a_arg); //static void s_net_proc_kill( dap_chain_net_t * a_net ); +static int s_chains_init_all(const char *a_netname, const char *a_path, int *a_ledger_flags); static int s_net_init(const char *a_net_name, const char *a_path, uint16_t a_acl_idx); static void *s_net_load(void *a_arg); static int s_net_try_online(dap_chain_net_t *a_net); @@ -1809,6 +1810,77 @@ static int s_nodes_hosts_init(dap_chain_net_t *a_net, dap_config_t *a_cfg, const return 0; } +static int s_chains_init_all(dap_chain_net_t *a_net, const char *a_path, int *a_ledger_flags) { + DIR *l_chains_dir = opendir(a_path); + if (!l_chains_dir) + return log_it(L_ERROR, "Can't find any chains for network %s", a_net->pub.name), -1; + bool is_esbocs_debug = dap_config_get_item_bool_default(a_net->pub.config, "esbocs", "consensus_debug", false); + dap_config_t *l_chain_config, *l_all_chain_configs = NULL, *l_tmp_cfg; + char l_chain_cfg_path[MAX_PATH + 1] = { '\0' }; + int l_pos = snprintf(l_chain_cfg_path, MAX_PATH, "network/%s/", a_net->pub.name); + for ( struct dirent *l_dir_entry; ( l_dir_entry = readdir(l_chains_dir) ); ) { + unsigned short l_len = strlen(l_dir_entry->d_name); + if ( l_len > 4 && !dap_strncmp(l_dir_entry->d_name + l_len - 4, ".cfg", 4) ) { + *(l_dir_entry->d_name + l_len - 4) = '\0'; + log_it(L_DEBUG, "Opening chain config \"%s.%s\"", a_net->pub.name, l_dir_entry->d_name); + dap_strncpy(l_chain_cfg_path + l_pos, l_dir_entry->d_name, MAX_PATH - l_pos); + if (!( l_chain_config = dap_config_open(l_chain_cfg_path) )) { + log_it(L_ERROR, "Can't open chain config %s, skip it", l_dir_entry->d_name); + continue; + } + HASH_ADD_KEYPTR(hh, l_all_chain_configs, l_chain_config->path, strlen(l_chain_config->path), l_chain_config); + } + } + closedir(l_chains_dir); + if (!l_all_chain_configs) + return log_it(L_ERROR, "Can't find any chains for network %s", a_net->pub.name), -2; + + HASH_SORT(l_all_chain_configs, s_cmp_cfg_pri); + dap_chain_t *l_chain; + dap_chain_type_t *l_types_arr; + char l_occupied_default_types[CHAIN_TYPE_MAX] = { 0 }; + int l_poa_signers = 0, l_poa_signers_min = 0; + HASH_ITER(hh, l_all_chain_configs, l_chain_config, l_tmp_cfg) { + if (( l_chain = dap_chain_load_from_cfg(a_net->pub.name, a_net->pub.id, l_chain_config) )) { + DL_APPEND(a_net->pub.chains, l_chain); + l_types_arr = l_chain->default_datum_types; + uint16_t + i = 0, + k = l_chain->default_datum_types_count; + for ( ; i < k; ++i) { + if ( l_occupied_default_types[l_types_arr[i]] ) { + if ( i < k - 1 ) + l_types_arr[i] = l_types_arr[k - 1]; + --i; + --k; + } else + l_occupied_default_types[l_types_arr[i]] = 1; + } + if ( k < l_chain->default_datum_types_count ) { + l_chain->default_datum_types_count = k; + l_chain->default_datum_types = DAP_REALLOC_COUNT(l_chain->default_datum_types, k); + } + if ( !dap_strcmp(DAP_CHAIN_PVT(l_chain)->cs_name, "esbocs") && is_esbocs_debug ) + dap_chain_esbocs_change_debug_mode(l_chain, true); + if (l_chain->callback_load_from_gdb && a_ledger_flags) { + *a_ledger_flags &= ~DAP_LEDGER_MAPPED; + *a_ledger_flags |= DAP_LEDGER_THRESHOLD_ENABLED; + } + if ( l_chain->callback_get_poa_certs ) { + uint16_t l_min_count = 0; + a_net->pub.keys = dap_list_append(a_net->pub.keys, l_chain->callback_get_poa_certs(l_chain, NULL, &l_min_count)); + a_net->pub.keys_min_count += l_min_count; + } + } else { + HASH_DEL(l_all_chain_configs, l_chain_config); + dap_config_close(l_chain_config); + return -3; + } + } + HASH_CLEAR(hh, l_all_chain_configs); + return 0; +} + /** * @brief load network config settings from cellframe-node.cfg file * @@ -1864,107 +1936,42 @@ int s_net_init(const char *a_net_name, const char *a_path, uint16_t a_acl_idx) log_it(L_WARNING, "Can't read seed nodes addresses, work with local balancer only"); // Get list chains name for enabled debug mode - bool is_esbocs_debug = dap_config_get_item_bool_default(l_cfg, "esbocs", "consensus_debug", false); if ( dap_server_enabled() && ( l_net_pvt->node_info->ext_port = dap_config_get_item_uint16(g_config, "server", "ext_port") )) log_it(L_INFO, "Set external port %u for adding in node list", l_net_pvt->node_info->ext_port); - struct dirent *l_dir_entry; // Services register & configure dap_chain_srv_start(l_net->pub.id, DAP_CHAIN_NET_SRV_XCHANGE_LITERAL, NULL); // Harcoded core service starting for exchange capability dap_chain_srv_start(l_net->pub.id, DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_LITERAL, NULL); // Harcoded core service starting for delegated keys storage char *l_services_path = dap_strdup_printf("%s/network/%s/services", dap_config_path(), l_net->pub.name); DIR *l_service_cfg_dir = opendir(l_services_path); DAP_DELETE(l_services_path); - while (l_service_cfg_dir && (l_dir_entry = readdir(l_service_cfg_dir)) != NULL) { - if (l_dir_entry->d_name[0] == '\0') - continue; - const char *l_entry_name = l_dir_entry->d_name; - size_t l_entry_len = strlen(l_entry_name); - if (l_entry_len < 4 || // It has non zero name excluding file extension - strncmp(l_entry_name + l_entry_len - 4, ".cfg", 4) != 0) // its not a .cfg file - continue; - log_it(L_DEBUG, "Opening service config \"%s\"...", l_entry_name); - char *l_service_cfg_path = dap_strdup_printf("network/%s/services/%s", l_net->pub.name, l_entry_name); - dap_config_t *l_cfg_new = dap_config_open(l_service_cfg_path); - if (l_cfg_new) { - char *l_service_name = DAP_DUP_SIZE((char *)l_entry_name, l_entry_len - 3); - l_service_name[l_entry_len - 4] = 0; - dap_chain_srv_start(l_net->pub.id, l_service_name, l_cfg_new); - dap_config_close(l_cfg_new); - DAP_DELETE(l_service_name); - } - DAP_DELETE(l_service_cfg_path); - } - closedir(l_service_cfg_dir); - - /* *** Chains init by configs *** */ - DIR *l_chains_dir = opendir(a_path); - if (!l_chains_dir) - return log_it(L_ERROR, "Can't find any chains for network %s", l_net->pub.name), dap_chain_net_delete(l_net), -7; - - dap_config_t *l_chain_config, *l_all_chain_configs = NULL, *l_tmp_cfg; - char l_chain_cfg_path[MAX_PATH + 1] = { '\0' }; - int l_pos = snprintf(l_chain_cfg_path, MAX_PATH, "network/%s/", a_net_name); - while (( l_dir_entry = readdir(l_chains_dir) )) { - unsigned short l_len = strlen(l_dir_entry->d_name); - if ( l_len > 4 && !dap_strncmp(l_dir_entry->d_name + l_len - 4, ".cfg", 4) ) { - *(l_dir_entry->d_name + l_len - 4) = '\0'; - log_it(L_DEBUG, "Opening chain config \"%s.%s\"", a_net_name, l_dir_entry->d_name); - dap_strncpy(l_chain_cfg_path + l_pos, l_dir_entry->d_name, MAX_PATH - l_pos); - if (!( l_chain_config = dap_config_open(l_chain_cfg_path) )) { - log_it(L_ERROR, "Can't open chain config %s, skip it", l_dir_entry->d_name); + if (l_service_cfg_dir) { + for ( struct dirent *l_dir_entry; ( l_dir_entry = readdir(l_service_cfg_dir) ); ) { + const char *l_entry_name = l_dir_entry->d_name; + size_t l_entry_len = strlen(l_entry_name); + if (l_entry_len < 4 || // It has non zero name excluding file extension + strncmp(l_entry_name + l_entry_len - 4, ".cfg", 4) != 0) // its not a .cfg file continue; + log_it(L_DEBUG, "Opening service config \"%s\"...", l_entry_name); + char *l_service_cfg_path = dap_strdup_printf("network/%s/services/%s", l_net->pub.name, l_entry_name); + dap_config_t *l_cfg_new = dap_config_open(l_service_cfg_path); + if (l_cfg_new) { + char *l_service_name = DAP_DUP_SIZE((char *)l_entry_name, l_entry_len - 3); + l_service_name[l_entry_len - 4] = 0; + dap_chain_srv_start(l_net->pub.id, l_service_name, l_cfg_new); + dap_config_close(l_cfg_new); + DAP_DELETE(l_service_name); } - HASH_ADD_KEYPTR(hh, l_all_chain_configs, l_chain_config->path, strlen(l_chain_config->path), l_chain_config); - } - } - closedir(l_chains_dir); - if (!l_all_chain_configs) - return log_it(L_ERROR, "Can't find any chains for network %s", l_net->pub.name), dap_chain_net_delete(l_net), -8; - - HASH_SORT(l_all_chain_configs, s_cmp_cfg_pri); - dap_chain_t *l_chain; - dap_chain_type_t *l_types_arr; - char l_occupied_default_types[CHAIN_TYPE_MAX] = { 0 }; - HASH_ITER(hh, l_all_chain_configs, l_chain_config, l_tmp_cfg) { - if (( l_chain = dap_chain_load_from_cfg(l_net->pub.name, l_net->pub.id, l_chain_config) )) { - DL_APPEND(l_net->pub.chains, l_chain); - l_types_arr = l_chain->default_datum_types; - uint16_t - i = 0, - k = l_chain->default_datum_types_count; - for ( ; i < k; ++i) { - if ( l_occupied_default_types[l_types_arr[i]] ) { - if ( i < k - 1 ) - l_types_arr[i] = l_types_arr[k - 1]; - --i; - --k; - } else - l_occupied_default_types[l_types_arr[i]] = 1; - } - if ( k < l_chain->default_datum_types_count ) { - l_chain->default_datum_types_count = k; - l_chain->default_datum_types = DAP_REALLOC_COUNT(l_chain->default_datum_types, k); - } - if (!dap_strcmp(DAP_CHAIN_PVT(l_chain)->cs_name, "esbocs") && is_esbocs_debug) { - dap_chain_esbocs_change_debug_mode(l_chain, true); - } - } else { - HASH_DEL(l_all_chain_configs, l_chain_config); - dap_config_close(l_chain_config); - dap_chain_net_delete(l_net); - return -5; + DAP_DELETE(l_service_cfg_path); } + closedir(l_service_cfg_dir); } - HASH_CLEAR(hh, l_all_chain_configs); - - // LEDGER model uint16_t l_ledger_flags = 0; switch ( PVT( l_net )->node_role.enums ) { case NODE_ROLE_LIGHT: //break; - PVT( l_net )->node_role.enums = NODE_ROLE_FULL; // TODO: implement light mode + PVT( a_net )->node_role.enums = NODE_ROLE_FULL; // TODO: implement light mode case NODE_ROLE_FULL: l_ledger_flags |= DAP_LEDGER_CHECK_LOCAL_DS; if (dap_config_get_item_bool_default(g_config, "ledger", "cache_enabled", false)) @@ -1975,23 +1982,12 @@ int s_net_init(const char *a_net_name, const char *a_path, uint16_t a_acl_idx) if (dap_config_get_item_bool_default(g_config, "ledger", "mapped", true)) l_ledger_flags |= DAP_LEDGER_MAPPED; - for (dap_chain_t *l_chain = l_net->pub.chains; l_chain; l_chain = l_chain->next) { - if (l_chain->callback_load_from_gdb) { - l_ledger_flags &= ~DAP_LEDGER_MAPPED; - l_ledger_flags |= DAP_LEDGER_THRESHOLD_ENABLED; - continue; - } - if (!l_chain->callback_get_poa_certs) - continue; - if (!l_net->pub.keys) - l_net->pub.keys = l_chain->callback_get_poa_certs(l_chain, NULL, NULL); - } - if (!l_net->pub.keys) - log_it(L_WARNING, "PoA certificates for net %s not found", l_net->pub.name); + int l_res = s_chains_init_all(l_net, a_path, &l_ledger_flags); + if ( l_res ) + return dap_chain_net_delete(l_net), l_res; // init LEDGER model l_net->pub.ledger = dap_ledger_create(l_net, l_ledger_flags); - return 0; } diff --git a/modules/net/include/dap_chain_net.h b/modules/net/include/dap_chain_net.h index b438c77cad..6f56bf9cc1 100644 --- a/modules/net/include/dap_chain_net.h +++ b/modules/net/include/dap_chain_net.h @@ -62,7 +62,10 @@ typedef struct dap_chain_net { dap_chain_net_id_t id; char name[DAP_CHAIN_NET_NAME_MAX + 1], gdb_nodes[DAP_CHAIN_NET_NAME_MAX + sizeof(s_gdb_nodes_postfix) + 1]; const char *gdb_groups_prefix, *native_ticker; + // PoA section dap_list_t *keys; // List of PoA certs for net + uint16_t keys_min_count; // PoA minimum required number + // dap_chain_t *chains; // double-linked list of chains dap_ledger_t *ledger; uint256_t fee_value; // Net fee -- GitLab From db28812600a04836bf4b8cadaf14ceef32be2815 Mon Sep 17 00:00:00 2001 From: "P. Constantin" <papizh.konstantin@demlabs.net> Date: Wed, 5 Feb 2025 01:05:50 +0700 Subject: [PATCH 04/11] ... --- modules/chain/dap_chain.c | 93 ++-- modules/chain/dap_chain_cell.c | 437 ++++++++++-------- modules/chain/dap_chain_cs.c | 9 +- modules/chain/include/dap_chain.h | 13 +- modules/chain/include/dap_chain_cell.h | 34 +- modules/chain/include/dap_chain_common.h | 16 +- .../consensus/dag-poa/dap_chain_cs_dag_poa.c | 30 +- modules/net/dap_chain_net.c | 159 ++----- modules/type/blocks/dap_chain_cs_blocks.c | 19 +- modules/type/dag/dap_chain_cs_dag.c | 2 +- 10 files changed, 421 insertions(+), 391 deletions(-) diff --git a/modules/chain/dap_chain.c b/modules/chain/dap_chain.c index af633b7822..4084a05703 100644 --- a/modules/chain/dap_chain.c +++ b/modules/chain/dap_chain.c @@ -385,10 +385,11 @@ dap_chain_t *dap_chain_load_from_cfg(const char *a_chain_net_name, dap_chain_net if (!dap_dir_test(DAP_CHAIN_PVT(l_chain)->file_storage_dir)) dap_mkdir_with_parents(DAP_CHAIN_PVT(l_chain)->file_storage_dir); } else - log_it (L_INFO, "Not set file storage path, will not stored in files"); + log_it (L_INFO, "Not set file storage path, will not be stored in files"); // TODO - if (!l_chain->cells) - dap_chain_cell_create_fill( l_chain, (dap_chain_cell_id_t){ .uint64 = 0 } ); + /*if (!l_chain->cells) + dap_chain_cell_create_fill( l_chain, (dap_chain_cell_id_t){ .uint64 = 0 } );*/ + l_chain->config = a_cfg; l_chain->load_priority = dap_config_get_item_uint16_default(a_cfg, "chain", "load_priority", 100); @@ -495,7 +496,7 @@ const char *dap_chain_get_cs_type(dap_chain_t *l_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) // TODO - move to cell.c { int l_ret = 0; pthread_rwlock_rdlock(&l_chain->cell_rwlock); @@ -509,7 +510,7 @@ int dap_chain_save_all(dap_chain_t *l_chain) } //send chain load_progress data to notify socket -bool download_notify_callback(dap_chain_t* a_chain) { +static bool s_load_notify_callback(dap_chain_t* a_chain) { json_object* l_chain_info = json_object_new_object(); json_object_object_add(l_chain_info, "class", json_object_new_string("chain_init")); json_object_object_add(l_chain_info, "net", json_object_new_string(a_chain->net_name)); @@ -529,55 +530,67 @@ bool download_notify_callback(dap_chain_t* a_chain) { */ int dap_chain_load_all(dap_chain_t *a_chain) { - int l_ret = 0; - if (!a_chain) - return -2; + dap_return_val_if_fail(a_chain, -2); if (a_chain->callback_load_from_gdb) { a_chain->is_mapped = false; a_chain->callback_load_from_gdb(a_chain); return 0; } char *l_storage_dir = DAP_CHAIN_PVT(a_chain)->file_storage_dir; - if (!l_storage_dir) - return 0; + dap_return_val_if_fail_err(l_storage_dir, 0, "No path set for chains files in net %s", a_chain->net_name); // TODO: light mode? + DIR *l_dir = opendir(l_storage_dir); - if (!l_dir) { - log_it(L_ERROR, "Cannot open directory %s", DAP_CHAIN_PVT(a_chain)->file_storage_dir); - return -3; - } - for (struct dirent *l_dir_entry = readdir(l_dir); l_dir_entry != NULL; l_dir_entry = readdir(l_dir)) { - const char *l_filename = l_dir_entry->d_name, l_suffix[] = ".dchaincell"; - size_t l_suffix_len = strlen(l_suffix); - if (!strncmp(l_filename + strlen(l_filename) - l_suffix_len, l_suffix, l_suffix_len)) { - uint64_t l_cell_id_uint64 = 0; - sscanf(l_filename, "%"DAP_UINT64_FORMAT_x".dchaincell", &l_cell_id_uint64); - dap_chain_cell_t *l_cell = dap_chain_cell_create_fill(a_chain, (dap_chain_cell_id_t){ .uint64 = l_cell_id_uint64 }); - dap_timerfd_t* l_download_notify_timer = dap_timerfd_start(5000, (dap_timerfd_callback_t)download_notify_callback, a_chain); - l_ret += dap_chain_cell_load(a_chain, l_cell); + dap_return_val_if_fail_err(l_dir, -3, "Cannot open directory %s, error %d: \"%s\"", + DAP_CHAIN_PVT(a_chain)->file_storage_dir, errno, dap_strerror(errno)); + int l_err = -1; + const char l_suffix[] = ".dchaincell", *l_filename; + struct dirent *l_dir_entry = NULL; + dap_time_t l_ts_start = dap_time_now(); + while (( l_dir_entry = readdir(l_dir) )) { + l_filename = l_dir_entry->d_name; + size_t l_namelen = strlen(l_filename); + if ( l_namelen >= sizeof(l_suffix) && !strncmp(l_filename + l_namelen - sizeof(l_suffix) - 1, l_suffix, sizeof(l_suffix) - 1) ) { + dap_timerfd_t* l_load_notify_timer = dap_timerfd_start(5000, (dap_timerfd_callback_t)s_load_notify_callback, a_chain); + l_err = dap_chain_cell_open(a_chain, l_filename, 'a'); + dap_timerfd_delete(l_load_notify_timer->worker, l_load_notify_timer->esocket_uuid); + s_load_notify_callback(a_chain); + if (l_err) + break; if ( DAP_CHAIN_PVT(a_chain)->need_reorder ) { #ifdef DAP_OS_WINDOWS - strcat(l_cell->file_storage_path, ".new"); - if (remove(l_cell->file_storage_path) == -1) { - log_it(L_ERROR, "File %s doesn't exist", l_cell->file_storage_path); - } - *(l_cell->file_storage_path + strlen(l_cell->file_storage_path) - 4) = '\0'; + char *l_new_path = dap_strdup_printf("%s/%s.new", DAP_CHAIN_PVT(a_chain)->file_storage_dir, l_filename); + if ( remove(l_new_path) == -1 ) + log_it(L_ERROR, "File \"%s\" doesn't exist", l_new_path); + DAP_DELETE(l_new_path); #else - const char *l_filename_backup = dap_strdup_printf("%s.unsorted", l_cell->file_storage_path); - if (remove(l_filename_backup) == -1) { + char *l_old_name = dap_strdup_printf("%s/%s", DAP_CHAIN_PVT(a_chain)->file_storage_dir, l_filename), + *l_filename_backup = dap_strdup_printf("%s.unsorted", l_old_name); + + if (remove(l_filename_backup) == -1) log_it(L_ERROR, "File %s doesn't exist", l_filename_backup); + if (rename(l_old_name, l_filename_backup)) { + log_it(L_ERROR, "Couldn't rename %s to %s", l_old_name, 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); + DAP_DEL_MULTY(l_old_name, l_filename_backup); #endif } - dap_timerfd_delete(l_download_notify_timer->worker, l_download_notify_timer->esocket_uuid); - download_notify_callback(a_chain); } } closedir(l_dir); - return l_ret; + + switch (l_err) { + case 0: + log_it(L_INFO, "Loaded all chain \"%s : %s\" cells in %lf s", + a_chain->net_name, a_chain->name, difftime((time_t)dap_time_now(), l_ts_start)); + break; + case -1: + if (!( l_err = dap_chain_cell_open_file(a_chain, "0.dchaincell", 'w') )) + log_it(L_INFO, "Initialized chain \"%s : %s\" cell 0", a_chain->net_name, a_chain->name); + break; + default: + log_it(L_ERROR, "Chain \"%s : %s\" cell was not loaded, error %d", a_chain->net_name, a_chain->name, l_err) + } + return l_err; } /** @@ -904,11 +917,7 @@ void dap_chain_datum_notify(dap_chain_cell_t *a_chain_cell, dap_hash_fast_t *a_ dap_list_t *l_iter; DL_FOREACH(a_chain_cell->chain->datum_notifiers, l_iter) { dap_chain_datum_notifier_t *l_notifier = (dap_chain_datum_notifier_t*)l_iter->data; - struct chain_thread_datum_notifier *l_arg = DAP_NEW_Z(struct chain_thread_datum_notifier); - if (!l_arg) { - log_it(L_CRITICAL, "%s", c_error_memory_alloc); - continue; - } + struct chain_thread_datum_notifier *l_arg = DAP_NEW_Z_RET_IF_FAIL(struct chain_thread_datum_notifier); *l_arg = (struct chain_thread_datum_notifier) { .callback = l_notifier->callback, .callback_arg = l_notifier->arg, .chain = a_chain_cell->chain, .cell_id = a_chain_cell->id, diff --git a/modules/chain/dap_chain_cell.c b/modules/chain/dap_chain_cell.c index 2f81640f4c..cf26c6514d 100644 --- a/modules/chain/dap_chain_cell.c +++ b/modules/chain/dap_chain_cell.c @@ -42,6 +42,9 @@ #define DAP_CHAIN_CELL_FILE_TYPE_RAW 0 #define DAP_CHAIN_CELL_FILE_TYPE_COMPRESSED 1 #define DAP_MAPPED_VOLUME_LIMIT ( 1 << 28 ) // 256 MB for now, may be should be configurable? + +#define CELL_FILE_EXT "dchaincell" + /** * @struct dap_chain_cell_file_header */ @@ -117,6 +120,7 @@ DAP_STATIC_INLINE void s_cell_reclaim_cur_volume(dap_chain_cell_t *a_cell) { } #endif +#if 0 DAP_STATIC_INLINE int s_cell_file_write_header(dap_chain_cell_t *a_cell) { dap_chain_cell_file_header_t l_hdr = { @@ -129,8 +133,9 @@ DAP_STATIC_INLINE int s_cell_file_write_header(dap_chain_cell_t *a_cell) }; return fwrite(&l_hdr, sizeof(l_hdr), 1, a_cell->file_storage) ? fflush(a_cell->file_storage) : -1; } +#endif -DAP_STATIC_INLINE int s_cell_map_new_volume(dap_chain_cell_t *a_cell, size_t a_fpos, bool a_load) { +DAP_STATIC_INLINE int s_cell_map_new_volume(dap_chain_cell_mmap_data_t *a_cell_map_data, size_t a_fpos, bool a_load) { #ifdef DAP_OS_WINDOWS HANDLE hSection = NULL; if ( !a_fpos ) { @@ -144,7 +149,8 @@ DAP_STATIC_INLINE int s_cell_map_new_volume(dap_chain_cell_t *a_cell, size_t a_f }; NTSTATUS err = pfnNtCreateSection(&hSection, SECTION_MAP_READ | SECTION_EXTEND_SIZE, - NULL, &SectionSize, PAGE_READWRITE, SEC_RESERVE, (HANDLE)_get_osfhandle(fileno(a_cell->file_storage))); + NULL, &SectionSize, PAGE_READWRITE, SEC_RESERVE, + (HANDLE)_get_osfhandle(fileno(a_cell->file_storage))); if ( !NT_SUCCESS(err) ) return log_it(L_ERROR, "NtCreateSection() failed, status %lx: \"%s\"", err, dap_str_ntstatus(err) ), -1; @@ -191,24 +197,7 @@ DAP_STATIC_INLINE int s_cell_map_new_volume(dap_chain_cell_t *a_cell, size_t a_f return 0; } -/** - * @brief dap_chain_cell_find_by_id - * get dap_chain_cell_t object by cell (shard) id - * @param a_chain dap_chain_t object - * @param a_cell_id dap_chain_cell_id_t cell (shard) id - * @return dap_chain_cell_t* - */ -dap_chain_cell_t * dap_chain_cell_find_by_id(dap_chain_t * a_chain, dap_chain_cell_id_t a_cell_id) -{ - if (!a_chain->cells) - return NULL; - dap_chain_cell_t *l_cell = NULL; - pthread_rwlock_rdlock(&a_chain->cell_rwlock); - HASH_FIND(hh, a_chain->cells, &a_cell_id, sizeof(dap_chain_cell_id_t), l_cell); - pthread_rwlock_unlock(&a_chain->cell_rwlock); - return l_cell; -} - +#if 0 /** * @brief * a_cell_id if < 0 then not used @@ -216,7 +205,7 @@ dap_chain_cell_t * dap_chain_cell_find_by_id(dap_chain_t * a_chain, dap_chain_ce * @param a_cell_id dap_chain_cell_id_t cell (shard) id * @return dap_chain_cell_t* */ -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_fill(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id) { dap_chain_cell_t * l_cell = NULL; pthread_rwlock_wrlock(&a_chain->cell_rwlock); @@ -233,6 +222,7 @@ dap_chain_cell_t * dap_chain_cell_create_fill(dap_chain_t * a_chain, dap_chain_c DAP_DELETE(l_cell); \ pthread_rwlock_unlock(&a_chain->cell_rwlock); \ NULL; }) + if ( !(l_file = fopen(file_storage_path, "a+b")) ) { log_it(L_ERROR, "Chain cell \"%s\" 0x%016"DAP_UINT64_FORMAT_X" cannot be opened, error %d", file_storage_path, a_cell_id.uint64, errno); @@ -263,6 +253,7 @@ dap_chain_cell_t * dap_chain_cell_create_fill(dap_chain_t * a_chain, dap_chain_c log_it(L_NOTICE, "Initialized file storage for cell 0x%016"DAP_UINT64_FORMAT_X" \"%s\"", a_cell_id.uint64, file_storage_path); fflush(l_file); + l_file = freopen(file_storage_path, "a+b", l_file); } if ( a_chain->is_mapped && s_cell_map_new_volume(l_cell, 0, true) ) { @@ -276,15 +267,10 @@ dap_chain_cell_t * dap_chain_cell_create_fill(dap_chain_t * a_chain, dap_chain_c return l_cell; } -/** - * @brief - * close a_cell->file_storage file object - * @param a_cell dap_chain_cell_t object - */ -void dap_chain_cell_close(dap_chain_cell_t *a_cell) -{ - if(!a_cell) - return; +#endif + +DAP_STATIC_INLINE int s_cell_close(dap_chain_cell_t *a_cell) { + pthread_rwlock_wrlock(&a_cell->storage_rwlock); if(a_cell->file_storage) { fclose(a_cell->file_storage); a_cell->file_storage = NULL; @@ -320,8 +306,31 @@ void dap_chain_cell_close(dap_chain_cell_t *a_cell) DAP_DELETE(l_orig); } #endif + pthread_rwlock_unlock(&a_cell->storage_rwlock); + pthread_rwlock_destroy(&a_cell->storage_rwlock); +} + +/** + * @brief + * close a_cell->file_storage file object + * @param a_cell dap_chain_cell_t object + */ +void dap_chain_cell_close(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id) +{ + dap_return_if_fail(a_chain); + dap_chain_cell_t *l_cell = NULL; + HASH_FIND(hh, a_chain->cells, &a_cell_id, sizeof(dap_chain_cell_id_t), l_cell); + if (l_cell) { + s_cell_close(l_cell); + HASH_DEL(a_chain->cells, l_cell); + DAP_DELETE(l_cell); + } else + log_it(L_ERROR, "Cell 0x%016"DAP_UINT64_FORMAT_X" not found in chain \"%s : %s\"", + a_cell_id.uint64, a_chain->net_name, a_chain->name); + pthread_rwlock_unlock(&a_chain->cell_rwlock); } +#if 0 /** * @brief * free chain cell objects @@ -387,15 +396,16 @@ void dap_chain_cell_delete_all_and_free_file(dap_chain_t *a_chain) { pthread_rwlock_unlock(&a_chain->cell_rwlock); } -void dap_chain_cell_delete_all(dap_chain_t *a_chain) { +#endif + +void dap_chain_cell_close_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); + s_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); @@ -408,107 +418,90 @@ void dap_chain_cell_delete_all(dap_chain_t *a_chain) { * @param a_cell_file_path contains name of chain, for example "0.dchaincell" * @return */ -int dap_chain_cell_load(dap_chain_t *a_chain, dap_chain_cell_t *a_cell) +DAP_STATIC_INLINE int s_cell_load_from_file(dap_chain_cell_t *a_cell) { - if (!a_cell) - return -1; - off_t l_full_size = !fseeko(a_cell->file_storage, 0, SEEK_END) ? ftello(a_cell->file_storage) : -1; - if (l_full_size < 0) - return log_it(L_ERROR, "Can't get chain size, error %d: \"%s\"", errno, dap_strerror(errno)), -1; - if ( l_full_size < (off_t)sizeof(dap_chain_cell_file_header_t) ) { - log_it(L_ERROR, "Chain cell \"%s\" is corrupt, create new file", a_cell->file_storage_path); - return -1; - } - dap_chain_cell_file_header_t *l_hdr = NULL; - if (a_chain->is_mapped) { - l_hdr = (dap_chain_cell_file_header_t*)a_cell->map; - } else { - fseeko(a_cell->file_storage, 0, SEEK_SET); - l_hdr = DAP_NEW(dap_chain_cell_file_header_t); - if ( fread(l_hdr, 1, sizeof(*l_hdr), a_cell->file_storage) != sizeof(*l_hdr) ) { - log_it(L_ERROR,"Can't read chain header \"%s\"", a_cell->file_storage_path); - fclose(a_cell->file_storage); - DAP_DELETE(l_hdr); - return -2; + off_t l_pos, l_full_size = !fseeko(a_cell->file_storage, 0, SEEK_END) ? ftello(a_cell->file_storage) : -1; + dap_return_val_if_fail_err(l_full_size < 0, 1, "Can't get chain size, error %d: \"%s\"", errno, dap_strerror(errno)); + dap_return_val_if_fail_err(l_full_size < (off_t)sizeof(dap_chain_cell_file_header_t), 2, "Chain cell \"%s\" is corrupt, create new file", a_cell->file_storage_path); + + /* Load header */ + { + dap_chain_cell_file_header_t *l_hdr = DAP_NEW_STACK(dap_chain_cell_file_header_t); + if (a_cell->chain->is_mapped) { + dap_return_val_if_pass_err( s_cell_map_new_volume(a_cell, 0, false), -3, "Error on mapping the first volume" ); + l_hdr = (dap_chain_cell_file_header_t*)a_cell->map; + } else { + fseeko(a_cell->file_storage, 0, SEEK_SET); + dap_return_val_if_fail_err( fread(l_hdr, 1, sizeof(*l_hdr), a_cell->file_storage) != sizeof(*l_hdr), -4, + "Can't read chain header \"%s\"", a_cell->file_storage_path ); } - } - if (l_hdr->signature != DAP_CHAIN_CELL_FILE_SIGNATURE) { - log_it(L_ERROR, "Wrong signature in chain \"%s\", possible file corrupt", a_cell->file_storage_path); - fclose(a_cell->file_storage); - if (!a_chain->is_mapped) DAP_DELETE(l_hdr); - return -3; - } - if (l_hdr->version < DAP_CHAIN_CELL_FILE_VERSION ){ - log_it(L_ERROR, "Too low chain version, backup files"); - fclose(a_cell->file_storage); - if (!a_chain->is_mapped) DAP_DELETE(l_hdr); - return -4; - } - off_t l_pos = sizeof(*l_hdr); - if (a_chain->is_mapped) - a_cell->map_pos = a_cell->map + l_pos; - if (l_full_size == l_pos) { - return fseeko(a_cell->file_storage, l_pos, SEEK_SET); + dap_return_val_if_fail_err( l_hdr->cell_id.uint64 == a_cell->id.uint64, 5, + "Wrong cell id, %lu != %lu", l_hdr->cell_id.uint64, a_cell->id.uint64); + dap_return_val_if_fail_err( l_hdr->signature == DAP_CHAIN_CELL_FILE_SIGNATURE, 5, + "Wrong signature in chain \"%s\", possible file corrupt", a_cell->file_storage_path ); + dap_return_val_if_fail_err( l_hdr->version >= DAP_CHAIN_CELL_FILE_VERSION, -6, + "Too low chain version %d < %d, create a backup", l_hdr->version, DAP_CHAIN_CELL_FILE_VERSION ); + l_pos = sizeof(*l_hdr); + if (a_cell->chain->is_mapped) + a_cell->map_pos = a_cell->map + l_pos; + if (l_full_size == l_pos) + return 0; // fseeko(a_cell->file_storage, l_pos, SEEK_SET); } + /* Load atoms */ int l_ret = 0; uint64_t l_el_size = 0, q = 0; - if (a_chain->is_mapped) { + if (a_cell->chain->is_mapped) { dap_hash_fast_t l_atom_hash; for ( off_t l_vol_rest = 0; l_pos + sizeof(uint64_t) < (size_t)l_full_size; ++q, l_pos += l_el_size + sizeof(uint64_t) ) { l_vol_rest = (off_t)(a_cell->map_end - a_cell->map_pos) - sizeof(uint64_t); if ( l_vol_rest <= 0 || (uint64_t)l_vol_rest < *(uint64_t*)a_cell->map_pos ) - if ( s_cell_map_new_volume(a_cell, l_pos, true) ) { - l_ret = -2; - break; - } + dap_return_val_if_pass_err( s_cell_map_new_volume(a_cell, l_pos, true), -7, "Error on mapping a new volume" ); l_el_size = *(uint64_t*)a_cell->map_pos; if ( !l_el_size || l_el_size > (size_t)(l_full_size - l_pos) ) break; a_cell->map_pos += sizeof(uint64_t); dap_chain_atom_ptr_t l_atom = (dap_chain_atom_ptr_t)(a_cell->map_pos); dap_hash_fast(l_atom, l_el_size, &l_atom_hash); - a_chain->callback_atom_add(a_chain, l_atom, l_el_size, &l_atom_hash, false); + a_cell->chain->callback_atom_add(a_cell->chain, l_atom, l_el_size, &l_atom_hash, false); a_cell->map_pos += l_el_size; - a_chain->load_progress = (int)((float)l_pos/l_full_size * 100 + 0.5); + a_cell->chain->load_progress = (int)((float)l_pos/l_full_size * 100 + 0.5); } #ifndef DAP_OS_WINDOWS s_cell_reclaim_cur_volume(a_cell); #endif } else { - DAP_DELETE(l_hdr); size_t l_read = 0; while ((l_read = fread(&l_el_size, 1, sizeof(l_el_size), a_cell->file_storage)) && !feof(a_cell->file_storage)) { if (l_read != sizeof(l_el_size) || l_el_size == 0) { log_it(L_ERROR, "Corrupted element size %zu, chain %s is damaged", l_el_size, a_cell->file_storage_path); - l_ret = -4; + l_ret = 8; 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_CRITICAL, "Memory allocation error"); - l_ret = -5; + l_ret = -9; break; } l_read = fread((void*)l_element, 1, l_el_size, a_cell->file_storage); if (l_read != l_el_size) { log_it(L_ERROR, "Read only %lu of %zu bytes, stop cell loading", l_read, l_el_size); DAP_DELETE(l_element); - l_ret = -6; + l_ret = 10; break; } l_pos += sizeof(uint64_t) + l_read; - a_chain->load_progress = (int)((float)l_pos/l_full_size * 100 + 0.5); + a_cell->chain->load_progress = (int)((float)l_pos/l_full_size * 100 + 0.5); dap_hash_fast_t l_atom_hash = {}; dap_hash_fast(l_element, l_el_size, &l_atom_hash); - dap_chain_atom_verify_res_t l_res = a_chain->callback_atom_add(a_chain, l_element, l_el_size, &l_atom_hash, false); - if (l_res != ATOM_ACCEPT && l_res != ATOM_FORK) { + dap_chain_atom_verify_res_t l_res = a_cell->chain->callback_atom_add(a_cell->chain, l_element, l_el_size, &l_atom_hash, false); + if (l_res != ATOM_ACCEPT && l_res != ATOM_FORK) DAP_DELETE(l_element); - } ++q; } } - if ( l_pos < l_full_size ) { + if ( l_pos < l_full_size && l_ret > 0 ) { log_it(L_ERROR, "Chain \"%s\" has incomplete tail, truncating %zu bytes", a_cell->file_storage_path, l_full_size - l_pos ); #ifdef DAP_OS_WINDOWS @@ -516,9 +509,8 @@ int dap_chain_cell_load(dap_chain_t *a_chain, dap_chain_cell_t *a_cell) LARGE_INTEGER SectionSize = (LARGE_INTEGER) { .QuadPart = l_pos }; HANDLE hSection = (HANDLE)a_cell->map_range_bounds->data; NTSTATUS err = pfnNtExtendSection(hSection, &SectionSize); - if ( !NT_SUCCESS(err) ) { + if ( !NT_SUCCESS(err) ) log_it(L_ERROR, "NtExtendSection() failed, status %lx", err); - } } else #endif ftruncate(fileno(a_cell->file_storage), l_pos); @@ -528,38 +520,125 @@ int dap_chain_cell_load(dap_chain_t *a_chain, dap_chain_cell_t *a_cell) return l_ret; } +DAP_STATIC_INLINE int s_cell_open(dap_chain_t *a_chain, const char *a_filename, const char a_mode) { + dap_chain_cell_id_t l_cell_id = { }; + { /* Check filename */ + char l_fmt[20] = "", l_ext[ sizeof(CELL_FILE_EXT) ] = "", l_ext2 = '\0'; + snprintf(l_fmt, sizeof(l_fmt), "%s%d%s", "%"DAP_UINT64_FORMAT_x".%", sizeof(CELL_FILE_EXT) - 1, "[^.].%c"); + + switch ( sscanf(a_filename, l_fmt, &l_cell_id.uint64, l_ext, &l_ext2) ) { + case 3: + case 2: + if ( !dap_strncmp(l_ext, CELL_FILE_EXT) ) + break; + default: + return log_it(L_ERROR, "Invalid cell file name \"%s\"", a_filename), EINVAL; + } + } + + const char file_storage_path[MAX_PATH], mode[] = { a_mode, '+', 'b', '\0' }; + snprintf(file_storage_path, MAX_PATH, "%s/%s", DAP_CHAIN_PVT(a_chain)->file_storage_dir, a_filename); + dap_chain_cell_t *l_cell = NULL; + +#define m_ret_err(err, ...) return ({ if (l_cell->file_storage) fclose(l_cell->file_storage); \ + DAP_DELETE(l_cell); log_it(L_ERROR, ##__VA_ARGS__), err }) + + dap_chain_cell_mmap_data_t l_cell_map_data = { }; + HASH_FIND(hh, a_chain->cells, &l_cell_id, sizeof(dap_chain_cell_id_t), l_cell); + if (l_cell) { + if (a_mode == 'w') { + s_cell_close(l_cell); + HASH_DEL(a_chain->cells, l_cell); + DAP_DELETE(l_cell); + } else + m_ret_err(EEXIST, "Cell \"%s\" is already loaded in chain \"%s : %s\"", + a_filename, a_chain->net_name, a_chain->name); + } + FILE *l_file = fopen(file_storage_path, mode); + if ( !l_file ) + m_ret_err(errno, "Cell \"%s : %s / \"%s\" cannot be opened, error %d", + a_chain->net_name, a_chain->name, a_filename, errno); + + l_cell = DAP_NEW_Z(dap_chain_cell_t); + *l_cell = (dap_chain_cell_t) { + .id = l_cell_id, + .chain = a_chain, + .file_storage = l_file, + .storage_rwlock = PTHREAD_RWLOCK_INITIALIZER + }; + dap_strncpy(l_cell->file_storage_path, file_storage_path, MAX_PATH); + + switch (a_mode) { + case 'a': { + int l_load_res = s_cell_load_from_file(l_cell); + if (!l_load_res) + break; + else if (l_load_res < 0) + m_ret_err(errno, "Cell \"%s : %s / \"%s\" cannot be loaded, code %d", + a_chain->net_name, a_chain->name, a_filename, l_load_res); + // Otherwise, rewrite the file from scratch + } + case 'w': { + 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 = a_chain->id, + .chain_net_id = a_chain->net_id, + .cell_id = l_cell_id + }; + if ( !fwrite(&l_hdr, sizeof(l_hdr), 1, l_cell->file_storage) ) + m_ret_err(errno, "fwrite() error %d", errno); + fflush(l_cell->file_storage); + l_cell->file_storage = freopen(file_storage_path, "a+b", l_cell->file_storage); + if ( a_chain->is_mapped && s_cell_map_new_volume(l_cell, 0, false) ) + m_ret_err(EINVAL, "Error on mapping the first volume"); + } + default: + break; + } + HASH_ADD(hh, a_chain->cells, id, sizeof(dap_chain_cell_id_t), l_cell); + log_it(L_INFO, "Cell storage \"%s\" is %s for chain \"%s : %s\"", + a_filename, a_mode == 'w' ? "created" : "opened" a_chain->net_name, a_chain->name); + return 0; +} + +int dap_chain_cell_open(dap_chain_t *a_chain, const char *a_filename, const char a_mode) { + pthread_rwlock_wrlock(&a_chain->cell_rwlock); + int l_ret = s_cell_open(a_chain, a_filename, a_mode); + pthread_rwlock_unlock(&a_chain->cell_rwlock); + return l_ret; +#undef m_ret_err +} + static int s_cell_file_atom_add(dap_chain_cell_t *a_cell, dap_chain_atom_ptr_t a_atom, uint64_t a_atom_size) { - if (!a_atom || !a_atom_size) { - log_it(L_CRITICAL, "Invalid arguments"); - return -1; - } + dap_return_val_if_fail(a_atom && a_atom_size, -1); + if (a_cell->chain->is_mapped) { off_t l_pos = !fseeko(a_cell->file_storage, 0, SEEK_END) ? ftello(a_cell->file_storage) : -1; - if (l_pos < 0) - return log_it(L_ERROR, "Can't get chain size, error %d: \"%s\"", errno, dap_strerror(errno)), -1; + dap_return_val_if_pass_err(l_pos < 0, -1, "Can't get \"%s : %s\" cell 0x%016"DAP_UINT64_FORMAT_X" size, error %d", + a_cell->chain->net_name, a_cell->chain->name, a_cell->id, errno); debug_if (s_debug_more, L_DEBUG, "Before filling volume for atom size %ld, stream pos of %s is %lu, map pos is %lu, space left in map %lu", - a_atom_size, a_cell->file_storage_path, l_pos, (size_t)(a_cell->map_pos - a_cell->map), (size_t)(a_cell->map_end - a_cell->map_pos)); + a_atom_size, a_cell->file_storage_path, l_pos, (size_t)(a_cell->map_pos - a_cell->map), (size_t)(a_cell->map_end - a_cell->map_pos)); if ( a_atom_size + sizeof(uint64_t) > (size_t)(a_cell->map_end - a_cell->map_pos) ) - if ( s_cell_map_new_volume(a_cell, (size_t)l_pos, false) ) - return -2; + dap_return_val_if_pass_err( + s_cell_map_new_volume(a_cell, (size_t)l_pos, false), + -2, "Failed to create new map volume for \"%s : %s\" cell 0x%016"DAP_UINT64_FORMAT_X"", + a_cell->chain->net_name, a_cell->chain->name, a_cell->id + ); } debug_if (s_debug_more && a_cell->chain->is_mapped, L_DEBUG, "Before writing an atom of size %lu, stream pos of %s is %ld and pos is %lu, space left in map %lu", a_atom_size, a_cell->file_storage_path, ftello(a_cell->file_storage), (size_t)(a_cell->map_pos - a_cell->map), (size_t)(a_cell->map_end - a_cell->map_pos)); + dap_return_val_if_fail_err( + fwrite(&a_atom_size, sizeof(a_atom_size), 1, a_cell->file_storage) == 1 && + fwrite(a_atom, a_atom_size, 1, a_cell->file_storage) == 1, + -3, "Can't write atom (%zu b) to \"%s : %s\" cell 0x%016"DAP_UINT64_FORMAT_X", error %d: \"%s\"", + a_atom_size, a_cell->chain->net_name, a_cell->chain->name, a_cell->id, errno, dap_strerror(errno) + ); - 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, a_atom_size, 1, a_cell->file_storage) != 1) { - log_it(L_ERROR, "Can't write atom (%zu b) to file \"%s\", err %d: \"%s\"", - a_atom_size, a_cell->file_storage_path, errno, dap_strerror(errno) ); - return -3; - } debug_if (s_debug_more && a_cell->chain->is_mapped, L_DEBUG, "After writing an atom of size %lu, stream pos of %s is %lu and map shift is %lu", a_atom_size, a_cell->file_storage_path, ftello(a_cell->file_storage), (size_t)(a_cell->map_pos - a_cell->map)); @@ -570,7 +649,7 @@ static int s_cell_file_atom_add(dap_chain_cell_t *a_cell, dap_chain_atom_ptr_t a MAP_PRIVATE|MAP_FIXED, fileno(a_cell->file_storage), a_cell->cur_vol_start)) ) { log_it(L_ERROR, "Chain cell \"%s\" 0x%016"DAP_UINT64_FORMAT_X" cannot be remapped, errno %d", a_cell->file_storage_path, a_cell->id.uint64, errno); - return -1; + return -2; } } #endif @@ -582,110 +661,100 @@ static int s_cell_file_atom_add(dap_chain_cell_t *a_cell, dap_chain_atom_ptr_t a * add atoms to selected chain * @param a_cell - cell object. Contains file path to cell storage data, for example - "0.dchaincell" * a_cell->chain contains - * name - "zerochain" - * net_name - "kelvin-testnet" - * filepath - "C:\\Users\\Public\\Documents\\cellframe-node\\var\\lib\\network\\kelvin-testnet\\zerochain\\/0.dchaincell" + * name + * net_name + * filepath * @param a_atom * @param a_atom_size * @return */ 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; - if (!a_atom && !a_cell->chain) { - log_it(L_WARNING,"Chain not found for cell 0x%016"DAP_UINT64_FORMAT_X" ( %s )", - a_cell->id.uint64, a_cell->file_storage_path); - return -1; - } - size_t l_total_res = 0, l_count = 0; - bool l_err = false; + dap_return_val_if_fail(a_cell, -1); + dap_return_val_if_pass_err(!a_atom && !a_cell->chain, -2, "Chain not found for cell 0x%016"DAP_UINT64_FORMAT_X" %s ", + a_cell->id.uint64, a_cell->file_storage_path); + size_t l_size = 0, l_count = 0; + int l_err = -1; pthread_rwlock_wrlock(&a_cell->storage_rwlock); - if (!a_atom || !a_atom_size) { + if ( a_atom && a_atom_size ) { + //pthread_rwlock_wrlock(a_cell->chain->cell_rwlock); + debug_if (s_debug_more && a_cell->chain->is_mapped, L_DEBUG, "Before appending an atom of size %lu, stream pos of %s is %lu, map pos is %lu", + a_atom_size, a_cell->file_storage_path, ftello(a_cell->file_storage), + (size_t)(a_cell->map_pos - a_cell->map)); + + if ( !s_cell_file_atom_add(a_cell, a_atom, a_atom_size) ) { + ++l_count; + l_size = a_atom_size + sizeof(uint64_t); + debug_if (s_debug_more && a_cell->chain->is_mapped, L_DEBUG,"After appending an atom of size %lu, stream pos of %s is %lu, map pos is %lu", + a_atom_size, a_cell->file_storage_path, ftello(a_cell->file_storage), + (size_t)(a_cell->map_end - a_cell->map_pos)); #ifdef DAP_OS_WINDOWS - strcat(a_cell->file_storage_path, ".new"); + if (a_cell->chain->is_mapped) { + off_t l_off = ftello(a_cell->file_storage); + LARGE_INTEGER SectionSize = (LARGE_INTEGER) { .QuadPart = l_off }; + HANDLE hSection = (HANDLE)a_cell->map_range_bounds->data; + NTSTATUS err = pfnNtExtendSection(hSection, &SectionSize); + if ( !NT_SUCCESS(err) ) { + log_it(L_ERROR, "NtExtendSection() failed, status %lx: \"%s\"", + err, dap_str_ntstatus(err) ); + l_err = -2; + } + } #endif - a_cell->file_storage = freopen(a_cell->file_storage_path, "w+b", a_cell->file_storage); - debug_if (s_debug_more,L_DEBUG, "Rewinding file %s", a_cell->file_storage_path); + } + //pthread_rwlock_unlock(a_cell->chain->cell_rwlock); + } else { + if (a_cell->chain->is_mapped) { + log_it(L_ERROR, "Unable to rewrite memory-mapped chain"); + // TODO: do we actually need it besides zerochain reordering issue? + pthread_rwlock_unlock(&a_cell->storage_rwlock); + return -3; + } + const char *l_fname = dap_strdup_printf("%"DAP_UINT64_FORMAT_x "." CELL_FILE_EXT +#ifdef DAP_OS_WINDOWS + ".new" +#endif + , a_cell->id.uint64); bool was_mapped = a_cell->chain->is_mapped; a_cell->chain->is_mapped = false; - if ( s_cell_file_write_header(a_cell) < 0 ) { - 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); - a_cell->chain->is_mapped = was_mapped; + l_err = dap_chain_cell_open(a_cell->chain, l_fname, 'w'); + DAP_DELETE(l_fname); + if (l_err) { + log_it(L_ERROR, "Can't open chain \"%s : %s\" cell, code %d", a_cell->chain->net_name, a_cell->chain->name, l_err); pthread_rwlock_unlock(&a_cell->storage_rwlock); - return -2; + return -3; } - l_total_res += sizeof(dap_chain_cell_file_header_t); + l_size += sizeof(dap_chain_cell_file_header_t); dap_chain_atom_iter_t *l_atom_iter = a_cell->chain->callback_atom_iter_create(a_cell->chain, a_cell->id, NULL); dap_chain_atom_ptr_t l_atom; uint64_t l_atom_size = 0; + //pthread_rwlock_wrlock(a_cell->chain->cell_rwlock); for (l_atom = a_cell->chain->callback_atom_iter_get(l_atom_iter, DAP_CHAIN_ITER_OP_FIRST, &l_atom_size); - l_atom && l_atom_size; + l_atom && l_atom_size && !( l_err = s_cell_file_atom_add(a_cell, l_atom, l_atom_size) ); l_atom = a_cell->chain->callback_atom_iter_get(l_atom_iter, DAP_CHAIN_ITER_OP_NEXT, &l_atom_size)) { - if ( s_cell_file_atom_add(a_cell, l_atom, l_atom_size) ) { - l_err = true; - break; - } else { - l_total_res += sizeof(uint64_t) + l_atom_size; - ++l_count; - } + l_size += sizeof(uint64_t) + l_atom_size; + ++l_count; } - a_cell->chain->is_mapped = was_mapped; a_cell->chain->callback_atom_iter_delete(l_atom_iter); + a_cell->chain->is_mapped = was_mapped; debug_if (s_debug_more && a_cell->chain->is_mapped,L_DEBUG, "After rewriting file %s, stream pos is %lu and map pos is %lu", a_cell->file_storage_path, ftello(a_cell->file_storage), (size_t)(a_cell->map_pos - a_cell->map)); - } else { - debug_if (s_debug_more && a_cell->chain->is_mapped,L_DEBUG, "Before appending an atom of size %lu, stream pos of %s is %lu, map pos is %lu", - a_atom_size, a_cell->file_storage_path, ftello(a_cell->file_storage), - (size_t)(a_cell->map_pos - a_cell->map)); - if ( s_cell_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; - } - debug_if (s_debug_more && a_cell->chain->is_mapped, L_DEBUG,"After appending an atom of size %lu, stream pos of %s is %lu, map pos is %lu", - a_atom_size, a_cell->file_storage_path, ftello(a_cell->file_storage), - (size_t)(a_cell->map_end - a_cell->map_pos)); - ++l_count; - l_total_res = a_atom_size + sizeof(uint64_t); + //pthread_rwlock_unlock(a_cell->chain->cell_rwlock); } - - if (l_total_res) { + + if (l_size) { #ifndef DAP_OS_DARWIN fflush(a_cell->file_storage); #endif -#ifdef DAP_OS_WINDOWS - if (a_cell->chain->is_mapped) { - off_t l_off = ftello(a_cell->file_storage); - if (l_off < 0) { - log_it(L_ERROR, "Can't get chain size!"); - l_err = true; - } else { - LARGE_INTEGER SectionSize = (LARGE_INTEGER) { .QuadPart = l_off }; - HANDLE hSection = (HANDLE)a_cell->map_range_bounds->data; - NTSTATUS err = pfnNtExtendSection(hSection, &SectionSize); - if ( !NT_SUCCESS(err) ) { - log_it(L_ERROR, "NtExtendSection() failed, status %lx: \"%s\"", - err, dap_str_ntstatus(err) ); - l_err = true; - } - } - } -#endif - 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!"); - } + log_it(L_DEBUG, "Saved %zu atom%s (%zu bytes) to chain \"%s : %s\" cell 0x%016"DAP_UINT64_FORMAT_X"", + l_count, l_count > 1 ? "s" : "", l_size, a_cell->chain->net_name, a_cell->chain->name, a_cell->id.uint64); + debug_if(l_err, L_WARNING, "Not all data was saved due to writing error %d!", l_err); } 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 l_total_res; + return l_size; } - diff --git a/modules/chain/dap_chain_cs.c b/modules/chain/dap_chain_cs.c index 124f0af805..d2e296b577 100644 --- a/modules/chain/dap_chain_cs.c +++ b/modules/chain/dap_chain_cs.c @@ -95,8 +95,7 @@ int dap_chain_cs_load(dap_chain_t *a_chain, dap_config_t *a_chain_cfg) { dap_chain_cs_callbacks_item_t *l_item = NULL; HASH_FIND_STR(s_cs_callbacks, DAP_CHAIN_PVT(a_chain)->cs_name, l_item); - if (!l_item) - return log_it(L_ERROR, "Callbacks for cs %s not found!", DAP_CHAIN_PVT(a_chain)->cs_name), -1; + dap_return_val_if_fail_err(l_item, -1, "Callbacks for cs %s not found!", DAP_CHAIN_PVT(a_chain)->cs_name); return l_item->callbacks.callback_load ? l_item->callbacks.callback_load(a_chain, a_chain_cfg) : 0; @@ -106,8 +105,7 @@ int dap_chain_cs_class_delete(dap_chain_t *a_chain) { dap_chain_cs_class_callbacks_item_t *l_item = NULL; HASH_FIND_STR(s_class_callbacks, DAP_CHAIN_PVT(a_chain)->cs_type, l_item); - if (!l_item) - return log_it(L_ERROR, "Callbacks for cs %s not found!", DAP_CHAIN_PVT(a_chain)->cs_name), -1; + dap_return_val_if_fail_err(l_item, -1, "Callbacks for cs %s not found!", DAP_CHAIN_PVT(a_chain)->cs_name); return l_item->callbacks.callback_delete ? l_item->callbacks.callback_delete(a_chain) : 0; @@ -117,8 +115,7 @@ int dap_chain_cs_class_purge(dap_chain_t *a_chain) { dap_chain_cs_class_callbacks_item_t *l_item = NULL; HASH_FIND_STR(s_class_callbacks, DAP_CHAIN_PVT(a_chain)->cs_type, l_item); - if (!l_item) - return log_it(L_ERROR, "Callbacks for cs %s not found!", DAP_CHAIN_PVT(a_chain)->cs_name), -1; + dap_return_val_if_fail_err(l_item, -1, "Callbacks for cs %s not found!", DAP_CHAIN_PVT(a_chain)->cs_name); return l_item->callbacks.callback_purge ? l_item->callbacks.callback_purge(a_chain) : 0; diff --git a/modules/chain/include/dap_chain.h b/modules/chain/include/dap_chain.h index 467e1b01bb..5d26c66bb3 100644 --- a/modules/chain/include/dap_chain.h +++ b/modules/chain/include/dap_chain.h @@ -71,15 +71,16 @@ typedef struct dap_chain_datum_iter { } dap_chain_datum_iter_t; typedef enum dap_chain_atom_verify_res{ - ATOM_ACCEPT = 0, ATOM_PASS, ATOM_REJECT, ATOM_MOVE_TO_THRESHOLD, ATOM_FORK + ATOM_ACCEPT = 0, ATOM_PASS, ATOM_REJECT, ATOM_MOVE_TO_THRESHOLD, ATOM_FORK, ATOM_CORRUPTED } dap_chain_atom_verify_res_t; static const char* const dap_chain_atom_verify_res_str[] = { - [ATOM_ACCEPT] = "accepted", - [ATOM_PASS] = "skipped", - [ATOM_REJECT] = "rejected", - [ATOM_MOVE_TO_THRESHOLD] = "thresholded", - [ATOM_FORK] = "forked" + [ATOM_ACCEPT] = "accepted", + [ATOM_PASS] = "skipped", + [ATOM_REJECT] = "rejected", + [ATOM_MOVE_TO_THRESHOLD]= "thresholded", + [ATOM_FORK] = "forked", + [ATOM_CORRUPTED] = "corrupted" }; typedef enum dap_chain_iter_op { diff --git a/modules/chain/include/dap_chain_cell.h b/modules/chain/include/dap_chain_cell.h index db47d0150a..6ed59c9ca3 100644 --- a/modules/chain/include/dap_chain_cell.h +++ b/modules/chain/include/dap_chain_cell.h @@ -29,6 +29,11 @@ #include "dap_chain.h" #include "dap_chain_common.h" +typedef struct dap_chain_cell_mmap_data { + off_t vol_size; + char *map, *map_pos, **maps; +} dap_chain_cell_mmap_data_t; + typedef struct dap_chain_cell { dap_chain_cell_id_t id; dap_chain_t * chain; @@ -76,14 +81,23 @@ 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_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_and_free_file(dap_chain_t *a_chain); -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); -ssize_t dap_chain_cell_file_append(dap_chain_cell_t *a_cell,const void *a_atom, size_t a_atom_size); -DAP_STATIC_INLINE ssize_t dap_chain_cell_file_update(dap_chain_cell_t *a_cell) { - return dap_chain_cell_file_append(a_cell, NULL, 0); +int dap_chain_cell_open(dap_chain_t *a_chain, const char *a_filename, const char a_mode); + +DAP_INLINE 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 *l_cell = NULL; + HASH_FIND(hh, a_chain->cells, &a_cell_id, sizeof(dap_chain_cell_id_t), l_cell); + return l_cell; +} +DAP_INLINE dap_chain_cell_t *dap_chain_cell_capture_by_id(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id) { + pthread_rwlock_rdlock(&a_chain->cell_rwlock); + return dap_chain_cell_find_by_id(a_chain, a_cell_id); } +DAP_INLINE void dap_chain_cell_remit(const dap_chain_cell_t *a_cell) { + pthread_rwlock_unlock(&a_cell->chain->cell_rwlock); +} + +void dap_chain_cell_close(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id); +void dap_chain_cell_close_all(dap_chain_t *a_chain); +ssize_t dap_chain_cell_file_append(dap_chain_cell_t *a_cell, const void *a_atom, size_t a_atom_size); +#define dap_chain_cell_file_update(a_cell) dap_chain_cell_file_append(a_cell, NULL, 0); + diff --git a/modules/chain/include/dap_chain_common.h b/modules/chain/include/dap_chain_common.h index 5de3ac83a0..74706f6d1b 100644 --- a/modules/chain/include/dap_chain_common.h +++ b/modules/chain/include/dap_chain_common.h @@ -80,14 +80,14 @@ typedef union dap_chain_node_role{ DAP_STATIC_INLINE const char *dap_chain_node_role_to_str(dap_chain_node_role_t a_node_role) { switch (a_node_role.enums) { - case NODE_ROLE_ROOT_MASTER: return "NODE_ROLE_ROOT_MASTER"; - case NODE_ROLE_ROOT: return "NODE_ROLE_ROOT"; - case NODE_ROLE_ARCHIVE: return "NODE_ROLE_ARCHIVE"; - case NODE_ROLE_CELL_MASTER: return "NODE_ROLE_CELL_MASTER"; - case NODE_ROLE_MASTER: return "NODE_ROLE_MASTER"; - case NODE_ROLE_FULL: return "NODE_ROLE_FULL"; - case NODE_ROLE_LIGHT: return "NODE_ROLE_LIGHT"; - default: return "UNDEFINED"; + case NODE_ROLE_ROOT_MASTER: return "root master"; + case NODE_ROLE_ROOT: return "root"; + case NODE_ROLE_ARCHIVE: return "archive"; + case NODE_ROLE_CELL_MASTER: return "cell master"; + case NODE_ROLE_MASTER: return "master"; + case NODE_ROLE_FULL: return "full"; + case NODE_ROLE_LIGHT: return "liht"; + default: return "none"; } } 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 a5e6e8cf31..68677baf8d 100644 --- a/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c +++ b/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c @@ -687,35 +687,33 @@ static int s_callback_created(dap_chain_t * a_chain, dap_config_t *a_chain_net_c dap_chain_cs_dag_t * l_dag = DAP_CHAIN_CS_DAG ( a_chain ); dap_chain_cs_dag_poa_t * l_poa = DAP_CHAIN_CS_DAG_POA( l_dag ); - const char * l_events_sign_cert = NULL; - if ( ( l_events_sign_cert = dap_config_get_item_str(a_chain_net_cfg,"dag-poa","events-sign-cert") ) != NULL ) { - if ( ( PVT(l_poa)->events_sign_cert = dap_cert_find_by_name(l_events_sign_cert)) == NULL ){ - log_it(L_ERROR,"Can't load events sign certificate, name \"%s\" is wrong",l_events_sign_cert); - }else - log_it(L_NOTICE,"Loaded \"%s\" certificate to sign poa event", l_events_sign_cert); - + const char *l_events_sign_cert = = dap_config_get_item_str(a_chain_net_cfg,"dag-poa","events-sign-cert"); + if ( l_events_sign_cert ) { + if (!( PVT(l_poa)->events_sign_cert = dap_cert_find_by_name(l_events_sign_cert) )) + log_it(L_ERROR,"Can't load events sign certificate, name \"%s\" is wrong", l_events_sign_cert); + else + log_it(L_NOTICE, "Loaded \"%s\" certificate to sign poa events", l_events_sign_cert); } + dap_chain_net_t *l_net = dap_chain_net_by_name(a_chain->net_name); assert(l_net); dap_global_db_cluster_t *l_dag_cluster = dap_global_db_cluster_add(dap_global_db_instance_get_default(), NULL, dap_guuid_compose(l_net->pub.id.uint64, DAP_CHAIN_CLUSTER_ID_DAG), l_dag->gdb_group_events_round_new, DAG_ROUND_NEW_TTL, true, DAP_GDB_MEMBER_ROLE_NOBODY, DAP_CLUSTER_TYPE_AUTONOMIC); - if (!l_dag_cluster) { - log_it(L_ERROR, "Can't create cluster for consensus communication. Can't start the DAG consensus"); - return -1; - } + dap_return_val_if_fail_err(l_dag_cluster, -1, "Can't create cluster for consensus communication. Can't start the DAG consensus"); + dap_global_db_cluster_add_notify_callback(l_dag_cluster, s_round_changes_notify, l_dag); dap_chain_net_add_auth_nodes_to_cluster(l_net, l_dag_cluster); dap_link_manager_add_net_associate(l_net->pub.id.uint64, l_dag_cluster->links_cluster); PVT(l_poa)->mempool_timer = dap_interval_timer_create(15000, s_timer_process_callback, a_chain); switch ( dap_chain_net_get_role(l_net).enums ) { - case NODE_ROLE_ROOT_MASTER: - case NODE_ROLE_ROOT: - dap_global_db_get_all(l_dag->gdb_group_events_round_new, 0, s_callback_sync_all_on_start, l_dag); - default: - break; + case NODE_ROLE_ROOT_MASTER: + case NODE_ROLE_ROOT: + dap_global_db_get_all(l_dag->gdb_group_events_round_new, 0, s_callback_sync_all_on_start, l_dag); + default: + break; } return 0; } diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c index 93d253d1e5..7406a88203 100644 --- a/modules/net/dap_chain_net.c +++ b/modules/net/dap_chain_net.c @@ -1839,7 +1839,8 @@ static int s_chains_init_all(dap_chain_net_t *a_net, const char *a_path, int *a_ dap_config_t *l_chain_config, *l_all_chain_configs = NULL, *l_tmp_cfg; char l_chain_cfg_path[MAX_PATH + 1] = { '\0' }; int l_pos = snprintf(l_chain_cfg_path, MAX_PATH, "network/%s/", a_net->pub.name); - for ( struct dirent *l_dir_entry; ( l_dir_entry = readdir(l_chains_dir) ); ) { + struct dirent *l_dir_entry = NULL; + while (( l_dir_entry = readdir(l_chains_dir) )) { unsigned short l_len = strlen(l_dir_entry->d_name); if ( l_len > 4 && !dap_strncmp(l_dir_entry->d_name + l_len - 4, ".cfg", 4) ) { *(l_dir_entry->d_name + l_len - 4) = '\0'; @@ -1978,11 +1979,10 @@ int s_net_init(const char *a_net_name, const char *a_path, uint16_t a_acl_idx) char *l_service_cfg_path = dap_strdup_printf("network/%s/services/%s", l_net->pub.name, l_entry_name); dap_config_t *l_cfg_new = dap_config_open(l_service_cfg_path); if (l_cfg_new) { - char *l_service_name = DAP_DUP_SIZE((char *)l_entry_name, l_entry_len - 3); - l_service_name[l_entry_len - 4] = 0; + char l_service_name[l_entry_len - 3]; + dap_strncpy(l_service_name, l_entry_name, l_entry_len - 4); dap_chain_srv_start(l_net->pub.id, l_service_name, l_cfg_new); dap_config_close(l_cfg_new); - DAP_DELETE(l_service_name); } DAP_DELETE(l_service_cfg_path); } @@ -2015,24 +2015,16 @@ int s_net_init(const char *a_net_name, const char *a_path, uint16_t a_acl_idx) static void *s_net_load(void *a_arg) { dap_chain_net_t *l_net = a_arg; - int l_err_code = 0; - - if (!l_net->pub.config) { - log_it(L_ERROR,"Can't open default network config"); - l_err_code = -1; - goto ret; - } + dap_return_val_if_fail_err(l_net->pub.config, NULL, "Can't open network %s config", l_net->pub.name); dap_chain_net_pvt_t *l_net_pvt = PVT(l_net); - //else dap_chain_net_srv_stake_load_cache(l_net); // TODO rework ledger and staking caches - // load chains - dap_chain_t *l_chain = l_net->pub.chains; - clock_t l_chain_load_start_time = clock(); - while (l_chain) { + l_net_pvt->balancer_type = dap_config_get_item_bool_default(l_net->pub.config, "general", "use_dns_links", false); + char l_gdb_groups_mask[DAP_GLOBAL_DB_GROUP_NAME_SIZE_MAX]; + dap_chain_t *l_chain; + DL_FOREACH(l_net->pub.chains, l_chain) { l_net->pub.fee_value = uint256_0; l_net->pub.fee_addr = c_dap_chain_addr_blank; - if (!dap_chain_load_all(l_chain)) { - log_it (L_NOTICE, "Loaded chain files"); + if ( !dap_chain_load_all(l_chain) ) { if ( DAP_CHAIN_PVT(l_chain)->need_reorder ) // # unsafe crutch, need to escape reorder usage { log_it(L_DAP, "Reordering chain files for chain %s", l_chain->name); @@ -2053,117 +2045,76 @@ static void *s_net_load(void *a_arg) while (l_chain->callback_atom_add_from_treshold(l_chain, NULL)) log_it(L_DEBUG, "Added atom from treshold"); } - } else { - //dap_chain_save_all( l_chain ); - log_it (L_NOTICE, "Initialized chain files"); } l_chain->atom_num_last = 0; - time_t l_chain_load_time_taken = clock() - l_chain_load_start_time; - double time_taken = ((double)l_chain_load_time_taken)/CLOCKS_PER_SEC; // in seconds - log_it(L_NOTICE, "[%s] Chain [%s] processing took %f seconds", l_chain->net_name, l_chain->name, time_taken); - l_chain = l_chain->next; - } - dap_ledger_load_end(l_net->pub.ledger); - - // Do specific role actions post-chain created - l_net_pvt->state_target = NET_STATE_OFFLINE; - switch ( l_net_pvt->node_role.enums ) { - 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; - log_it(L_INFO,"Root master node role established"); - } // Master root includes root - case NODE_ROLE_ROOT:{ - // Set to process only zerochain - dap_chain_id_t l_chain_id = {{0}}; - dap_chain_t *l_chain = dap_chain_find_by_id(l_net->pub.id, l_chain_id); - if (l_chain) - l_chain->is_datum_pool_proc = true; - log_it(L_INFO,"Root node role established"); - } break; + switch ( l_net_pvt->node_role.enums ) { + case NODE_ROLE_ROOT_MASTER: + /* Processes everything in mempool*/ + l_chain->is_datum_pool_proc = true; + break; + case NODE_ROLE_ROOT: + /* Processes zerochain only */ + l_chain->is_datum_pool_proc = !l_chain->id.uint64; + break; case NODE_ROLE_CELL_MASTER: - case NODE_ROLE_MASTER:{ - uint16_t l_proc_chains_count=0; - const char **l_proc_chains = dap_config_get_array_str(l_net->pub.config, "role-master", "proc_chains", &l_proc_chains_count); - for (size_t i = 0; i< l_proc_chains_count ; i++) { - dap_chain_id_t l_chain_id = {}; - if (dap_chain_id_parse(l_proc_chains[i], &l_chain_id) == 0) { - dap_chain_t *l_chain = dap_chain_find_by_id(l_net->pub.id, l_chain_id ); - if (l_chain) - l_chain->is_datum_pool_proc = true; - else - log_it(L_WARNING, "Can't find chain id 0x%016" DAP_UINT64_FORMAT_X, l_chain_id.uint64); - } - } - log_it(L_INFO,"Master node role established"); - } break; - case NODE_ROLE_FULL:{ - log_it(L_INFO,"Full node role established"); + case NODE_ROLE_MASTER: { + /* Processes specified chains only */ + uint16_t k = 0; + dap_chain_id_t l_chain_id; + const char **l_proc_chains = dap_config_get_array_str(l_net->pub.config, "role-master", "proc_chains", &k); + while (k--) + l_chain->is_datum_pool_proc = ( !dap_chain_id_parse(l_proc_chains[k], &l_chain_id) && (l_chain->id.uint64 == l_chain_id.uint64) ); } break; - case NODE_ROLE_LIGHT: - default: - log_it(L_INFO,"Light node role established"); - - } - - l_net_pvt->balancer_type = dap_config_get_item_bool_default(l_net->pub.config, "general", "use_dns_links", false); + default: break; - // Init GlobalDB clusters for mempool, service and nodes (with aliases) - char *l_gdb_groups_mask = NULL; - DL_FOREACH(l_net->pub.chains, l_chain) { // Personal chain mempool cluster for each chain - l_gdb_groups_mask = dap_strdup_printf("%s.chain-%s.mempool", l_net->pub.gdb_groups_prefix, l_chain->name); + snprintf(l_gdb_groups_mask, sizeof(l_gdb_groups_mask), "%s.chain-%s.mempool", + l_net->pub.gdb_groups_prefix, l_chain->name); dap_global_db_cluster_t *l_cluster = dap_global_db_cluster_add( dap_global_db_instance_get_default(), l_net->pub.name, dap_guuid_compose(l_net->pub.id.uint64, 0), l_gdb_groups_mask, dap_config_get_item_int32_default(l_net->pub.config, "global_db", "mempool_ttl", DAP_CHAIN_NET_MEMPOOL_TTL), true, DAP_GDB_MEMBER_ROLE_USER, DAP_CLUSTER_TYPE_EMBEDDED); - if (!l_cluster) { - log_it(L_ERROR, "Can't initialize mempool cluster for network %s", l_net->pub.name); - l_err_code = -2; - goto ret; - } + dap_return_val_if_fail_err(l_cluster, NULL, "Net \"%s\" loading error %d: can't initialize mempool cluster", + l_net->pub.name, -2); dap_chain_net_add_auth_nodes_to_cluster(l_net, l_cluster); - DAP_DELETE(l_gdb_groups_mask); if (l_net->pub.chains == l_chain) // Pointer for first mempool cluster in global double-linked list of clusters l_net_pvt->mempool_clusters = l_cluster; } + dap_ledger_load_end(l_net->pub.ledger); + log_it(L_INFO, "Node role \"%s\" established in net %s", dap_chain_node_role_to_str(l_net_pvt->node_role.enums), l_net->pub.name); + l_net_pvt->state_target = NET_STATE_OFFLINE; + + // Init GlobalDB clusters for service and nodes (with aliases) // Service orders cluster - l_gdb_groups_mask = dap_strdup_printf("%s.service.orders", l_net->pub.gdb_groups_prefix); + snprintf(l_gdb_groups_mask, sizeof(l_gdb_groups_mask), "%s.service.orders", l_net->pub.gdb_groups_prefix); l_net_pvt->orders_cluster = dap_global_db_cluster_add(dap_global_db_instance_get_default(), l_net->pub.name, dap_guuid_compose(l_net->pub.id.uint64, 0), l_gdb_groups_mask, 0, true, DAP_GDB_MEMBER_ROLE_GUEST, DAP_CLUSTER_TYPE_EMBEDDED); - if (!l_net_pvt->orders_cluster) { - log_it(L_ERROR, "Can't initialize orders cluster for network %s", l_net->pub.name); - goto ret; - } + dap_return_val_if_fail_err(l_net_pvt->orders_cluster, NULL, "Net \"%s\" loading error %d: can't initialize orders cluster", + l_net->pub.name, -3); dap_chain_net_add_auth_nodes_to_cluster(l_net, l_net_pvt->orders_cluster); - DAP_DELETE(l_gdb_groups_mask); // Common orders cluster - l_gdb_groups_mask = dap_strdup_printf("%s.orders", l_net->pub.gdb_groups_prefix); + snprintf(l_gdb_groups_mask, sizeof(l_gdb_groups_mask), "%s.orders", l_net->pub.gdb_groups_prefix); l_net_pvt->common_orders = dap_global_db_cluster_add(dap_global_db_instance_get_default(), l_net->pub.name, dap_guuid_compose(l_net->pub.id.uint64, 0), l_gdb_groups_mask, 0, true, DAP_GDB_MEMBER_ROLE_USER, DAP_CLUSTER_TYPE_EMBEDDED); - if (!l_net_pvt->common_orders) { - log_it(L_ERROR, "Can't initialize orders cluster for network %s", l_net->pub.name); - goto ret; - } + dap_return_val_if_fail_err(l_net_pvt->common_orders, NULL, "Net \"%s\" loading error %d: can't initialize common orders cluster" + l_net->pub.name, -4); dap_chain_net_add_auth_nodes_to_cluster(l_net, l_net_pvt->common_orders); - DAP_DELETE(l_gdb_groups_mask); // Node states cluster - l_gdb_groups_mask = dap_strdup_printf("%s.nodes.states", l_net->pub.gdb_groups_prefix); + snprintf(l_gdb_groups_mask, sizeof(l_gdb_groups_mask), "%s.nodes.states", l_net->pub.gdb_groups_prefix); l_net_pvt->nodes_states = dap_global_db_cluster_add(dap_global_db_instance_get_default(), l_net->pub.name, dap_guuid_compose(l_net->pub.id.uint64, 0), l_gdb_groups_mask, DAP_CHAIN_NET_NODES_TTL, true, DAP_GDB_MEMBER_ROLE_USER, DAP_CLUSTER_TYPE_EMBEDDED); - DAP_DELETE(l_gdb_groups_mask); + dap_return_val_if_fail_err(l_net_pvt->nodes_states, NULL, "Net \"%s\" loading error %d: can't initialize node states cluster" + l_net->pub.name, -5); // Nodes and its aliases cluster snprintf(l_net->pub.gdb_nodes, sizeof(l_net->pub.gdb_nodes), "%s.%s", l_net->pub.gdb_groups_prefix, s_gdb_nodes_postfix); l_net_pvt->nodes_cluster = dap_global_db_cluster_add(dap_global_db_instance_get_default(), @@ -2171,19 +2122,14 @@ static void *s_net_load(void *a_arg) l_net->pub.gdb_nodes, 7200, true, DAP_GDB_MEMBER_ROLE_GUEST, DAP_CLUSTER_TYPE_EMBEDDED); - if (!l_net_pvt->nodes_cluster) { - log_it(L_ERROR, "Can't initialize nodes cluster for network %s", l_net->pub.name); - l_err_code = -3; - goto ret; - } + dap_return_val_if_fail_err(l_net_pvt->nodes_cluster, NULL, "Net \"%s\" loading error %d: can't initialize nodes cluster" + l_net->pub.name, -6); dap_chain_net_add_auth_nodes_to_cluster(l_net, l_net_pvt->nodes_cluster); dap_chain_net_add_nodelist_notify_callback(l_net, s_nodelist_change_notify, l_net); - if (dap_link_manager_add_net(l_net->pub.id.uint64, l_net_pvt->nodes_cluster->links_cluster, - dap_config_get_item_uint16_default(l_net->pub.config, - "general", "links_required", 3))) { + if ( dap_link_manager_add_net(l_net->pub.id.uint64, l_net_pvt->nodes_cluster->links_cluster, + dap_config_get_item_uint16_default(l_net->pub.config, "general", "links_required", 3)) ) log_it(L_WARNING, "Can't add net %s to link manager", l_net->pub.name); - } DL_FOREACH(l_net->pub.chains, l_chain) dap_chain_cs_load(l_chain, l_net->pub.config); @@ -2215,12 +2161,9 @@ static void *s_net_load(void *a_arg) l_net_pvt->sync_context.sync_idle_time = dap_config_get_item_uint32_default(g_config, "chain", "sync_idle_time", 60); dap_proc_thread_timer_add(NULL, s_sync_timer_callback, l_net, c_sync_timer_period); - log_it(L_INFO, "Chain network \"%s\" initialized", l_net->pub.name); + log_it(L_INFO, "Network \"%s\" initialized", l_net->pub.name); l_net_pvt->state = NET_STATE_OFFLINE; -ret: - if (l_err_code) - log_it(L_ERROR, "Loading chains of net %s finished with (%d) error code.", l_net->pub.name, l_err_code); - return NULL; + return l_net; } dap_global_db_cluster_t *dap_chain_net_get_mempool_cluster(dap_chain_t *a_chain) diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c index 19609ca5cb..8c67acdacd 100644 --- a/modules/type/blocks/dap_chain_cs_blocks.c +++ b/modules/type/blocks/dap_chain_cs_blocks.c @@ -279,11 +279,7 @@ void dap_chain_cs_blocks_deinit() static int s_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_CRITICAL, "%s", c_error_memory_alloc); - return -1; - } + dap_chain_cs_blocks_t * l_cs_blocks = DAP_NEW_Z_RET_VAL_IF_FAIL(dap_chain_cs_blocks_t, -1); a_chain->_inheritor = l_cs_blocks; l_cs_blocks->chain = a_chain; @@ -1506,7 +1502,7 @@ static int s_callback_cs_blocks_purge(dap_chain_t *a_chain) l_datum_index = NULL; } pthread_rwlock_unlock(&PVT(l_blocks)->datums_rwlock); - dap_chain_cell_delete_all(a_chain); + dap_chain_cell_close_all(a_chain); return 0; } @@ -1564,8 +1560,9 @@ static int s_add_atom_datums(dap_chain_cs_blocks_t *a_blocks, dap_chain_block_ca pthread_rwlock_wrlock(&PVT(a_blocks)->datums_rwlock); HASH_ADD(hh, PVT(a_blocks)->datum_index, datum_hash, sizeof(*l_datum_hash), l_datum_index); pthread_rwlock_unlock(&PVT(a_blocks)->datums_rwlock); - dap_chain_cell_t *l_cell = dap_chain_cell_find_by_id(a_blocks->chain, a_blocks->chain->active_cell_id); + dap_chain_cell_t *l_cell = dap_chain_cell_capture_by_id(a_blocks->chain, a_blocks->chain->active_cell_id); dap_chain_datum_notify(l_cell, l_datum_hash, &l_datum_index->block_cache->block_hash, (byte_t *)l_datum, l_datum_size, l_res, l_datum_index_data.action, l_datum_index_data.uid); + dap_chain_cell_remit(l_cell); } } debug_if(s_debug_more, L_DEBUG, "Block %s checked, %s", a_block_cache->block_hash_str, @@ -1598,8 +1595,9 @@ static int s_delete_atom_datums(dap_chain_cs_blocks_t *a_blocks, dap_chain_block l_ret++; HASH_DEL(PVT(a_blocks)->datum_index, l_datum_index); // notify datum removed - dap_chain_cell_t *l_cell = dap_chain_cell_find_by_id(a_blocks->chain, a_blocks->chain->active_cell_id); + dap_chain_cell_t *l_cell = dap_chain_cell_capture_by_id(a_blocks->chain, a_blocks->chain->active_cell_id); dap_chain_datum_removed_notify(l_cell, l_datum_hash); + dap_chain_cell_remit(l_cell); } } debug_if(s_debug_more, L_DEBUG, "Block %s checked, %s", a_block_cache->block_hash_str, @@ -1720,7 +1718,7 @@ static dap_chain_atom_verify_res_t s_callback_atom_add(dap_chain_t * a_chain, da case ATOM_ACCEPT:{ dap_chain_net_t *l_net = dap_chain_net_by_id(a_chain->net_id); assert(l_net); - dap_chain_cell_t *l_cell = dap_chain_cell_find_by_id(a_chain, l_block->hdr.cell_id); + dap_chain_cell_t *l_cell = dap_chain_cell_capture_by_id(a_chain, l_block->hdr.cell_id); #ifndef DAP_CHAIN_BLOCKS_TEST if ( !dap_chain_net_get_load_mode(l_net) ) { if ( (ret = dap_chain_atom_save(l_cell, a_atom, a_atom_size, a_atom_new ? &l_block_hash : NULL)) < 0 ) { @@ -1843,9 +1841,9 @@ static dap_chain_atom_verify_res_t s_callback_atom_add(dap_chain_t * a_chain, da debug_if(s_debug_more, L_DEBUG, "Verified atom %p with hash %s: REJECTED", a_atom, dap_chain_hash_fast_to_str_static(&l_block_hash)); break; case ATOM_FORK:{ - dap_chain_cell_t *l_cell = dap_chain_cell_find_by_id(a_chain, l_block->hdr.cell_id); #ifndef DAP_CHAIN_BLOCKS_TEST if ( !dap_chain_net_get_load_mode( dap_chain_net_by_id(a_chain->net_id)) ) { + dap_chain_cell_t *l_cell = dap_chain_cell_capture_by_id(a_chain, l_block->hdr.cell_id); if ( (ret = dap_chain_atom_save(l_cell, a_atom, a_atom_size, a_atom_new ? &l_block_hash : NULL)) < 0 ) { log_it(L_ERROR, "Can't save atom to file, code %d", ret); return ATOM_REJECT; @@ -1853,6 +1851,7 @@ static dap_chain_atom_verify_res_t s_callback_atom_add(dap_chain_t * a_chain, da l_block = (dap_chain_block_t*)( l_cell->map_pos += sizeof(uint64_t) ); // Switching to mapped area l_cell->map_pos += a_atom_size; } + dap_chain_cell_remit(l_cell); ret = ATOM_FORK; } #endif diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c index bef0bb74de..431f3f0b90 100644 --- a/modules/type/dag/dap_chain_cs_dag.c +++ b/modules/type/dag/dap_chain_cs_dag.c @@ -372,7 +372,7 @@ static int s_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_delete_all(a_chain); + dap_chain_cell_close_all(a_chain); return 0; } -- GitLab From 83bc572bd90e5ed0e706184ef075554cfa105206 Mon Sep 17 00:00:00 2001 From: "P. Constantin" <papizh.konstantin@demlabs.net> Date: Thu, 6 Feb 2025 21:45:46 +0700 Subject: [PATCH 05/11] ... --- dap-sdk | 2 +- modules/chain/dap_chain.c | 49 +++++----- modules/chain/dap_chain_cell.c | 130 +++++++------------------ modules/chain/include/dap_chain.h | 8 +- modules/chain/include/dap_chain_cell.h | 3 +- 5 files changed, 65 insertions(+), 127 deletions(-) diff --git a/dap-sdk b/dap-sdk index b6ead51e41..e4ffa996e2 160000 --- a/dap-sdk +++ b/dap-sdk @@ -1 +1 @@ -Subproject commit b6ead51e413671d2416f98796b8ac7d397e2e0ed +Subproject commit e4ffa996e2df6a6f454ba8110bc49b8f1c533741 diff --git a/modules/chain/dap_chain.c b/modules/chain/dap_chain.c index 4084a05703..6070d8e8c6 100644 --- a/modules/chain/dap_chain.c +++ b/modules/chain/dap_chain.c @@ -821,17 +821,16 @@ static bool s_notify_datum_removed_on_thread(void *a_arg) return false; } -ssize_t dap_chain_atom_save(dap_chain_cell_t *a_chain_cell, const uint8_t *a_atom, size_t a_atom_size, dap_hash_fast_t *a_new_atom_hash) +ssize_t dap_chain_atom_save(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id, + const uint8_t *a_atom, size_t a_atom_size, + dap_hash_fast_t *a_new_atom_hash, char **a_atom_map) { - dap_return_val_if_fail(a_chain_cell && a_chain_cell->chain, -1); - dap_chain_t *l_chain = a_chain_cell->chain; - if (a_new_atom_hash) { // Atom is new and need to be distributed for the net - dap_cluster_t *l_net_cluster = dap_cluster_find(dap_guuid_compose(l_chain->net_id.uint64, 0)); + dap_cluster_t *l_net_cluster = dap_cluster_find(dap_guuid_compose(a_chain->net_id.uint64, 0)); if (l_net_cluster) { size_t l_pkt_size = a_atom_size + sizeof(dap_chain_ch_pkt_t); - dap_chain_ch_pkt_t *l_pkt = dap_chain_ch_pkt_new(l_chain->net_id, l_chain->id, - a_chain_cell->id, a_atom, a_atom_size, + dap_chain_ch_pkt_t *l_pkt = dap_chain_ch_pkt_new(a_chain->net_id, a_chain->id, + a_cell_id, a_atom, a_atom_size, DAP_CHAIN_CH_PKT_VERSION_CURRENT); if (l_pkt) { dap_gossip_msg_issue(l_net_cluster, DAP_CHAIN_CH_ID, l_pkt, l_pkt_size, a_new_atom_hash); @@ -839,7 +838,7 @@ ssize_t dap_chain_atom_save(dap_chain_cell_t *a_chain_cell, const uint8_t *a_ato } } } - return dap_chain_cell_file_append(a_chain_cell, a_atom, a_atom_size); + return dap_chain_cell_file_append(a_chain, a_cell_id, a_atom, a_atom_size, a_atom_map); } /** @@ -882,47 +881,43 @@ const char* dap_chain_get_path(dap_chain_t *a_chain) return DAP_CHAIN_PVT(a_chain)->file_storage_dir; } -void dap_chain_atom_notify(dap_chain_cell_t *a_chain_cell, dap_hash_fast_t *a_hash, const uint8_t *a_atom, size_t a_atom_size) { +void dap_chain_atom_notify(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id, dap_hash_fast_t *a_hash, const uint8_t *a_atom, size_t a_atom_size) { #ifdef DAP_CHAIN_BLOCKS_TEST return; #endif - if ( !a_chain_cell->chain->atom_notifiers ) + if ( !a_chain->atom_notifiers ) return; dap_list_t *l_iter; - DL_FOREACH(a_chain_cell->chain->atom_notifiers, l_iter) { + DL_FOREACH(a_chain->atom_notifiers, l_iter) { dap_chain_atom_notifier_t *l_notifier = (dap_chain_atom_notifier_t*)l_iter->data; - struct chain_thread_notifier *l_arg = DAP_NEW_Z(struct chain_thread_notifier); - if (!l_arg) { - log_it(L_CRITICAL, "%s", c_error_memory_alloc); - continue; - } + struct chain_thread_notifier *l_arg = DAP_NEW_Z_RET_IF_FAIL(struct chain_thread_notifier); *l_arg = (struct chain_thread_notifier) { .callback = l_notifier->callback, .callback_arg = l_notifier->arg, - .chain = a_chain_cell->chain, .cell_id = a_chain_cell->id, + .chain = a_chain, .cell_id = a_cell_id, .hash = *a_hash, - .atom = a_chain_cell->chain->is_mapped ? (byte_t*)a_atom : DAP_DUP_SIZE((byte_t*)a_atom, a_atom_size), + .atom = a_chain->is_mapped ? (byte_t*)a_atom : DAP_DUP_SIZE((byte_t*)a_atom, a_atom_size), .atom_size = a_atom_size }; dap_proc_thread_callback_add_pri(l_notifier->proc_thread, s_notify_atom_on_thread, l_arg, DAP_QUEUE_MSG_PRIORITY_LOW); } } -void dap_chain_datum_notify(dap_chain_cell_t *a_chain_cell, dap_hash_fast_t *a_hash, dap_hash_fast_t *a_atom_hash, const uint8_t *a_datum, size_t a_datum_size, int a_ret_code, uint32_t a_action, dap_chain_srv_uid_t a_uid) { +void dap_chain_datum_notify(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id, dap_hash_fast_t *a_hash, dap_hash_fast_t *a_atom_hash, const uint8_t *a_datum, size_t a_datum_size, int a_ret_code, uint32_t a_action, dap_chain_srv_uid_t a_uid) { #ifdef DAP_CHAIN_BLOCKS_TEST return; #endif - if ( !a_chain_cell->chain->datum_notifiers ) + if ( !a_chain->datum_notifiers ) return; dap_list_t *l_iter; - DL_FOREACH(a_chain_cell->chain->datum_notifiers, l_iter) { + DL_FOREACH(a_chain->datum_notifiers, l_iter) { dap_chain_datum_notifier_t *l_notifier = (dap_chain_datum_notifier_t*)l_iter->data; struct chain_thread_datum_notifier *l_arg = DAP_NEW_Z_RET_IF_FAIL(struct chain_thread_datum_notifier); *l_arg = (struct chain_thread_datum_notifier) { .callback = l_notifier->callback, .callback_arg = l_notifier->arg, - .chain = a_chain_cell->chain, .cell_id = a_chain_cell->id, + .chain = a_chain, .cell_id = a_cell_id, .hash = *a_hash, - .datum = a_chain_cell->chain->is_mapped ? (byte_t*)a_datum : DAP_DUP_SIZE((byte_t*)a_datum, a_datum_size), + .datum = a_chain->is_mapped ? (byte_t*)a_datum : DAP_DUP_SIZE((byte_t*)a_datum, a_datum_size), .datum_size = a_datum_size, .ret_code = a_ret_code, .action = a_action, @@ -931,15 +926,15 @@ void dap_chain_datum_notify(dap_chain_cell_t *a_chain_cell, dap_hash_fast_t *a_ } } -void dap_chain_datum_removed_notify(dap_chain_cell_t *a_chain_cell, dap_hash_fast_t *a_hash) { +void dap_chain_datum_removed_notify(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id, dap_hash_fast_t *a_hash) { #ifdef DAP_CHAIN_BLOCKS_TEST return; #endif - if ( !a_chain_cell->chain->datum_removed_notifiers ) + if ( !a_chain->datum_removed_notifiers ) return; dap_list_t *l_iter; - DL_FOREACH(a_chain_cell->chain->datum_removed_notifiers, l_iter) { + DL_FOREACH(a_chain->datum_removed_notifiers, l_iter) { dap_chain_datum_removed_notifier_t *l_notifier = (dap_chain_datum_removed_notifier_t*)l_iter->data; struct chain_thread_datum_removed_notifier *l_arg = DAP_NEW_Z(struct chain_thread_datum_removed_notifier); if (!l_arg) { @@ -948,7 +943,7 @@ void dap_chain_datum_removed_notify(dap_chain_cell_t *a_chain_cell, dap_hash_fa } *l_arg = (struct chain_thread_datum_removed_notifier) { .callback = l_notifier->callback, .callback_arg = l_notifier->arg, - .chain = a_chain_cell->chain, .cell_id = a_chain_cell->id, + .chain = a_chain, .cell_id = a_cell_id, .hash = *a_hash}; dap_proc_thread_callback_add_pri(l_notifier->proc_thread, s_notify_datum_removed_on_thread, l_arg, DAP_QUEUE_MSG_PRIORITY_LOW); } diff --git a/modules/chain/dap_chain_cell.c b/modules/chain/dap_chain_cell.c index cf26c6514d..f7b8580bfd 100644 --- a/modules/chain/dap_chain_cell.c +++ b/modules/chain/dap_chain_cell.c @@ -611,10 +611,8 @@ int dap_chain_cell_open(dap_chain_t *a_chain, const char *a_filename, const char #undef m_ret_err } -static int s_cell_file_atom_add(dap_chain_cell_t *a_cell, dap_chain_atom_ptr_t a_atom, uint64_t a_atom_size) +static int s_cell_file_atom_add(dap_chain_cell_t *a_cell, dap_chain_atom_ptr_t a_atom, uint64_t a_atom_size, char **a_atom_map) { - dap_return_val_if_fail(a_atom && a_atom_size, -1); - if (a_cell->chain->is_mapped) { off_t l_pos = !fseeko(a_cell->file_storage, 0, SEEK_END) ? ftello(a_cell->file_storage) : -1; dap_return_val_if_pass_err(l_pos < 0, -1, "Can't get \"%s : %s\" cell 0x%016"DAP_UINT64_FORMAT_X" size, error %d", @@ -635,24 +633,40 @@ static int s_cell_file_atom_add(dap_chain_cell_t *a_cell, dap_chain_atom_ptr_t a dap_return_val_if_fail_err( fwrite(&a_atom_size, sizeof(a_atom_size), 1, a_cell->file_storage) == 1 && fwrite(a_atom, a_atom_size, 1, a_cell->file_storage) == 1, - -3, "Can't write atom (%zu b) to \"%s : %s\" cell 0x%016"DAP_UINT64_FORMAT_X", error %d: \"%s\"", + -3, "Can't write atom [%zu b] to \"%s : %s\" cell 0x%016"DAP_UINT64_FORMAT_X", error %d: \"%s\"", a_atom_size, a_cell->chain->net_name, a_cell->chain->name, a_cell->id, errno, dap_strerror(errno) ); debug_if (s_debug_more && a_cell->chain->is_mapped, L_DEBUG, "After writing an atom of size %lu, stream pos of %s is %lu and map shift is %lu", a_atom_size, a_cell->file_storage_path, ftello(a_cell->file_storage), (size_t)(a_cell->map_pos - a_cell->map)); -#ifdef DAP_OS_DARWIN fflush(a_cell->file_storage); + if (a_cell->chain->is_mapped) { +#ifdef DAP_OS_DARWIN if ( MAP_FAILED == (a_cell->map = mmap(a_cell->map, dap_page_roundup(DAP_MAPPED_VOLUME_LIMIT), PROT_READ, MAP_PRIVATE|MAP_FIXED, fileno(a_cell->file_storage), a_cell->cur_vol_start)) ) { log_it(L_ERROR, "Chain cell \"%s\" 0x%016"DAP_UINT64_FORMAT_X" cannot be remapped, errno %d", a_cell->file_storage_path, a_cell->id.uint64, errno); return -2; } - } +#elif defined DAP_OS_WINDOWS + off_t l_off = ftello(a_cell->file_storage); + LARGE_INTEGER SectionSize = (LARGE_INTEGER) { .QuadPart = l_off }; + HANDLE hSection = (HANDLE)a_cell->map_range_bounds->data; + NTSTATUS err = pfnNtExtendSection(hSection, &SectionSize); + if ( !NT_SUCCESS(err) ) { + log_it(L_ERROR, "NtExtendSection() failed, status %lx: \"%s\"", + err, dap_str_ntstatus(err) ); + return -2; + } #endif + /* Pass ptr to mapped area */ + if (a_atom_map) { + *a_atom_map = a_cell->map_pos += sizeof(uint64_t); + a_cell->map_pos += a_atom_size; + } + } return 0; } @@ -668,93 +682,21 @@ static int s_cell_file_atom_add(dap_chain_cell_t *a_cell, dap_chain_atom_ptr_t a * @param a_atom_size * @return */ -ssize_t 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_t *a_chain, dap_chain_cell_id_t a_cell_id, const void *a_atom, size_t a_atom_size, char **a_atom_map) { - dap_return_val_if_fail(a_cell, -1); - dap_return_val_if_pass_err(!a_atom && !a_cell->chain, -2, "Chain not found for cell 0x%016"DAP_UINT64_FORMAT_X" %s ", - a_cell->id.uint64, a_cell->file_storage_path); - size_t l_size = 0, l_count = 0; - int l_err = -1; - pthread_rwlock_wrlock(&a_cell->storage_rwlock); - if ( a_atom && a_atom_size ) { - //pthread_rwlock_wrlock(a_cell->chain->cell_rwlock); - debug_if (s_debug_more && a_cell->chain->is_mapped, L_DEBUG, "Before appending an atom of size %lu, stream pos of %s is %lu, map pos is %lu", - a_atom_size, a_cell->file_storage_path, ftello(a_cell->file_storage), - (size_t)(a_cell->map_pos - a_cell->map)); - - if ( !s_cell_file_atom_add(a_cell, a_atom, a_atom_size) ) { - ++l_count; - l_size = a_atom_size + sizeof(uint64_t); - debug_if (s_debug_more && a_cell->chain->is_mapped, L_DEBUG,"After appending an atom of size %lu, stream pos of %s is %lu, map pos is %lu", - a_atom_size, a_cell->file_storage_path, ftello(a_cell->file_storage), - (size_t)(a_cell->map_end - a_cell->map_pos)); -#ifdef DAP_OS_WINDOWS - if (a_cell->chain->is_mapped) { - off_t l_off = ftello(a_cell->file_storage); - LARGE_INTEGER SectionSize = (LARGE_INTEGER) { .QuadPart = l_off }; - HANDLE hSection = (HANDLE)a_cell->map_range_bounds->data; - NTSTATUS err = pfnNtExtendSection(hSection, &SectionSize); - if ( !NT_SUCCESS(err) ) { - log_it(L_ERROR, "NtExtendSection() failed, status %lx: \"%s\"", - err, dap_str_ntstatus(err) ); - l_err = -2; - } - } -#endif - } - //pthread_rwlock_unlock(a_cell->chain->cell_rwlock); - } else { - if (a_cell->chain->is_mapped) { - log_it(L_ERROR, "Unable to rewrite memory-mapped chain"); - // TODO: do we actually need it besides zerochain reordering issue? - pthread_rwlock_unlock(&a_cell->storage_rwlock); - return -3; - } - const char *l_fname = dap_strdup_printf("%"DAP_UINT64_FORMAT_x "." CELL_FILE_EXT -#ifdef DAP_OS_WINDOWS - ".new" -#endif - , a_cell->id.uint64); - bool was_mapped = a_cell->chain->is_mapped; - a_cell->chain->is_mapped = false; - l_err = dap_chain_cell_open(a_cell->chain, l_fname, 'w'); - DAP_DELETE(l_fname); - if (l_err) { - log_it(L_ERROR, "Can't open chain \"%s : %s\" cell, code %d", a_cell->chain->net_name, a_cell->chain->name, l_err); - pthread_rwlock_unlock(&a_cell->storage_rwlock); - return -3; - } - l_size += sizeof(dap_chain_cell_file_header_t); - dap_chain_atom_iter_t *l_atom_iter = a_cell->chain->callback_atom_iter_create(a_cell->chain, a_cell->id, NULL); - dap_chain_atom_ptr_t l_atom; - uint64_t l_atom_size = 0; - //pthread_rwlock_wrlock(a_cell->chain->cell_rwlock); - for (l_atom = a_cell->chain->callback_atom_iter_get(l_atom_iter, DAP_CHAIN_ITER_OP_FIRST, &l_atom_size); - l_atom && l_atom_size && !( l_err = s_cell_file_atom_add(a_cell, l_atom, l_atom_size) ); - l_atom = a_cell->chain->callback_atom_iter_get(l_atom_iter, DAP_CHAIN_ITER_OP_NEXT, &l_atom_size)) - { - l_size += sizeof(uint64_t) + l_atom_size; - ++l_count; - } - a_cell->chain->callback_atom_iter_delete(l_atom_iter); - a_cell->chain->is_mapped = was_mapped; - debug_if (s_debug_more && a_cell->chain->is_mapped,L_DEBUG, "After rewriting file %s, stream pos is %lu and map pos is %lu", - a_cell->file_storage_path, ftello(a_cell->file_storage), - (size_t)(a_cell->map_pos - a_cell->map)); - //pthread_rwlock_unlock(a_cell->chain->cell_rwlock); - } - - if (l_size) { -#ifndef DAP_OS_DARWIN - fflush(a_cell->file_storage); -#endif - log_it(L_DEBUG, "Saved %zu atom%s (%zu bytes) to chain \"%s : %s\" cell 0x%016"DAP_UINT64_FORMAT_X"", - l_count, l_count > 1 ? "s" : "", l_size, a_cell->chain->net_name, a_cell->chain->name, a_cell->id.uint64); - debug_if(l_err, L_WARNING, "Not all data was saved due to writing error %d!", l_err); - } 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 l_size; + dap_return_val_if_fail(a_atom && a_atom_size && a_chain, -1); + dap_chain_cell_t *l_cell = dap_chain_cell_capture_by_id(a_chain, a_cell_id); + dap_return_val_if_fail_err(l_cell, -2, "Cell #%"DAP_UINT64_FORMAT_x" not found in chain \"%s : %s\"", + a_cell_id, a_chain->net_name, a_chain->name); + pthread_rwlock_wrlock(&l_cell->storage_rwlock); + int l_err = s_cell_file_atom_add(l_cell, a_atom, a_atom_size, a_atom_map); + if (l_err) + log_it(L_DEBUG, "Saved atom of size %zu bytes to chain \"%s : %s\", cell 0x%016"DAP_UINT64_FORMAT_X"", + a_atom_size, a_chain->net_name, a_chain->name, a_cell_id.uint64); + else + log_it(L_ERROR, "Noting saved to chain \"%s : %s\", cell 0x%016"DAP_UINT64_FORMAT_X", error %d", + a_chain->net_name, a_chain->name, a_cell_id.uint64, l_err); + pthread_rwlock_unlock(&l_cell->storage_rwlock); + dap_chain_cell_remit(l_cell); + return 0; } diff --git a/modules/chain/include/dap_chain.h b/modules/chain/include/dap_chain.h index 5d26c66bb3..767b46442b 100644 --- a/modules/chain/include/dap_chain.h +++ b/modules/chain/include/dap_chain.h @@ -313,9 +313,9 @@ void dap_chain_add_callback_notify(dap_chain_t *a_chain, dap_chain_callback_noti void dap_chain_add_callback_datum_index_notify(dap_chain_t *a_chain, dap_chain_callback_datum_notify_t a_callback, dap_proc_thread_t *a_thread, void *a_callback_arg); void dap_chain_add_callback_datum_removed_from_index_notify(dap_chain_t *a_chain, dap_chain_callback_datum_removed_notify_t a_callback, dap_proc_thread_t *a_thread, void *a_callback_arg); void dap_chain_atom_confirmed_notify_add(dap_chain_t *a_chain, dap_chain_callback_notify_t a_callback, void *a_arg, uint64_t a_conf_cnt); -void dap_chain_atom_notify(dap_chain_cell_t *a_chain_cell, dap_hash_fast_t *a_hash, const uint8_t *a_atom, size_t a_atom_size); -void dap_chain_datum_notify(dap_chain_cell_t *a_chain_cell, dap_hash_fast_t *a_hash, dap_chain_hash_fast_t *a_atom_hash, const uint8_t *a_datum, size_t a_datum_size, int a_ret_code, uint32_t a_action, dap_chain_srv_uid_t a_uid); -void dap_chain_datum_removed_notify(dap_chain_cell_t *a_chain_cell, dap_hash_fast_t *a_hash); +void dap_chain_atom_notify(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id, dap_hash_fast_t *a_hash, const uint8_t *a_atom, size_t a_atom_size); +void dap_chain_datum_notify(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id, dap_hash_fast_t *a_hash, dap_chain_hash_fast_t *a_atom_hash, const uint8_t *a_datum, size_t a_datum_size, int a_ret_code, uint32_t a_action, dap_chain_srv_uid_t a_uid); +void dap_chain_datum_removed_notify(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id, dap_hash_fast_t *a_hash); void dap_chain_atom_add_from_threshold(dap_chain_t *a_chain); dap_chain_atom_ptr_t dap_chain_get_atom_by_hash(dap_chain_t * a_chain, dap_chain_hash_fast_t * a_atom_hash, size_t * a_atom_size); bool dap_chain_get_atom_last_hash_num_ts(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id, dap_hash_fast_t *a_atom_hash, uint64_t *a_atom_num, dap_time_t *a_atom_timestamp); @@ -323,7 +323,7 @@ DAP_STATIC_INLINE bool dap_chain_get_atom_last_hash(dap_chain_t *a_chain, dap_ch { return dap_chain_get_atom_last_hash_num_ts(a_chain, a_cell_id, a_atom_hash, NULL, NULL); } -ssize_t dap_chain_atom_save(dap_chain_cell_t *a_chain_cell, const uint8_t *a_atom, size_t a_atom_size, dap_hash_fast_t *a_new_atom_hash); +ssize_t dap_chain_atom_save(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id, const uint8_t *a_atom, size_t a_atom_size, dap_hash_fast_t *a_new_atom_hash); int dap_cert_chain_file_save(dap_chain_datum_t *datum, char *net_name); const char *dap_chain_type_to_str(dap_chain_type_t a_chain_type); diff --git a/modules/chain/include/dap_chain_cell.h b/modules/chain/include/dap_chain_cell.h index 6ed59c9ca3..618def9cc6 100644 --- a/modules/chain/include/dap_chain_cell.h +++ b/modules/chain/include/dap_chain_cell.h @@ -98,6 +98,7 @@ DAP_INLINE void dap_chain_cell_remit(const dap_chain_cell_t *a_cell) { void dap_chain_cell_close(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id); void dap_chain_cell_close_all(dap_chain_t *a_chain); -ssize_t 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_t *a_chain, dap_chain_cell_id_t a_cell_id, + const void *a_atom, size_t a_atom_size, char **a_atom_map); #define dap_chain_cell_file_update(a_cell) dap_chain_cell_file_append(a_cell, NULL, 0); -- GitLab From 223dca189c0c49737545551f44a40b88f95455d5 Mon Sep 17 00:00:00 2001 From: "P. Constantin" <papizh.konstantin@demlabs.net> Date: Mon, 17 Feb 2025 20:41:15 +0700 Subject: [PATCH 06/11] .... --- dap-sdk | 2 +- modules/chain/dap_chain.c | 57 +-- modules/chain/dap_chain_cell.c | 465 ++++++------------ modules/chain/include/dap_chain.h | 14 +- modules/chain/include/dap_chain_cell.h | 12 +- .../consensus/dag-poa/dap_chain_cs_dag_poa.c | 8 +- modules/ledger/dap_chain_ledger.c | 20 +- modules/ledger/dap_chain_ledger_decree.c | 2 +- modules/net/dap_chain_net.c | 244 ++++----- .../service/datum/dap_chain_net_srv_datum.c | 2 +- modules/type/blocks/dap_chain_cs_blocks.c | 63 +-- modules/type/dag/dap_chain_cs_dag.c | 278 ++++++----- 12 files changed, 456 insertions(+), 711 deletions(-) diff --git a/dap-sdk b/dap-sdk index e4ffa996e2..64b2cd4990 160000 --- a/dap-sdk +++ b/dap-sdk @@ -1 +1 @@ -Subproject commit e4ffa996e2df6a6f454ba8110bc49b8f1c533741 +Subproject commit 64b2cd4990a59c3af91e8f1402d4cfd468bd90bc diff --git a/modules/chain/dap_chain.c b/modules/chain/dap_chain.c index 6070d8e8c6..20b2e15e7d 100644 --- a/modules/chain/dap_chain.c +++ b/modules/chain/dap_chain.c @@ -83,11 +83,11 @@ int dap_chain_init(void) */ void dap_chain_deinit(void) { - dap_chain_item_t * l_item = NULL, *l_tmp = NULL; + /*dap_chain_item_t * l_item = NULL, *l_tmp = NULL; HASH_ITER(hh, s_chain_items, l_item, l_tmp) { dap_chain_delete(l_item->chain); DAP_DELETE(l_item); - } + }*/ // TODO! dap_chain_srv_deinit(); } @@ -144,12 +144,6 @@ void dap_chain_set_cs_type(dap_chain_t *a_chain, const char *a_cs_type) DAP_CHAIN_PVT(a_chain)->cs_type = dap_strdup(a_cs_type); } -int dap_chain_purge(dap_chain_t *a_chain) -{ - int ret = dap_chain_cs_class_purge(a_chain); - return ret + dap_chain_cs_purge(a_chain); -} - /** * @brief * delete dap chain object @@ -216,6 +210,7 @@ dap_chain_atom_ptr_t dap_chain_get_atom_by_hash(dap_chain_t * a_chain, dap_chain */ dap_chain_t * dap_chain_find_by_id(dap_chain_net_id_t a_chain_net_id,dap_chain_id_t a_chain_id) { + // TODO! Reconsider lock mechanics dap_chain_item_id_t l_chain_item_id = { .id = a_chain_id, .net_id = a_chain_net_id, @@ -491,24 +486,6 @@ const char *dap_chain_get_cs_type(dap_chain_t *l_chain) return (const char *)DAP_CHAIN_PVT(l_chain)->cs_name; } -/** - * @brief dap_chain_save_all - * @param l_chain - * @return - */ -int dap_chain_save_all(dap_chain_t *l_chain) // TODO - move to cell.c -{ - int l_ret = 0; - pthread_rwlock_rdlock(&l_chain->cell_rwlock); - dap_chain_cell_t *l_item = NULL, *l_item_tmp = NULL; - HASH_ITER(hh,l_chain->cells,l_item,l_item_tmp){ - if(dap_chain_cell_file_update(l_item) <= 0) - l_ret++; - } - pthread_rwlock_unlock(&l_chain->cell_rwlock); - return l_ret; -} - //send chain load_progress data to notify socket static bool s_load_notify_callback(dap_chain_t* a_chain) { json_object* l_chain_info = json_object_new_object(); @@ -546,7 +523,7 @@ int dap_chain_load_all(dap_chain_t *a_chain) const char l_suffix[] = ".dchaincell", *l_filename; struct dirent *l_dir_entry = NULL; dap_time_t l_ts_start = dap_time_now(); - while (( l_dir_entry = readdir(l_dir) )) { + while (( l_dir_entry = readdir(l_dir) ) && !l_err ) { l_filename = l_dir_entry->d_name; size_t l_namelen = strlen(l_filename); if ( l_namelen >= sizeof(l_suffix) && !strncmp(l_filename + l_namelen - sizeof(l_suffix) - 1, l_suffix, sizeof(l_suffix) - 1) ) { @@ -554,26 +531,6 @@ int dap_chain_load_all(dap_chain_t *a_chain) l_err = dap_chain_cell_open(a_chain, l_filename, 'a'); dap_timerfd_delete(l_load_notify_timer->worker, l_load_notify_timer->esocket_uuid); s_load_notify_callback(a_chain); - if (l_err) - break; - if ( DAP_CHAIN_PVT(a_chain)->need_reorder ) { -#ifdef DAP_OS_WINDOWS - char *l_new_path = dap_strdup_printf("%s/%s.new", DAP_CHAIN_PVT(a_chain)->file_storage_dir, l_filename); - if ( remove(l_new_path) == -1 ) - log_it(L_ERROR, "File \"%s\" doesn't exist", l_new_path); - DAP_DELETE(l_new_path); -#else - char *l_old_name = dap_strdup_printf("%s/%s", DAP_CHAIN_PVT(a_chain)->file_storage_dir, l_filename), - *l_filename_backup = dap_strdup_printf("%s.unsorted", l_old_name); - - if (remove(l_filename_backup) == -1) - log_it(L_ERROR, "File %s doesn't exist", l_filename_backup); - if (rename(l_old_name, l_filename_backup)) { - log_it(L_ERROR, "Couldn't rename %s to %s", l_old_name, l_filename_backup); - } - DAP_DEL_MULTY(l_old_name, l_filename_backup); -#endif - } } } closedir(l_dir); @@ -584,11 +541,11 @@ int dap_chain_load_all(dap_chain_t *a_chain) a_chain->net_name, a_chain->name, difftime((time_t)dap_time_now(), l_ts_start)); break; case -1: - if (!( l_err = dap_chain_cell_open_file(a_chain, "0.dchaincell", 'w') )) + if (!( l_err = dap_chain_cell_open(a_chain, "0.dchaincell", 'w') )) log_it(L_INFO, "Initialized chain \"%s : %s\" cell 0", a_chain->net_name, a_chain->name); break; default: - log_it(L_ERROR, "Chain \"%s : %s\" cell was not loaded, error %d", a_chain->net_name, a_chain->name, l_err) + log_it(L_ERROR, "Chain \"%s : %s\" cell was not loaded, error %d", a_chain->net_name, a_chain->name, l_err); } return l_err; } @@ -821,7 +778,7 @@ static bool s_notify_datum_removed_on_thread(void *a_arg) return false; } -ssize_t dap_chain_atom_save(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id, +int dap_chain_atom_save(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id, const uint8_t *a_atom, size_t a_atom_size, dap_hash_fast_t *a_new_atom_hash, char **a_atom_map) { diff --git a/modules/chain/dap_chain_cell.c b/modules/chain/dap_chain_cell.c index f7b8580bfd..7df6254238 100644 --- a/modules/chain/dap_chain_cell.c +++ b/modules/chain/dap_chain_cell.c @@ -58,6 +58,23 @@ typedef struct dap_chain_cell_file_header dap_chain_cell_id_t cell_id; } DAP_ALIGN_PACKED dap_chain_cell_file_header_t; +typedef struct dap_chain_cell_mmap_volume { +#ifdef DAP_OS_DARWIN + off_t offset; +#endif + off_t size; + char *base; + struct dap_chain_cell_mmap_volume *prev, *next; +} dap_chain_cell_mmap_volume_t; + +typedef struct dap_chain_cell_mmap_data { +#ifdef DAP_OS_WINDOWS + HANDLE section; +#endif + dap_chain_cell_mmap_volume_t *volume; + char *cursor; +} dap_chain_cell_mmap_data_t; + #ifdef DAP_OS_WINDOWS typedef NTSTATUS (*pfn_NtCreateSection)( OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, @@ -110,204 +127,100 @@ int dap_chain_cell_init(void) } #ifndef DAP_OS_WINDOWS -DAP_STATIC_INLINE void s_cell_reclaim_cur_volume(dap_chain_cell_t *a_cell) { +DAP_STATIC_INLINE void s_cell_reclaim_cur_volume(dap_chain_cell_mmap_volume_t *a_vol) { if ( #ifdef MADV_PAGEOUT - //madvise(a_cell->map, (size_t)(a_cell->map_end - a_cell->map), MADV_PAGEOUT) && + //madvise(a_vol->base, a_vol->size, MADV_PAGEOUT) && #endif - madvise(a_cell->map, (size_t)(a_cell->map_end - a_cell->map), MADV_DONTNEED) ) + madvise(a_vol->base, a_vol->size, MADV_DONTNEED) ) log_it(L_ERROR, "Unable to reclaim the previous volume, errno %d: \"%s\"", errno, dap_strerror(errno)); } #endif -#if 0 -DAP_STATIC_INLINE int s_cell_file_write_header(dap_chain_cell_t *a_cell) -{ - 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 = a_cell->chain->id, - .chain_net_id = a_cell->chain->net_id, - .cell_id = a_cell->id - }; - return fwrite(&l_hdr, sizeof(l_hdr), 1, a_cell->file_storage) ? fflush(a_cell->file_storage) : -1; -} -#endif - -DAP_STATIC_INLINE int s_cell_map_new_volume(dap_chain_cell_mmap_data_t *a_cell_map_data, size_t a_fpos, bool a_load) { +DAP_STATIC_INLINE int s_cell_map_new_volume(dap_chain_cell_t *a_cell, off_t a_fpos, bool a_load) { #ifdef DAP_OS_WINDOWS - HANDLE hSection = NULL; if ( !a_fpos ) { - //if (a_cell->map_range_bounds) - // NtClose( (HANDLE)a_cell->map_range_bounds->data ); - off_t l_ssize = !fseeko(a_cell->file_storage, 0, SEEK_END) ? ftello(a_cell->file_storage) : -1; - if (l_ssize < 0) - return log_it(L_ERROR, "Can't get chain size, error %d: \"%s\"", errno, dap_strerror(errno)), -1; - LARGE_INTEGER SectionSize = { - .QuadPart = l_ssize - }; - - NTSTATUS err = pfnNtCreateSection(&hSection, SECTION_MAP_READ | SECTION_EXTEND_SIZE, - NULL, &SectionSize, PAGE_READWRITE, SEC_RESERVE, - (HANDLE)_get_osfhandle(fileno(a_cell->file_storage))); + LARGE_INTEGER SectionSize = { .QuadPart = !fseeko(a_cell->file_storage, 0, SEEK_END) ? ftello(a_cell->file_storage) : -1 }; + dap_return_val_if_pass_err(SectionSize.QuadPart < 0, -1, "Can't get chain size, error %d: \"%s\"", errno, dap_strerror(errno)); + NTSTATUS err = pfnNtCreateSection( &a_cell->mapping->section, SECTION_MAP_READ | SECTION_EXTEND_SIZE, + NULL, &SectionSize, PAGE_READWRITE, SEC_RESERVE, + (HANDLE)_get_osfhandle(fileno(a_cell->file_storage)) ); if ( !NT_SUCCESS(err) ) return log_it(L_ERROR, "NtCreateSection() failed, status %lx: \"%s\"", err, dap_str_ntstatus(err) ), -1; - a_cell->map_range_bounds = dap_list_append(a_cell->map_range_bounds, hSection); } #endif - size_t l_map_size = dap_page_roundup(DAP_MAPPED_VOLUME_LIMIT), + dap_chain_cell_mmap_volume_t *l_new_vol = DAP_NEW_Z(dap_chain_cell_mmap_volume_t); + l_new_vol->size = dap_page_roundup(DAP_MAPPED_VOLUME_LIMIT); + off_t l_volume_offset = a_fpos ? #ifdef DAP_OS_WINDOWS - l_volume_start = a_fpos ? dap_64k_rounddown(a_fpos) : 0, + dap_64k_rounddown(a_fpos) #else - l_volume_start = a_fpos ? dap_page_rounddown(a_fpos) : 0, -#endif - l_offset = a_fpos - l_volume_start; + dap_page_rounddown(a_fpos) +#endif + : 0, + l_offset = a_fpos - l_volume_offset; #ifdef DAP_OS_WINDOWS - hSection = (HANDLE)a_cell->map_range_bounds->data; - a_cell->map = NULL; int err = 0; - LARGE_INTEGER Offset = { - .QuadPart = l_volume_start - }; - err = pfnNtMapViewOfSection(hSection, GetCurrentProcess(), (HANDLE)&a_cell->map, 0, 0, - &Offset, &l_map_size, ViewUnmap, MEM_RESERVE, PAGE_READONLY); - if ( !NT_SUCCESS(err) ) - return NtClose(hSection), log_it(L_ERROR, "NtMapViewOfSection() failed, status %lx: \"%s\"", - err, dap_str_ntstatus(err) ), -1; + LARGE_INTEGER Offset = { .QuadPart = l_volume_offset }; + err = pfnNtMapViewOfSection(a_cell->mapping->section, GetCurrentProcess(), (HANDLE)&l_new_vol->base, 0, 0, + &Offset, &l_new_vol->size, ViewUnmap, MEM_RESERVE, PAGE_READONLY); + if ( !NT_SUCCESS(err) ) { + NtClose(a_cell->mapping->section); + log_it(L_ERROR, "NtMapViewOfSection() failed, status %lx: \"%s\"", err, dap_str_ntstatus(err) ); + DAP_DELETE(l_new_vol); + return -1; + } #else if (a_load) - s_cell_reclaim_cur_volume(a_cell); - if (( a_cell->map = mmap(NULL, l_map_size, PROT_READ, MAP_PRIVATE, - fileno(a_cell->file_storage), l_volume_start) ) == MAP_FAILED ) - return log_it(L_ERROR, "Chain cell \"%s\" 0x%016"DAP_UINT64_FORMAT_X" cannot be mapped, errno %d", - a_cell->file_storage_path, a_cell->id.uint64, errno), -1; + s_cell_reclaim_cur_volume(a_cell->mapping->volume); + l_new_vol->base = mmap( NULL, l_new_vol->size, PROT_READ, MAP_PRIVATE, + fileno(a_cell->file_storage), l_volume_offset ); + if ( l_new_vol->base == MAP_FAILED ) { + log_it(L_ERROR, "Chain cell \"%s\" 0x%016"DAP_UINT64_FORMAT_X" cannot be mapped, errno %d", + a_cell->file_storage_path, a_cell->id.uint64, errno); + DAP_DELETE(l_new_vol); + return -1; + } #ifdef DAP_OS_DARWIN - a_cell->cur_vol_start = l_volume_start; + l_new_vol->offset = l_volume_offset; #endif #endif - a_cell->map_pos = a_cell->map + l_offset; - a_cell->map_range_bounds = dap_list_append(a_cell->map_range_bounds, a_cell->map); - a_cell->map_range_bounds = dap_list_append(a_cell->map_range_bounds, a_cell->map_end = a_cell->map + l_map_size); + a_cell->mapping->cursor = l_new_vol->base + l_offset; #ifndef DAP_OS_WINDOWS if (a_load) - madvise(a_cell->map, l_map_size, MADV_SEQUENTIAL); + madvise(l_new_vol->base, l_new_vol->size, MADV_SEQUENTIAL); #endif + DL_PREPEND(a_cell->mapping->volume, l_new_vol); return 0; } -#if 0 -/** - * @brief - * a_cell_id if < 0 then not used - * @param a_chain dap_chain_t object - * @param a_cell_id dap_chain_cell_id_t cell (shard) id - * @return dap_chain_cell_t* - */ -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 * l_cell = NULL; - pthread_rwlock_wrlock(&a_chain->cell_rwlock); - HASH_FIND(hh, a_chain->cells, &a_cell_id, sizeof(dap_chain_cell_id_t), l_cell); - if (l_cell) { - pthread_rwlock_unlock(&a_chain->cell_rwlock); - return l_cell; - } - char file_storage_path[MAX_PATH]; - snprintf(file_storage_path, MAX_PATH, "%s/%0"DAP_UINT64_FORMAT_x".dchaincell", - DAP_CHAIN_PVT(a_chain)->file_storage_dir, a_cell_id.uint64); - FILE *l_file = NULL; -#define CLEANUP_AND_RET return ({ if (l_file) fclose(l_file); \ - DAP_DELETE(l_cell); \ - pthread_rwlock_unlock(&a_chain->cell_rwlock); \ - NULL; }) - - if ( !(l_file = fopen(file_storage_path, "a+b")) ) { - log_it(L_ERROR, "Chain cell \"%s\" 0x%016"DAP_UINT64_FORMAT_X" cannot be opened, error %d", - file_storage_path, a_cell_id.uint64, errno); - CLEANUP_AND_RET; - } - if ( !(l_cell = DAP_NEW_Z(dap_chain_cell_t)) ) - CLEANUP_AND_RET; - *l_cell = (dap_chain_cell_t) { - .id = a_cell_id, - .chain = a_chain, - .file_storage = l_file, - .storage_rwlock = PTHREAD_RWLOCK_INITIALIZER - }; - off_t l_size = !fseeko(l_file, 0, SEEK_END) ? ftello(l_file) : -1; - if (l_size < 0) - CLEANUP_AND_RET; - else if ( (size_t)l_size < sizeof(dap_chain_cell_file_header_t) ) { - if ( l_size ) { - log_it(L_INFO, "Possibly corrupt cell storage 0x%016"DAP_UINT64_FORMAT_X" \"%s\", rewriting it", - a_cell_id.uint64, file_storage_path); - l_file = freopen(file_storage_path, "w+b", l_file); - } - if ( s_cell_file_write_header(l_cell) < 0 ) { - log_it(L_ERROR, "Can't init file storage for cell 0x%016"DAP_UINT64_FORMAT_X" \"%s\", errno %d", - a_cell_id.uint64, file_storage_path, errno); - CLEANUP_AND_RET; - } - log_it(L_NOTICE, "Initialized file storage for cell 0x%016"DAP_UINT64_FORMAT_X" \"%s\"", - a_cell_id.uint64, file_storage_path); - fflush(l_file); - l_file = freopen(file_storage_path, "a+b", l_file); - } - - if ( a_chain->is_mapped && s_cell_map_new_volume(l_cell, 0, true) ) { - CLEANUP_AND_RET; - } -#undef CLEANUP_AND_RET - memcpy(l_cell->file_storage_path, file_storage_path, sizeof(file_storage_path)); - debug_if (s_debug_more && a_chain->is_mapped, L_DEBUG, "Mapped volume size is %lu", (size_t)(l_cell->map_end - l_cell->map)); - HASH_ADD(hh, a_chain->cells, id, sizeof(dap_chain_cell_id_t), l_cell); - pthread_rwlock_unlock(&a_chain->cell_rwlock); - return l_cell; -} - -#endif - DAP_STATIC_INLINE int s_cell_close(dap_chain_cell_t *a_cell) { - pthread_rwlock_wrlock(&a_cell->storage_rwlock); + //pthread_rwlock_wrlock(&a_cell->storage_rwlock); if(a_cell->file_storage) { fclose(a_cell->file_storage); a_cell->file_storage = NULL; } if (a_cell->chain->is_mapped) { - dap_list_t *l_iter = a_cell->map_range_bounds; + a_cell->mapping->cursor = NULL; + int i = 0; + dap_chain_cell_mmap_volume_t *l_vol, *l_tmp; + DL_FOREACH_SAFE(a_cell->mapping->volume, l_vol, l_tmp) { + debug_if(s_debug_more, L_DEBUG, "Unmap volume #%d, %lu bytes", i++, l_vol->size); #ifdef DAP_OS_WINDOWS - l_iter = l_iter->next; -#endif - for (; l_iter; l_iter = l_iter->next) { - if (l_iter->next) { - debug_if(s_debug_more, L_DEBUG, "Unmap volume %p (%lu bytes)", l_iter->data, (size_t)(l_iter->next->data - l_iter->data)); -#ifdef DAP_OS_WINDOWS - pfnNtUnmapViewOfSection(GetCurrentProcess(), l_iter->data); + pfnNtUnmapViewOfSection(GetCurrentProcess(), l_vol->base); #else - munmap(l_iter->data, (size_t)(l_iter->next->data - l_iter->data)); + munmap(l_vol->base, l_vol->size); #endif - l_iter = l_iter->next; - } + DL_DELETE(a_cell->mapping->volume, l_vol); + DAP_DELETE(l_vol); } #ifdef DAP_OS_WINDOWS - NtClose(a_cell->map_range_bounds->data); + NtClose(a_cell->mapping->section); #endif - dap_list_free(a_cell->map_range_bounds); } -#ifdef DAP_OS_WINDOWS - char *l_new = strstr(a_cell->file_storage_path, ".new"); - if (l_new) { - char *l_orig = dap_strdup(a_cell->file_storage_path); - *l_new = '\0'; - remove(a_cell->file_storage_path); - rename(l_orig, a_cell->file_storage_path); - DAP_DELETE(l_orig); - } -#endif - pthread_rwlock_unlock(&a_cell->storage_rwlock); - pthread_rwlock_destroy(&a_cell->storage_rwlock); + //pthread_rwlock_unlock(&a_cell->storage_rwlock); + //pthread_rwlock_destroy(&a_cell->storage_rwlock); } /** @@ -318,89 +231,17 @@ DAP_STATIC_INLINE int s_cell_close(dap_chain_cell_t *a_cell) { void dap_chain_cell_close(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id) { dap_return_if_fail(a_chain); - dap_chain_cell_t *l_cell = NULL; - HASH_FIND(hh, a_chain->cells, &a_cell_id, sizeof(dap_chain_cell_id_t), l_cell); - if (l_cell) { - s_cell_close(l_cell); - HASH_DEL(a_chain->cells, l_cell); - DAP_DELETE(l_cell); - } else - log_it(L_ERROR, "Cell 0x%016"DAP_UINT64_FORMAT_X" not found in chain \"%s : %s\"", - a_cell_id.uint64, a_chain->net_name, a_chain->name); - pthread_rwlock_unlock(&a_chain->cell_rwlock); -} - -#if 0 -/** - * @brief - * free chain cell objects - * @param a_cell dap_chain_cell_t object - */ -void dap_chain_cell_delete(dap_chain_cell_t *a_cell) -{ - if(!a_cell) - return; - dap_chain_cell_close(a_cell); - if (a_cell->chain->cells) { - dap_chain_cell_t *l_cell = NULL; - dap_chain_cell_id_t l_cell_id = { - .uint64 = a_cell->id.uint64 - }; - pthread_rwlock_wrlock(&a_cell->chain->cell_rwlock); - HASH_FIND(hh, a_cell->chain->cells, &l_cell_id, sizeof(dap_chain_cell_id_t), l_cell); - if (l_cell) - HASH_DEL(a_cell->chain->cells, l_cell); - pthread_rwlock_unlock(&a_cell->chain->cell_rwlock); - } - a_cell->chain = NULL; - a_cell->file_storage_path[0] = '\0'; - pthread_rwlock_destroy(&a_cell->storage_rwlock); - DAP_DELETE(a_cell); -} - -void dap_chain_cell_delete_all_and_free_file(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) { - char *l_fsp = dap_strdup(l_cell->file_storage_path); - dap_chain_cell_id_t l_cell_id = l_cell->id; - dap_chain_cell_close(l_cell); - - dap_chain_cell_t * l_cell_nh = DAP_NEW_Z(dap_chain_cell_t); - FILE *l_file = fopen(l_fsp, "w+b"); - if ( !l_file ) { - log_it(L_ERROR, "Chain cell \"%s\" 0x%016"DAP_UINT64_FORMAT_X" cannot be opened, error %d", - l_fsp, l_cell_id.uint64, errno); - } - *l_cell_nh = (dap_chain_cell_t) { - .id = l_cell_id, - .chain = a_chain, - .file_storage = l_file - }; - if ( s_cell_file_write_header(l_cell_nh) < 0 ) { - log_it(L_ERROR, "Can't init file storage for cell 0x%016"DAP_UINT64_FORMAT_X" \"%s\", errno %d", - l_cell_id.uint64, l_fsp, errno); - } else { - log_it(L_NOTICE, "Reinitialized file storage for cell 0x%016"DAP_UINT64_FORMAT_X" \"%s\"", - l_cell_id.uint64, l_fsp); - } - dap_chain_cell_close(l_cell_nh); - - DAP_DELETE(l_fsp); - 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); + dap_chain_cell_t *l_cell = dap_chain_cell_capture_by_id(a_chain, a_cell_id); + dap_return_if_fail_err(l_cell, "Cell 0x%016"DAP_UINT64_FORMAT_X" not found in chain \"%s : %s\"", + a_cell_id.uint64, a_chain->net_name, a_chain->name); + s_cell_close(l_cell); + HASH_DEL(a_chain->cells, l_cell); + DAP_DELETE(l_cell); + dap_chain_cell_remit(l_cell); } -#endif - void dap_chain_cell_close_all(dap_chain_t *a_chain) { - if (!a_chain) - return; + dap_return_if_fail(a_chain); 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) { @@ -429,7 +270,7 @@ DAP_STATIC_INLINE int s_cell_load_from_file(dap_chain_cell_t *a_cell) dap_chain_cell_file_header_t *l_hdr = DAP_NEW_STACK(dap_chain_cell_file_header_t); if (a_cell->chain->is_mapped) { dap_return_val_if_pass_err( s_cell_map_new_volume(a_cell, 0, false), -3, "Error on mapping the first volume" ); - l_hdr = (dap_chain_cell_file_header_t*)a_cell->map; + l_hdr = (dap_chain_cell_file_header_t*)a_cell->mapping->volume->base; } else { fseeko(a_cell->file_storage, 0, SEEK_SET); dap_return_val_if_fail_err( fread(l_hdr, 1, sizeof(*l_hdr), a_cell->file_storage) != sizeof(*l_hdr), -4, @@ -443,62 +284,78 @@ DAP_STATIC_INLINE int s_cell_load_from_file(dap_chain_cell_t *a_cell) "Too low chain version %d < %d, create a backup", l_hdr->version, DAP_CHAIN_CELL_FILE_VERSION ); l_pos = sizeof(*l_hdr); if (a_cell->chain->is_mapped) - a_cell->map_pos = a_cell->map + l_pos; + a_cell->mapping->cursor = a_cell->mapping->volume->base + l_pos; if (l_full_size == l_pos) - return 0; // fseeko(a_cell->file_storage, l_pos, SEEK_SET); + return 0; } /* Load atoms */ int l_ret = 0; - uint64_t l_el_size = 0, q = 0; + off_t l_el_size = 0, q = 0; + dap_chain_atom_ptr_t l_atom; + dap_hash_fast_t l_atom_hash; if (a_cell->chain->is_mapped) { - dap_hash_fast_t l_atom_hash; - for ( off_t l_vol_rest = 0; l_pos + sizeof(uint64_t) < (size_t)l_full_size; ++q, l_pos += l_el_size + sizeof(uint64_t) ) { - l_vol_rest = (off_t)(a_cell->map_end - a_cell->map_pos) - sizeof(uint64_t); - if ( l_vol_rest <= 0 || (uint64_t)l_vol_rest < *(uint64_t*)a_cell->map_pos ) + for ( off_t l_vol_rest = 0; l_pos + sizeof(uint64_t) < l_full_size; ++q, l_pos += sizeof(uint64_t) + l_el_size ) { + l_vol_rest = (off_t)( a_cell->mapping->volume->base + a_cell->mapping->volume->size - a_cell->mapping->cursor - sizeof(uint64_t) ); + if ( l_vol_rest <= 0 || (uint64_t)l_vol_rest < ( l_el_size = *(uint64_t*)a_cell->mapping->cursor ) ) dap_return_val_if_pass_err( s_cell_map_new_volume(a_cell, l_pos, true), -7, "Error on mapping a new volume" ); - l_el_size = *(uint64_t*)a_cell->map_pos; if ( !l_el_size || l_el_size > (size_t)(l_full_size - l_pos) ) break; - a_cell->map_pos += sizeof(uint64_t); - dap_chain_atom_ptr_t l_atom = (dap_chain_atom_ptr_t)(a_cell->map_pos); + l_atom = (dap_chain_atom_ptr_t)(a_cell->mapping->cursor + sizeof(uint64_t)); dap_hash_fast(l_atom, l_el_size, &l_atom_hash); - a_cell->chain->callback_atom_add(a_cell->chain, l_atom, l_el_size, &l_atom_hash, false); - a_cell->map_pos += l_el_size; - a_cell->chain->load_progress = (int)((float)l_pos/l_full_size * 100 + 0.5); + dap_chain_atom_verify_res_t l_verif = a_cell->chain->callback_atom_prefetch + ? a_cell->chain->callback_atom_prefetch(a_cell->chain, l_atom, l_el_size, &l_atom_hash) + : a_cell->chain->callback_atom_add(a_cell->chain, l_atom, l_el_size, &l_atom_hash, false); + if ( l_verif == ATOM_CORRUPTED ) { + log_it(L_ERROR, "Atom #%d is corrupted, can't proceed with loading chain \"%s : %s\" cell 0x%016"DAP_UINT64_FORMAT_X"", + q, a_cell->chain->net_name, a_cell->chain->name, a_cell->id.uint64); + l_ret = 8; + break; + } + a_cell->mapping->cursor += sizeof(uint64_t) + l_el_size; + if ( !a_cell->chain->callback_atom_prefetch ) + a_cell->chain->load_progress = (int)((float)l_pos/l_full_size * 100 + 0.5); } #ifndef DAP_OS_WINDOWS - s_cell_reclaim_cur_volume(a_cell); + /* Reclaim the last volume */ + s_cell_reclaim_cur_volume(a_cell->mapping->volume); #endif } else { size_t l_read = 0; - while ((l_read = fread(&l_el_size, 1, sizeof(l_el_size), a_cell->file_storage)) && !feof(a_cell->file_storage)) { - if (l_read != sizeof(l_el_size) || l_el_size == 0) { + while (( l_read = fread(&l_el_size, 1, sizeof(l_el_size), a_cell->file_storage) ) && !feof(a_cell->file_storage) ) { + if ( !l_el_size || l_read != sizeof(l_el_size) ) { log_it(L_ERROR, "Corrupted element size %zu, chain %s is damaged", l_el_size, a_cell->file_storage_path); l_ret = 8; break; } - dap_chain_atom_ptr_t l_element = DAP_NEW_SIZE(dap_chain_atom_ptr_t, l_el_size); - if (!l_element) { + l_atom = DAP_NEW_SIZE(dap_chain_atom_ptr_t, l_el_size); + if (!l_atom) { log_it(L_CRITICAL, "Memory allocation error"); l_ret = -9; break; } - l_read = fread((void*)l_element, 1, l_el_size, a_cell->file_storage); + l_read = fread((void*)l_atom, 1, l_el_size, a_cell->file_storage); if (l_read != l_el_size) { log_it(L_ERROR, "Read only %lu of %zu bytes, stop cell loading", l_read, l_el_size); - DAP_DELETE(l_element); + DAP_DELETE(l_atom); l_ret = 10; break; } - l_pos += sizeof(uint64_t) + l_read; - a_cell->chain->load_progress = (int)((float)l_pos/l_full_size * 100 + 0.5); - dap_hash_fast_t l_atom_hash = {}; - dap_hash_fast(l_element, l_el_size, &l_atom_hash); - dap_chain_atom_verify_res_t l_res = a_cell->chain->callback_atom_add(a_cell->chain, l_element, l_el_size, &l_atom_hash, false); - if (l_res != ATOM_ACCEPT && l_res != ATOM_FORK) - DAP_DELETE(l_element); + dap_hash_fast(l_atom, l_el_size, &l_atom_hash); + dap_chain_atom_verify_res_t l_verif = a_cell->chain->callback_atom_prefetch + ? a_cell->chain->callback_atom_prefetch(a_cell->chain, l_atom, l_el_size, &l_atom_hash) + : a_cell->chain->callback_atom_add(a_cell->chain, l_atom, l_el_size, &l_atom_hash, false); + DAP_DELETE(l_atom); + if ( l_verif == ATOM_CORRUPTED ) { + log_it(L_ERROR, "Atom #%d is corrupted, can't proceed with loading chain \"%s : %s\" cell 0x%016"DAP_UINT64_FORMAT_X"", + q, a_cell->chain->net_name, a_cell->chain->name, a_cell->id.uint64); + l_ret = 11; + break; + } ++q; + l_pos += sizeof(uint64_t) + l_read; + if ( !a_cell->chain->callback_atom_prefetch ) + a_cell->chain->load_progress = (int)((float)l_pos/l_full_size * 100 + 0.5); } } if ( l_pos < l_full_size && l_ret > 0 ) { @@ -507,8 +364,7 @@ DAP_STATIC_INLINE int s_cell_load_from_file(dap_chain_cell_t *a_cell) #ifdef DAP_OS_WINDOWS if (a_cell->chain->is_mapped) { LARGE_INTEGER SectionSize = (LARGE_INTEGER) { .QuadPart = l_pos }; - HANDLE hSection = (HANDLE)a_cell->map_range_bounds->data; - NTSTATUS err = pfnNtExtendSection(hSection, &SectionSize); + NTSTATUS err = pfnNtExtendSection(a_cell->mapping->section, &SectionSize); if ( !NT_SUCCESS(err) ) log_it(L_ERROR, "NtExtendSection() failed, status %lx", err); } else @@ -516,7 +372,10 @@ DAP_STATIC_INLINE int s_cell_load_from_file(dap_chain_cell_t *a_cell) ftruncate(fileno(a_cell->file_storage), l_pos); } fseeko(a_cell->file_storage, l_pos, SEEK_SET); - log_it(L_INFO, "Loaded %lu atoms in cell %s", q, a_cell->file_storage_path); + if ( a_cell->chain->callback_atoms_prefetched_add ) + a_cell->chain->callback_atoms_prefetched_add(a_cell->chain); + log_it(L_INFO, "Loaded %lu atoms in chain \"%s : %s\" cell 0x%016"DAP_UINT64_FORMAT_X"", + q, a_cell->chain->net_name, a_cell->chain->name, a_cell->id.uint64); return l_ret; } @@ -528,25 +387,26 @@ DAP_STATIC_INLINE int s_cell_open(dap_chain_t *a_chain, const char *a_filename, switch ( sscanf(a_filename, l_fmt, &l_cell_id.uint64, l_ext, &l_ext2) ) { case 3: + // TODO: X.dchaincell.* case 2: - if ( !dap_strncmp(l_ext, CELL_FILE_EXT) ) + if ( !dap_strncmp(l_ext, CELL_FILE_EXT, sizeof(l_ext)) ) break; default: return log_it(L_ERROR, "Invalid cell file name \"%s\"", a_filename), EINVAL; } } - - const char file_storage_path[MAX_PATH], mode[] = { a_mode, '+', 'b', '\0' }; + char file_storage_path[MAX_PATH], mode[] = { a_mode, '+', 'b', '\0' }; snprintf(file_storage_path, MAX_PATH, "%s/%s", DAP_CHAIN_PVT(a_chain)->file_storage_dir, a_filename); dap_chain_cell_t *l_cell = NULL; #define m_ret_err(err, ...) return ({ if (l_cell->file_storage) fclose(l_cell->file_storage); \ - DAP_DELETE(l_cell); log_it(L_ERROR, ##__VA_ARGS__), err }) + DAP_DELETE(l_cell); log_it(L_ERROR, ##__VA_ARGS__), err; }) dap_chain_cell_mmap_data_t l_cell_map_data = { }; HASH_FIND(hh, a_chain->cells, &l_cell_id, sizeof(dap_chain_cell_id_t), l_cell); if (l_cell) { if (a_mode == 'w') { + /* Attention! File rewriting requires that ledger was already purged */ s_cell_close(l_cell); HASH_DEL(a_chain->cells, l_cell); DAP_DELETE(l_cell); @@ -564,19 +424,21 @@ DAP_STATIC_INLINE int s_cell_open(dap_chain_t *a_chain, const char *a_filename, .id = l_cell_id, .chain = a_chain, .file_storage = l_file, - .storage_rwlock = PTHREAD_RWLOCK_INITIALIZER + //.storage_rwlock = PTHREAD_RWLOCK_INITIALIZER }; dap_strncpy(l_cell->file_storage_path, file_storage_path, MAX_PATH); - switch (a_mode) { + switch (*mode) { case 'a': { int l_load_res = s_cell_load_from_file(l_cell); - if (!l_load_res) + if ( !l_load_res ) break; else if (l_load_res < 0) m_ret_err(errno, "Cell \"%s : %s / \"%s\" cannot be loaded, code %d", a_chain->net_name, a_chain->name, a_filename, l_load_res); // Otherwise, rewrite the file from scratch + ftruncate(fileno(l_cell->file_storage), 0); + *mode = 'w'; } case 'w': { dap_chain_cell_file_header_t l_hdr = { @@ -599,8 +461,9 @@ DAP_STATIC_INLINE int s_cell_open(dap_chain_t *a_chain, const char *a_filename, } HASH_ADD(hh, a_chain->cells, id, sizeof(dap_chain_cell_id_t), l_cell); log_it(L_INFO, "Cell storage \"%s\" is %s for chain \"%s : %s\"", - a_filename, a_mode == 'w' ? "created" : "opened" a_chain->net_name, a_chain->name); + a_filename, *mode == 'w' ? "created" : "opened", a_chain->net_name, a_chain->name); return 0; +#undef m_ret_err } int dap_chain_cell_open(dap_chain_t *a_chain, const char *a_filename, const char a_mode) { @@ -608,7 +471,6 @@ int dap_chain_cell_open(dap_chain_t *a_chain, const char *a_filename, const char int l_ret = s_cell_open(a_chain, a_filename, a_mode); pthread_rwlock_unlock(&a_chain->cell_rwlock); return l_ret; -#undef m_ret_err } static int s_cell_file_atom_add(dap_chain_cell_t *a_cell, dap_chain_atom_ptr_t a_atom, uint64_t a_atom_size, char **a_atom_map) @@ -617,55 +479,38 @@ static int s_cell_file_atom_add(dap_chain_cell_t *a_cell, dap_chain_atom_ptr_t a off_t l_pos = !fseeko(a_cell->file_storage, 0, SEEK_END) ? ftello(a_cell->file_storage) : -1; dap_return_val_if_pass_err(l_pos < 0, -1, "Can't get \"%s : %s\" cell 0x%016"DAP_UINT64_FORMAT_X" size, error %d", a_cell->chain->net_name, a_cell->chain->name, a_cell->id, errno); - debug_if (s_debug_more, L_DEBUG, "Before filling volume for atom size %ld, stream pos of %s is %lu, map pos is %lu, space left in map %lu", - a_atom_size, a_cell->file_storage_path, l_pos, (size_t)(a_cell->map_pos - a_cell->map), (size_t)(a_cell->map_end - a_cell->map_pos)); - if ( a_atom_size + sizeof(uint64_t) > (size_t)(a_cell->map_end - a_cell->map_pos) ) + if ( a_atom_size + sizeof(uint64_t) > (size_t)(a_cell->mapping->volume->base + a_cell->mapping->volume->size - a_cell->mapping->cursor) ) dap_return_val_if_pass_err( - s_cell_map_new_volume(a_cell, (size_t)l_pos, false), + s_cell_map_new_volume(a_cell, l_pos, false), -2, "Failed to create new map volume for \"%s : %s\" cell 0x%016"DAP_UINT64_FORMAT_X"", a_cell->chain->net_name, a_cell->chain->name, a_cell->id ); } - - debug_if (s_debug_more && a_cell->chain->is_mapped, L_DEBUG, "Before writing an atom of size %lu, stream pos of %s is %ld and pos is %lu, space left in map %lu", - a_atom_size, a_cell->file_storage_path, ftello(a_cell->file_storage), - (size_t)(a_cell->map_pos - a_cell->map), (size_t)(a_cell->map_end - a_cell->map_pos)); dap_return_val_if_fail_err( fwrite(&a_atom_size, sizeof(a_atom_size), 1, a_cell->file_storage) == 1 && fwrite(a_atom, a_atom_size, 1, a_cell->file_storage) == 1, -3, "Can't write atom [%zu b] to \"%s : %s\" cell 0x%016"DAP_UINT64_FORMAT_X", error %d: \"%s\"", a_atom_size, a_cell->chain->net_name, a_cell->chain->name, a_cell->id, errno, dap_strerror(errno) ); - - debug_if (s_debug_more && a_cell->chain->is_mapped, L_DEBUG, "After writing an atom of size %lu, stream pos of %s is %lu and map shift is %lu", - a_atom_size, a_cell->file_storage_path, ftello(a_cell->file_storage), - (size_t)(a_cell->map_pos - a_cell->map)); fflush(a_cell->file_storage); if (a_cell->chain->is_mapped) { -#ifdef DAP_OS_DARWIN - if ( MAP_FAILED == (a_cell->map = mmap(a_cell->map, dap_page_roundup(DAP_MAPPED_VOLUME_LIMIT), PROT_READ, - MAP_PRIVATE|MAP_FIXED, fileno(a_cell->file_storage), a_cell->cur_vol_start)) ) { - log_it(L_ERROR, "Chain cell \"%s\" 0x%016"DAP_UINT64_FORMAT_X" cannot be remapped, errno %d", - a_cell->file_storage_path, a_cell->id.uint64, errno); - return -2; - } +#ifdef DAP_OS_DARWIN + a_cell->mapping->volume->base = mmap( a_cell->mapping->volume->base, a_cell->mapping->volume->size, + PROT_READ, MAP_PRIVATE | MAP_FIXED, fileno(a_cell->file_storage), + a_cell->mapping->volume->offset ); + dap_return_val_if_pass_err( a_cell->mapping->volume->base == MAP_FAILED, -2, + "Chain cell \"%s\" 0x%016"DAP_UINT64_FORMAT_X" cannot be remapped, errno %d", + a_cell->file_storage_path, a_cell->id.uint64, errno ); #elif defined DAP_OS_WINDOWS - off_t l_off = ftello(a_cell->file_storage); - LARGE_INTEGER SectionSize = (LARGE_INTEGER) { .QuadPart = l_off }; - HANDLE hSection = (HANDLE)a_cell->map_range_bounds->data; - NTSTATUS err = pfnNtExtendSection(hSection, &SectionSize); - if ( !NT_SUCCESS(err) ) { - log_it(L_ERROR, "NtExtendSection() failed, status %lx: \"%s\"", - err, dap_str_ntstatus(err) ); - return -2; - } + LARGE_INTEGER SectionSize = (LARGE_INTEGER) { .QuadPart = ftello(a_cell->file_storage) }; + NTSTATUS err = pfnNtExtendSection(a_cell->mapping->section, &SectionSize); + dap_return_val_if_fail_err( NT_SUCCESS(err), -2, "NtExtendSection() failed, status %lx: \"%s\"", err, dap_str_ntstatus(err) ); #endif /* Pass ptr to mapped area */ - if (a_atom_map) { - *a_atom_map = a_cell->map_pos += sizeof(uint64_t); - a_cell->map_pos += a_atom_size; - } + if (a_atom_map) + *a_atom_map = a_cell->mapping->cursor + sizeof(uint64_t); + a_cell->mapping->cursor += sizeof(uint64_t) + a_atom_size; } return 0; } @@ -688,7 +533,7 @@ int dap_chain_cell_file_append(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_ dap_chain_cell_t *l_cell = dap_chain_cell_capture_by_id(a_chain, a_cell_id); dap_return_val_if_fail_err(l_cell, -2, "Cell #%"DAP_UINT64_FORMAT_x" not found in chain \"%s : %s\"", a_cell_id, a_chain->net_name, a_chain->name); - pthread_rwlock_wrlock(&l_cell->storage_rwlock); + //pthread_rwlock_wrlock(&l_cell->storage_rwlock); int l_err = s_cell_file_atom_add(l_cell, a_atom, a_atom_size, a_atom_map); if (l_err) log_it(L_DEBUG, "Saved atom of size %zu bytes to chain \"%s : %s\", cell 0x%016"DAP_UINT64_FORMAT_X"", @@ -696,7 +541,7 @@ int dap_chain_cell_file_append(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_ else log_it(L_ERROR, "Noting saved to chain \"%s : %s\", cell 0x%016"DAP_UINT64_FORMAT_X", error %d", a_chain->net_name, a_chain->name, a_cell_id.uint64, l_err); - pthread_rwlock_unlock(&l_cell->storage_rwlock); + //pthread_rwlock_unlock(&l_cell->storage_rwlock); dap_chain_cell_remit(l_cell); return 0; } diff --git a/modules/chain/include/dap_chain.h b/modules/chain/include/dap_chain.h index 767b46442b..310fce8b26 100644 --- a/modules/chain/include/dap_chain.h +++ b/modules/chain/include/dap_chain.h @@ -97,6 +97,7 @@ typedef int (*dap_chain_callback_new_cfg_t)(dap_chain_t *, dap_config_t *); typedef void (*dap_chain_callback_ptr_t)(dap_chain_t *, void * ); typedef dap_chain_atom_verify_res_t (*dap_chain_callback_atom_t)(dap_chain_t *a_chain, dap_chain_atom_ptr_t a_atom, size_t a_atom_size, dap_hash_fast_t *a_atom_hash, bool a_atom_new); +typedef unsigned (*dap_chain_callback_atoms_t)(dap_chain_t*); typedef dap_chain_atom_ptr_t (*dap_chain_callback_atom_form_treshold_t)(dap_chain_t *, size_t *); typedef json_object *(*dap_chain_callback_atom_to_json)(json_object **a_arr_out, dap_chain_t *a_chain, dap_chain_atom_ptr_t a_atom, size_t a_atom_size, const char *a_hex_out_type); typedef dap_chain_atom_verify_res_t (*dap_chain_callback_atom_verify_t)(dap_chain_t *, dap_chain_atom_ptr_t , size_t, dap_hash_fast_t*); @@ -192,6 +193,8 @@ typedef struct dap_chain { pthread_rwlock_t cell_rwlock; + dap_chain_callback_atom_verify_t callback_atom_prefetch; + dap_chain_callback_atoms_t callback_atoms_prefetched_add; dap_chain_callback_atom_t callback_atom_add; dap_chain_callback_atom_form_treshold_t callback_atom_add_from_treshold; dap_chain_callback_atom_verify_t callback_atom_verify; @@ -273,11 +276,8 @@ typedef struct dap_chain_atom_confirmed_notifier { typedef struct dap_chain_pvt { char *file_storage_dir; - char *cs_name; - char *cs_type; + char *cs_name, *cs_type; bool cs_started; - bool need_reorder; - } dap_chain_pvt_t; #define DAP_CHAIN_PVT(a) ((dap_chain_pvt_t *)a->_pvt) @@ -298,17 +298,15 @@ void dap_chain_deinit(void); dap_chain_t *dap_chain_create(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); void dap_chain_set_cs_type(dap_chain_t *a_chain, const char *a_cs_type); -int dap_chain_purge(dap_chain_t *a_chain); int dap_chain_load_all(dap_chain_t *a_chain); -int dap_chain_save_all(dap_chain_t *a_chain); bool dap_chain_has_file_store(dap_chain_t *a_chain); dap_chain_t *dap_chain_find_by_id(dap_chain_net_id_t a_chain_net_id,dap_chain_id_t a_chain_id); dap_chain_t *dap_chain_load_from_cfg(const char *a_chain_net_name, dap_chain_net_id_t a_chain_net_id, dap_config_t *a_cfg); void dap_chain_info_dump_log(dap_chain_t *a_chain); -void dap_chain_delete(dap_chain_t * a_chain); +void dap_chain_delete(dap_chain_t *a_chain); void dap_chain_add_callback_notify(dap_chain_t *a_chain, dap_chain_callback_notify_t a_callback, dap_proc_thread_t *a_thread, void *a_arg); void dap_chain_add_callback_datum_index_notify(dap_chain_t *a_chain, dap_chain_callback_datum_notify_t a_callback, dap_proc_thread_t *a_thread, void *a_callback_arg); void dap_chain_add_callback_datum_removed_from_index_notify(dap_chain_t *a_chain, dap_chain_callback_datum_removed_notify_t a_callback, dap_proc_thread_t *a_thread, void *a_callback_arg); @@ -323,7 +321,7 @@ DAP_STATIC_INLINE bool dap_chain_get_atom_last_hash(dap_chain_t *a_chain, dap_ch { return dap_chain_get_atom_last_hash_num_ts(a_chain, a_cell_id, a_atom_hash, NULL, NULL); } -ssize_t dap_chain_atom_save(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id, const uint8_t *a_atom, size_t a_atom_size, dap_hash_fast_t *a_new_atom_hash); +int dap_chain_atom_save(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id, const uint8_t *a_atom, size_t a_atom_size, dap_hash_fast_t *a_new_atom_hash, char **a_atom_map); int dap_cert_chain_file_save(dap_chain_datum_t *datum, char *net_name); const char *dap_chain_type_to_str(dap_chain_type_t a_chain_type); diff --git a/modules/chain/include/dap_chain_cell.h b/modules/chain/include/dap_chain_cell.h index 618def9cc6..74efe15fdb 100644 --- a/modules/chain/include/dap_chain_cell.h +++ b/modules/chain/include/dap_chain_cell.h @@ -29,20 +29,15 @@ #include "dap_chain.h" #include "dap_chain_common.h" -typedef struct dap_chain_cell_mmap_data { - off_t vol_size; - char *map, *map_pos, **maps; -} dap_chain_cell_mmap_data_t; +typedef struct dap_chain_cell_mmap_data dap_chain_cell_mmap_data_t; typedef struct dap_chain_cell { dap_chain_cell_id_t id; - dap_chain_t * chain; - + dap_chain_t *chain; char file_storage_path[MAX_PATH]; - char *map, *map_pos, *map_end; + dap_chain_cell_mmap_data_t *mapping; FILE *file_storage; uint8_t file_storage_type; - dap_list_t *map_range_bounds; #ifdef DAP_OS_DARWIN size_t cur_vol_start; #endif @@ -100,5 +95,4 @@ void dap_chain_cell_close(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id); void dap_chain_cell_close_all(dap_chain_t *a_chain); int dap_chain_cell_file_append(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id, const void *a_atom, size_t a_atom_size, char **a_atom_map); -#define dap_chain_cell_file_update(a_cell) dap_chain_cell_file_append(a_cell, NULL, 0); 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 68677baf8d..a026bc1dc1 100644 --- a/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c +++ b/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c @@ -351,11 +351,7 @@ static int s_callback_new(dap_chain_t *a_chain, dap_config_t * a_chain_cfg) return -1; } 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_CRITICAL, "%s", c_error_memory_alloc); - return -1; - } + dap_chain_cs_dag_poa_t *l_poa = DAP_NEW_Z_RET_VAL_IF_FAIL(dap_chain_cs_dag_poa_t, -1); l_dag->_inheritor = l_poa; l_dag->callback_delete = s_callback_delete; l_dag->callback_cs_verify = s_callback_event_verify; @@ -687,7 +683,7 @@ static int s_callback_created(dap_chain_t * a_chain, dap_config_t *a_chain_net_c dap_chain_cs_dag_t * l_dag = DAP_CHAIN_CS_DAG ( a_chain ); dap_chain_cs_dag_poa_t * l_poa = DAP_CHAIN_CS_DAG_POA( l_dag ); - const char *l_events_sign_cert = = dap_config_get_item_str(a_chain_net_cfg,"dag-poa","events-sign-cert"); + const char *l_events_sign_cert = dap_config_get_item_str(a_chain_net_cfg,"dag-poa","events-sign-cert"); if ( l_events_sign_cert ) { if (!( PVT(l_poa)->events_sign_cert = dap_cert_find_by_name(l_events_sign_cert) )) log_it(L_ERROR,"Can't load events sign certificate, name \"%s\" is wrong", l_events_sign_cert); diff --git a/modules/ledger/dap_chain_ledger.c b/modules/ledger/dap_chain_ledger.c index 23414a6063..2b6b213fb9 100644 --- a/modules/ledger/dap_chain_ledger.c +++ b/modules/ledger/dap_chain_ledger.c @@ -971,7 +971,7 @@ void dap_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db) HASH_DEL(l_ledger_pvt->ledger_items, l_item_current); if (!is_ledger_mapped(l_ledger_pvt)) DAP_DELETE(l_item_current->tx); - DAP_DEL_Z(l_item_current); + DAP_DELETE(l_item_current); } if (!a_preserve_db) { l_gdb_group = dap_ledger_get_gdb_group(a_ledger, DAP_LEDGER_TXS_STR); @@ -983,8 +983,7 @@ void dap_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db) dap_ledger_wallet_balance_t *l_balance_current, *l_balance_tmp; HASH_ITER(hh, l_ledger_pvt->balance_accounts, l_balance_current, l_balance_tmp) { HASH_DEL(l_ledger_pvt->balance_accounts, l_balance_current); - DAP_DELETE(l_balance_current->key); - DAP_DELETE(l_balance_current); + DAP_DEL_MULTY(l_balance_current->key, l_balance_current); } if (!a_preserve_db) { l_gdb_group = dap_ledger_get_gdb_group(a_ledger, DAP_LEDGER_BALANCES_STR); @@ -1000,19 +999,12 @@ void dap_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db) pthread_rwlock_wrlock(&l_token_current->token_emissions_rwlock); HASH_ITER(hh, l_token_current->token_emissions, l_emission_current, l_emission_tmp) { HASH_DEL(l_token_current->token_emissions, l_emission_current); - DAP_DELETE(l_emission_current->datum_token_emission); - DAP_DEL_Z(l_emission_current); + DAP_DEL_MULTY(l_emission_current->datum_token_emission, l_emission_current); } pthread_rwlock_unlock(&l_token_current->token_emissions_rwlock); - DAP_DELETE(l_token_current->datum_token); - DAP_DELETE(l_token_current->auth_pkeys); - DAP_DELETE(l_token_current->auth_pkey_hashes); - DAP_DEL_Z(l_token_current->tx_recv_allow); - DAP_DEL_Z(l_token_current->tx_recv_block); - DAP_DEL_Z(l_token_current->tx_send_allow); - DAP_DEL_Z(l_token_current->tx_send_block); pthread_rwlock_destroy(&l_token_current->token_emissions_rwlock); - DAP_DELETE(l_token_current); + DAP_DEL_MULTY(l_token_current->datum_token, l_token_current->datum_token, l_token_current->auth_pkeys, l_token_current->auth_pkey_hashes, + l_token_current->tx_recv_allow, l_token_current->tx_recv_block, l_token_current->tx_send_allow, l_token_current->tx_send_block, l_token_current); } if (!a_preserve_db) { l_gdb_group = dap_ledger_get_gdb_group(a_ledger, DAP_LEDGER_TOKENS_STR); @@ -1040,7 +1032,7 @@ void dap_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db) HASH_DEL(l_ledger_pvt->threshold_txs, l_item_current); if (!is_ledger_mapped(l_ledger_pvt)) DAP_DELETE(l_item_current->tx); - DAP_DEL_Z(l_item_current); + DAP_DELETE(l_item_current); } l_ledger_pvt->ledger_items = NULL; diff --git a/modules/ledger/dap_chain_ledger_decree.c b/modules/ledger/dap_chain_ledger_decree.c index 94a51110c5..000b8e67e5 100644 --- a/modules/ledger/dap_chain_ledger_decree.c +++ b/modules/ledger/dap_chain_ledger_decree.c @@ -71,7 +71,7 @@ static int s_decree_clear(dap_ledger_t *a_ledger) void dap_ledger_decree_purge(dap_ledger_t *a_ledger) { s_decree_clear(a_ledger); - dap_ledger_decree_create(a_ledger); + //dap_ledger_decree_create(a_ledger); } static int s_decree_verify(dap_chain_net_t *a_net, dap_chain_datum_decree_t *a_decree, size_t a_data_size, dap_chain_hash_fast_t *a_decree_hash, bool a_anchored) diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c index 7406a88203..72ea0e13f2 100644 --- a/modules/net/dap_chain_net.c +++ b/modules/net/dap_chain_net.c @@ -220,7 +220,7 @@ static bool s_net_states_proc(void *a_arg); static void s_net_states_notify(dap_chain_net_t * l_net); static void s_nodelist_change_notify(dap_store_obj_t *a_obj, void *a_arg); //static void s_net_proc_kill( dap_chain_net_t * a_net ); -static int s_chains_init_all(const char *a_netname, const char *a_path, int *a_ledger_flags); +static int s_chains_init_all(dap_chain_net_t *a_net, const char *a_path, uint16_t *a_ledger_flags); static int s_net_init(const char *a_net_name, const char *a_path, uint16_t a_acl_idx); static void *s_net_load(void *a_arg); static int s_net_try_online(dap_chain_net_t *a_net); @@ -904,21 +904,34 @@ void s_set_reply_text_node_status(void **a_str_reply, dap_chain_net_t * a_net){ * @return true * @return false */ -void dap_chain_net_purge(dap_chain_net_t *l_net) +void dap_chain_net_purge(dap_chain_net_t *a_net) { - dap_chain_srv_purge_all(l_net->pub.id); - dap_ledger_purge(l_net->pub.ledger, false); - dap_chain_t *l_chain = NULL; - DL_FOREACH(l_net->pub.chains, l_chain) { - dap_chain_purge(l_chain); - dap_chain_load_all(l_chain); - l_net->pub.fee_value = uint256_0; - l_net->pub.fee_addr = c_dap_chain_addr_blank; + dap_chain_net_pvt_t *l_pvt = PVT(a_net); + dap_global_db_cluster_t *l_mempool = l_pvt->mempool_clusters; + while (l_mempool) { + dap_global_db_cluster_t *l_next = l_mempool->next; + dap_global_db_cluster_delete(l_mempool); + l_mempool = l_next; } - 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)) - debug_if(s_debug_more, L_DEBUG, "Added atom from treshold"); + dap_global_db_cluster_delete(l_pvt->orders_cluster); + dap_global_db_cluster_delete(l_pvt->nodes_cluster); + dap_global_db_cluster_delete(l_pvt->nodes_states); + dap_global_db_cluster_delete(l_pvt->common_orders); + struct block_reward *l_reward, *l_tmp; + DL_FOREACH_SAFE(l_pvt->rewards, l_reward, l_tmp) { + DL_DELETE(l_pvt->rewards, l_reward); + DAP_DELETE(l_reward); + } + dap_chain_srv_purge_all(a_net->pub.id); + if (a_net->pub.ledger) { + dap_ledger_purge(a_net->pub.ledger, false); + dap_ledger_handle_free(a_net->pub.ledger); + } + if (a_net->pub.chains) { + dap_chain_t *l_chain = NULL, *l_tmp = NULL; + DL_FOREACH_SAFE(a_net->pub.chains, l_chain, l_tmp) { + DL_DELETE(a_net->pub.chains, l_chain); + dap_chain_delete(l_chain); } } } @@ -1753,36 +1766,15 @@ void dap_chain_net_deinit() */ void dap_chain_net_delete(dap_chain_net_t *a_net) { - // Synchronously going to offline state - PVT(a_net)->state = PVT(a_net)->state_target = NET_STATE_OFFLINE; - s_net_states_proc(a_net); - dap_global_db_cluster_t *l_mempool = PVT(a_net)->mempool_clusters; - while (l_mempool) { - dap_global_db_cluster_t *l_next = l_mempool->next; - dap_global_db_cluster_delete(l_mempool); - l_mempool = l_next; - } - dap_global_db_cluster_delete(PVT(a_net)->orders_cluster); - dap_global_db_cluster_delete(PVT(a_net)->nodes_cluster); - dap_global_db_cluster_delete(PVT(a_net)->nodes_states); - dap_global_db_cluster_delete(PVT(a_net)->common_orders); - - DAP_DELETE(PVT(a_net)->node_info); - if (a_net->pub.ledger) { - dap_ledger_purge(a_net->pub.ledger, true); - dap_ledger_handle_free(a_net->pub.ledger); - } - if (a_net->pub.chains) { - dap_chain_t - *l_cur = NULL, - *l_tmp = NULL; - DL_FOREACH_SAFE(a_net->pub.chains, l_cur, l_tmp) { - DL_DELETE(a_net->pub.chains, l_cur); - dap_chain_delete(l_cur); - } - } + dap_chain_net_pvt_t *l_pvt = PVT(a_net); + dap_chain_net_purge(a_net); + DAP_DEL_ARRAY(l_pvt->permanent_links_hosts, l_pvt->permanent_links_hosts_count); + DAP_DEL_ARRAY(l_pvt->seed_nodes_hosts, l_pvt->seed_nodes_count); + DAP_DEL_MULTY(l_pvt->permanent_links_hosts, l_pvt->seed_nodes_hosts, l_pvt->permanent_links_addrs, l_pvt->node_info); + // TODO: delete sync_timer and whatever else is initialized AFTER chains load HASH_DEL(s_nets_by_name, a_net); HASH_DELETE(hh2, s_nets_by_id, a_net); + dap_config_close(a_net->pub.config); DAP_DELETE(a_net); } @@ -1831,7 +1823,7 @@ static int s_nodes_hosts_init(dap_chain_net_t *a_net, dap_config_t *a_cfg, const return 0; } -static int s_chains_init_all(dap_chain_net_t *a_net, const char *a_path, int *a_ledger_flags) { +static int s_chains_init_all(dap_chain_net_t *a_net, const char *a_path, uint16_t *a_ledger_flags) { DIR *l_chains_dir = opendir(a_path); if (!l_chains_dir) return log_it(L_ERROR, "Can't find any chains for network %s", a_net->pub.name), -1; @@ -1903,6 +1895,56 @@ static int s_chains_init_all(dap_chain_net_t *a_net, const char *a_path, int *a_ return 0; } +int s_chain_net_preload(dap_chain_net_t *a_net) { + // Services register & configure + dap_chain_srv_start(a_net->pub.id, DAP_CHAIN_NET_SRV_XCHANGE_LITERAL, NULL); // Harcoded core service starting for exchange capability + dap_chain_srv_start(a_net->pub.id, DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_LITERAL, NULL); // Harcoded core service starting for delegated keys storage + char *l_services_path = dap_strdup_printf("%s/network/%s/services", dap_config_path(), a_net->pub.name); + DIR *l_service_cfg_dir = opendir(l_services_path); + DAP_DELETE(l_services_path); + if (l_service_cfg_dir) { + for ( struct dirent *l_dir_entry; ( l_dir_entry = readdir(l_service_cfg_dir) ); ) { + const char *l_entry_name = l_dir_entry->d_name; + size_t l_entry_len = strlen(l_entry_name); + if (l_entry_len < 4 || // It has non zero name excluding file extension + strncmp(l_entry_name + l_entry_len - 4, ".cfg", 4) != 0) // its not a .cfg file + continue; + log_it(L_DEBUG, "Opening service config \"%s\"...", l_entry_name); + char *l_service_cfg_path = dap_strdup_printf("network/%s/services/%s", a_net->pub.name, l_entry_name); + dap_config_t *l_cfg_new = dap_config_open(l_service_cfg_path); + if (l_cfg_new) { + char l_service_name[l_entry_len - 3]; + dap_strncpy(l_service_name, l_entry_name, l_entry_len - 4); + dap_chain_srv_start(a_net->pub.id, l_service_name, l_cfg_new); + dap_config_close(l_cfg_new); + } + DAP_DELETE(l_service_cfg_path); + } + closedir(l_service_cfg_dir); + } + uint16_t l_ledger_flags = 0; + switch ( PVT( a_net )->node_role.enums ) { + case NODE_ROLE_LIGHT: + //break; + PVT( a_net )->node_role.enums = NODE_ROLE_FULL; // TODO: implement light mode + case NODE_ROLE_FULL: + l_ledger_flags |= DAP_LEDGER_CHECK_LOCAL_DS; + if (dap_config_get_item_bool_default(g_config, "ledger", "cache_enabled", false)) + l_ledger_flags |= DAP_LEDGER_CACHE_ENABLED; + default: + l_ledger_flags |= DAP_LEDGER_CHECK_CELLS_DS | DAP_LEDGER_CHECK_TOKEN_EMISSION; + } + if (dap_config_get_item_bool_default(g_config, "ledger", "mapped", true)) + l_ledger_flags |= DAP_LEDGER_MAPPED; + + int l_res = s_chains_init_all(a_net, a_net->pub.config->path, &l_ledger_flags); + if (!l_res) + a_net->pub.ledger = dap_ledger_create(a_net, l_ledger_flags); + + return l_res; + +} + /** * @brief load network config settings from cellframe-node.cfg file * @@ -1913,8 +1955,7 @@ static int s_chains_init_all(dap_chain_net_t *a_net, const char *a_path, int *a_ int s_net_init(const char *a_net_name, const char *a_path, uint16_t a_acl_idx) { dap_config_t *l_cfg = dap_config_open(a_path); - if (!l_cfg) - return log_it(L_ERROR,"Can't open default network config %s", a_path), -1; + dap_return_val_if_fail_err(l_cfg, -1, "Can't open default network config %s", a_path); dap_chain_net_t *l_net = s_net_new(a_net_name, l_cfg); if ( !l_net ) @@ -1951,65 +1992,17 @@ int s_net_init(const char *a_net_name, const char *a_path, uint16_t a_acl_idx) || ( !l_net_pvt->seed_nodes_count && s_nodes_hosts_init(l_net, l_cfg, "bootstrap_hosts", &l_net_pvt->seed_nodes_hosts, &l_net_pvt->seed_nodes_count) ) ) { dap_chain_net_delete(l_net); - dap_config_close(l_cfg); return -4; } - if (!l_net_pvt->seed_nodes_count) + if ( !l_net_pvt->seed_nodes_count ) log_it(L_WARNING, "Can't read seed nodes addresses, work with local balancer only"); - // Get list chains name for enabled debug mode - if ( dap_server_enabled() && ( l_net_pvt->node_info->ext_port = dap_config_get_item_uint16(g_config, "server", "ext_port") )) log_it(L_INFO, "Set external port %u for adding in node list", l_net_pvt->node_info->ext_port); - // Services register & configure - dap_chain_srv_start(l_net->pub.id, DAP_CHAIN_NET_SRV_XCHANGE_LITERAL, NULL); // Harcoded core service starting for exchange capability - dap_chain_srv_start(l_net->pub.id, DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_LITERAL, NULL); // Harcoded core service starting for delegated keys storage - char *l_services_path = dap_strdup_printf("%s/network/%s/services", dap_config_path(), l_net->pub.name); - DIR *l_service_cfg_dir = opendir(l_services_path); - DAP_DELETE(l_services_path); - if (l_service_cfg_dir) { - for ( struct dirent *l_dir_entry; ( l_dir_entry = readdir(l_service_cfg_dir) ); ) { - const char *l_entry_name = l_dir_entry->d_name; - size_t l_entry_len = strlen(l_entry_name); - if (l_entry_len < 4 || // It has non zero name excluding file extension - strncmp(l_entry_name + l_entry_len - 4, ".cfg", 4) != 0) // its not a .cfg file - continue; - log_it(L_DEBUG, "Opening service config \"%s\"...", l_entry_name); - char *l_service_cfg_path = dap_strdup_printf("network/%s/services/%s", l_net->pub.name, l_entry_name); - dap_config_t *l_cfg_new = dap_config_open(l_service_cfg_path); - if (l_cfg_new) { - char l_service_name[l_entry_len - 3]; - dap_strncpy(l_service_name, l_entry_name, l_entry_len - 4); - dap_chain_srv_start(l_net->pub.id, l_service_name, l_cfg_new); - dap_config_close(l_cfg_new); - } - DAP_DELETE(l_service_cfg_path); - } - closedir(l_service_cfg_dir); - } - uint16_t l_ledger_flags = 0; - switch ( PVT( l_net )->node_role.enums ) { - case NODE_ROLE_LIGHT: - //break; - PVT( a_net )->node_role.enums = NODE_ROLE_FULL; // TODO: implement light mode - case NODE_ROLE_FULL: - l_ledger_flags |= DAP_LEDGER_CHECK_LOCAL_DS; - if (dap_config_get_item_bool_default(g_config, "ledger", "cache_enabled", false)) - l_ledger_flags |= DAP_LEDGER_CACHE_ENABLED; - default: - l_ledger_flags |= DAP_LEDGER_CHECK_CELLS_DS | DAP_LEDGER_CHECK_TOKEN_EMISSION; - } - if (dap_config_get_item_bool_default(g_config, "ledger", "mapped", true)) - l_ledger_flags |= DAP_LEDGER_MAPPED; + int l_ret = s_chain_net_preload(l_net); + return l_ret ? dap_chain_net_delete(l_net), l_ret : 0; - int l_res = s_chains_init_all(l_net, a_path, &l_ledger_flags); - if ( l_res ) - return dap_chain_net_delete(l_net), l_res; - - // init LEDGER model - l_net->pub.ledger = dap_ledger_create(l_net, l_ledger_flags); - return 0; } static void *s_net_load(void *a_arg) @@ -2024,28 +2017,7 @@ static void *s_net_load(void *a_arg) DL_FOREACH(l_net->pub.chains, l_chain) { l_net->pub.fee_value = uint256_0; l_net->pub.fee_addr = c_dap_chain_addr_blank; - if ( !dap_chain_load_all(l_chain) ) { - if ( DAP_CHAIN_PVT(l_chain)->need_reorder ) // # unsafe crutch, need to escape reorder usage - { - log_it(L_DAP, "Reordering chain files for chain %s", l_chain->name); - 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"); - } - dap_chain_save_all(l_chain); - - DAP_CHAIN_PVT(l_chain)->need_reorder = false; - dap_chain_purge(l_chain); - dap_ledger_purge(l_net->pub.ledger, false); - l_net->pub.fee_value = uint256_0; - l_net->pub.fee_addr = c_dap_chain_addr_blank; - dap_chain_load_all(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"); - } - } + int l_ret = dap_chain_load_all(l_chain); l_chain->atom_num_last = 0; switch ( l_net_pvt->node_role.enums ) { case NODE_ROLE_ROOT_MASTER: @@ -2066,7 +2038,7 @@ static void *s_net_load(void *a_arg) l_chain->is_datum_pool_proc = ( !dap_chain_id_parse(l_proc_chains[k], &l_chain_id) && (l_chain->id.uint64 == l_chain_id.uint64) ); } break; default: break; - + } // Personal chain mempool cluster for each chain snprintf(l_gdb_groups_mask, sizeof(l_gdb_groups_mask), "%s.chain-%s.mempool", l_net->pub.gdb_groups_prefix, l_chain->name); @@ -2082,7 +2054,7 @@ static void *s_net_load(void *a_arg) l_net_pvt->mempool_clusters = l_cluster; } dap_ledger_load_end(l_net->pub.ledger); - log_it(L_INFO, "Node role \"%s\" established in net %s", dap_chain_node_role_to_str(l_net_pvt->node_role.enums), l_net->pub.name); + log_it(L_INFO, "Node role \"%s\" established in net %s", dap_chain_node_role_to_str(l_net_pvt->node_role), l_net->pub.name); l_net_pvt->state_target = NET_STATE_OFFLINE; // Init GlobalDB clusters for service and nodes (with aliases) @@ -2103,7 +2075,7 @@ static void *s_net_load(void *a_arg) l_gdb_groups_mask, 0, true, DAP_GDB_MEMBER_ROLE_USER, DAP_CLUSTER_TYPE_EMBEDDED); - dap_return_val_if_fail_err(l_net_pvt->common_orders, NULL, "Net \"%s\" loading error %d: can't initialize common orders cluster" + dap_return_val_if_fail_err(l_net_pvt->common_orders, NULL, "Net \"%s\" loading error %d: can't initialize common orders cluster", l_net->pub.name, -4); dap_chain_net_add_auth_nodes_to_cluster(l_net, l_net_pvt->common_orders); // Node states cluster @@ -2113,7 +2085,7 @@ static void *s_net_load(void *a_arg) l_gdb_groups_mask, DAP_CHAIN_NET_NODES_TTL, true, DAP_GDB_MEMBER_ROLE_USER, DAP_CLUSTER_TYPE_EMBEDDED); - dap_return_val_if_fail_err(l_net_pvt->nodes_states, NULL, "Net \"%s\" loading error %d: can't initialize node states cluster" + dap_return_val_if_fail_err(l_net_pvt->nodes_states, NULL, "Net \"%s\" loading error %d: can't initialize node states cluster", l_net->pub.name, -5); // Nodes and its aliases cluster snprintf(l_net->pub.gdb_nodes, sizeof(l_net->pub.gdb_nodes), "%s.%s", l_net->pub.gdb_groups_prefix, s_gdb_nodes_postfix); @@ -2122,7 +2094,7 @@ static void *s_net_load(void *a_arg) l_net->pub.gdb_nodes, 7200, true, DAP_GDB_MEMBER_ROLE_GUEST, DAP_CLUSTER_TYPE_EMBEDDED); - dap_return_val_if_fail_err(l_net_pvt->nodes_cluster, NULL, "Net \"%s\" loading error %d: can't initialize nodes cluster" + dap_return_val_if_fail_err(l_net_pvt->nodes_cluster, NULL, "Net \"%s\" loading error %d: can't initialize nodes cluster", l_net->pub.name, -6); dap_chain_net_add_auth_nodes_to_cluster(l_net, l_net_pvt->nodes_cluster); dap_chain_net_add_nodelist_notify_callback(l_net, s_nodelist_change_notify, l_net); @@ -2144,7 +2116,7 @@ static void *s_net_load(void *a_arg) // TODO rework alias concept const char * l_node_addr_type = dap_config_get_item_str_default(l_net->pub.config , "general", "node_addr_type", "auto"); - if (!dap_strcmp(l_node_addr_type, "static")) { + if ( !dap_strcmp(l_node_addr_type, "static") ) { const char *l_node_alias_str = dap_config_get_item_str_default(l_net->pub.config, "general", "node-addr", dap_config_get_item_str(l_net->pub.config, "general", "node-alias")); @@ -2160,7 +2132,7 @@ static void *s_net_load(void *a_arg) l_net_pvt->sync_context.sync_idle_time = dap_config_get_item_uint32_default(g_config, "chain", "sync_idle_time", 60); dap_proc_thread_timer_add(NULL, s_sync_timer_callback, l_net, c_sync_timer_period); - + // TODO! Delete the timer in "purge()" log_it(L_INFO, "Network \"%s\" initialized", l_net->pub.name); l_net_pvt->state = NET_STATE_OFFLINE; return l_net; @@ -2802,11 +2774,7 @@ int dap_chain_net_add_reward(dap_chain_net_t *a_net, uint256_t a_reward, uint64_ log_it(L_ERROR, "Can't add retrospective reward for block"); return -2; } - struct block_reward *l_new_reward = DAP_NEW_Z(struct block_reward); - if (!l_new_reward) { - log_it(L_CRITICAL, "Out of memory"); - return -3; - } + struct block_reward *l_new_reward = DAP_NEW_Z_RET_VAL_IF_FAIL(struct block_reward, -3); l_new_reward->block_number = a_block_num; l_new_reward->reward = a_reward; // Place new reward at begining @@ -3279,18 +3247,14 @@ DAP_INLINE dap_chain_net_state_t dap_chain_net_get_target_state(dap_chain_net_t bool dap_chain_net_stop(dap_chain_net_t *a_net) { int l_attempts_count = 0; - bool l_ret = false; - if (dap_chain_net_get_target_state(a_net) == NET_STATE_ONLINE) { - dap_chain_net_state_go_to(a_net, NET_STATE_OFFLINE); - l_ret = true; - } else if (dap_chain_net_get_state(a_net) != NET_STATE_OFFLINE) { + if ( dap_chain_net_get_target_state(a_net) == NET_STATE_ONLINE || dap_chain_net_get_state(a_net) != NET_STATE_OFFLINE ) dap_chain_net_state_go_to(a_net, NET_STATE_OFFLINE); + + while (dap_chain_net_get_state(a_net) != NET_STATE_OFFLINE && l_attempts_count++ < 5) { + sched_yield(); + sleep(1); } - while (dap_chain_net_get_state(a_net) != NET_STATE_OFFLINE && l_attempts_count++ < 5) { sleep(1); } - if (dap_chain_net_get_state(a_net) != NET_STATE_OFFLINE) { - log_it(L_ERROR, "Can't stop net %s", a_net->pub.name); - } - return l_ret; + return dap_chain_net_get_state(a_net) == NET_STATE_OFFLINE; } /*------------------------------------State machine block end---------------------------------*/ diff --git a/modules/service/datum/dap_chain_net_srv_datum.c b/modules/service/datum/dap_chain_net_srv_datum.c index 768e158fb1..25eb125b06 100644 --- a/modules/service/datum/dap_chain_net_srv_datum.c +++ b/modules/service/datum/dap_chain_net_srv_datum.c @@ -221,7 +221,7 @@ void s_order_notficator(dap_store_obj_t *a_obj, void *a_arg) dap_chain_net_srv_price_t *l_price = NULL; if ((l_order->price_unit.uint32 != SERV_UNIT_PCS) || (l_order->direction != SERV_DIR_BUY) || - (strncmp(l_order->price_ticker, l_price->token, DAP_CHAIN_TICKER_SIZE_MAX)) || + (dap_strncmp(l_order->price_ticker, l_price->token, DAP_CHAIN_TICKER_SIZE_MAX)) || (!compare256(l_order->price, l_price->value_datoshi))) { char *l_balance_order = dap_chain_balance_coins_print(l_order->price); char *l_balance_service = dap_chain_balance_coins_print(l_price->value_datoshi); diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c index 8c67acdacd..9bd233b211 100644 --- a/modules/type/blocks/dap_chain_cs_blocks.c +++ b/modules/type/blocks/dap_chain_cs_blocks.c @@ -1560,9 +1560,8 @@ static int s_add_atom_datums(dap_chain_cs_blocks_t *a_blocks, dap_chain_block_ca pthread_rwlock_wrlock(&PVT(a_blocks)->datums_rwlock); HASH_ADD(hh, PVT(a_blocks)->datum_index, datum_hash, sizeof(*l_datum_hash), l_datum_index); pthread_rwlock_unlock(&PVT(a_blocks)->datums_rwlock); - dap_chain_cell_t *l_cell = dap_chain_cell_capture_by_id(a_blocks->chain, a_blocks->chain->active_cell_id); - dap_chain_datum_notify(l_cell, l_datum_hash, &l_datum_index->block_cache->block_hash, (byte_t *)l_datum, l_datum_size, l_res, l_datum_index_data.action, l_datum_index_data.uid); - dap_chain_cell_remit(l_cell); + dap_chain_datum_notify(a_blocks->chain, a_block_cache->block->hdr.cell_id, l_datum_hash, &l_datum_index->block_cache->block_hash, + (byte_t*)l_datum, l_datum_size, l_res, l_datum_index_data.action, l_datum_index_data.uid); } } debug_if(s_debug_more, L_DEBUG, "Block %s checked, %s", a_block_cache->block_hash_str, @@ -1595,9 +1594,7 @@ static int s_delete_atom_datums(dap_chain_cs_blocks_t *a_blocks, dap_chain_block l_ret++; HASH_DEL(PVT(a_blocks)->datum_index, l_datum_index); // notify datum removed - dap_chain_cell_t *l_cell = dap_chain_cell_capture_by_id(a_blocks->chain, a_blocks->chain->active_cell_id); - dap_chain_datum_removed_notify(l_cell, l_datum_hash); - dap_chain_cell_remit(l_cell); + dap_chain_datum_removed_notify(a_blocks->chain, a_block_cache->block->hdr.cell_id, l_datum_hash); } } debug_if(s_debug_more, L_DEBUG, "Block %s checked, %s", a_block_cache->block_hash_str, @@ -1618,7 +1615,7 @@ static void s_add_atom_to_blocks(dap_chain_cs_blocks_t *a_blocks, dap_chain_bloc } -static bool s_select_longest_branch(dap_chain_cs_blocks_t * a_blocks, dap_chain_block_cache_t * a_bcache, uint64_t a_main_branch_length, dap_chain_cell_t *a_cell) +static bool s_select_longest_branch(dap_chain_cs_blocks_t * a_blocks, dap_chain_block_cache_t * a_bcache, uint64_t a_main_branch_length) { dap_chain_cs_blocks_t * l_blocks = a_blocks; if (!a_blocks){ @@ -1683,7 +1680,7 @@ static bool s_select_longest_branch(dap_chain_cs_blocks_t * a_blocks, dap_chain_ HASH_ADD(hh, PVT(l_blocks)->blocks, block_hash, sizeof(l_curr_atom->block_hash), l_curr_atom); debug_if(s_debug_more, L_DEBUG, "Verified atom %p: ACCEPTED", l_curr_atom); s_add_atom_datums(l_blocks, l_curr_atom); - dap_chain_atom_notify(a_cell, &l_curr_atom->block_hash, (byte_t*)l_curr_atom->block, l_curr_atom->block_size); + dap_chain_atom_notify(a_blocks->chain, l_curr_atom->block->hdr.cell_id, &l_curr_atom->block_hash, (byte_t*)l_curr_atom->block, l_curr_atom->block_size); HASH_DEL(new_main_branch, l_item); } // Next we save pointer to new forked branch (former main branch) instead of it @@ -1718,24 +1715,15 @@ static dap_chain_atom_verify_res_t s_callback_atom_add(dap_chain_t * a_chain, da case ATOM_ACCEPT:{ dap_chain_net_t *l_net = dap_chain_net_by_id(a_chain->net_id); assert(l_net); - dap_chain_cell_t *l_cell = dap_chain_cell_capture_by_id(a_chain, l_block->hdr.cell_id); #ifndef DAP_CHAIN_BLOCKS_TEST if ( !dap_chain_net_get_load_mode(l_net) ) { - if ( (ret = dap_chain_atom_save(l_cell, a_atom, a_atom_size, a_atom_new ? &l_block_hash : NULL)) < 0 ) { - log_it(L_ERROR, "Can't save atom to file, code %d", ret); - return ATOM_REJECT; - } else if (a_chain->is_mapped) { - l_block = (dap_chain_block_t*)( l_cell->map_pos += sizeof(uint64_t) ); // Switching to mapped area - l_cell->map_pos += a_atom_size; - } - ret = ATOM_ACCEPT; + int l_err = dap_chain_atom_save(a_chain, l_block->hdr.cell_id, a_atom, a_atom_size, a_atom_new ? &l_block_hash : NULL, (char**)&l_block); + dap_return_val_if_pass_err(l_err, ATOM_REJECT, "Can't save atom to file, code %d", l_err); } #endif l_block_cache = dap_chain_block_cache_new(&l_block_hash, l_block, a_atom_size, PVT(l_blocks)->blocks_count + 1, !a_chain->is_mapped); - if (!l_block_cache) { - log_it(L_DEBUG, "%s", "... corrupted block"); - return ATOM_REJECT; - } + dap_return_val_if_fail_err(l_block_cache, dap_chain_net_get_load_mode(l_net) ? ATOM_CORRUPTED : ATOM_REJECT, + "Block %s is corrupted!", l_block_cache->block_hash_str); debug_if(s_debug_more, L_DEBUG, "... new block %s", l_block_cache->block_hash_str); pthread_rwlock_wrlock(& PVT(l_blocks)->rwlock); @@ -1746,7 +1734,7 @@ static dap_chain_atom_verify_res_t s_callback_atom_add(dap_chain_t * a_chain, da HASH_ADD(hh, PVT(l_blocks)->blocks, block_hash, sizeof(l_block_cache->block_hash), l_block_cache); debug_if(s_debug_more, L_DEBUG, "Verified atom %p: ACCEPTED", a_atom); s_add_atom_datums(l_blocks, l_block_cache); - dap_chain_atom_notify(l_cell, &l_block_cache->block_hash, (byte_t*)l_block, a_atom_size); + dap_chain_atom_notify(a_chain, l_block->hdr.cell_id, &l_block_cache->block_hash, (byte_t*)l_block, a_atom_size); dap_chain_atom_add_from_threshold(a_chain); pthread_rwlock_unlock(&PVT(l_blocks)->rwlock); @@ -1772,8 +1760,6 @@ static dap_chain_atom_verify_res_t s_callback_atom_add(dap_chain_t * a_chain, da #endif return ATOM_ACCEPT; } - - for (size_t i = 0; i < PVT(l_blocks)->forked_br_cnt; i++){ dap_chain_block_forked_branch_t *l_cur_branch = PVT(l_blocks)->forked_branches[i]; dap_chain_block_forked_branch_atoms_table_t *l_last = HASH_LAST(l_cur_branch->forked_branch_atoms); @@ -1788,7 +1774,7 @@ static dap_chain_atom_verify_res_t s_callback_atom_add(dap_chain_t * a_chain, da l_block_cache->block_number = l_last->block_cache->block_number + 1; HASH_ADD(hh, l_cur_branch->forked_branch_atoms, block_hash, sizeof(dap_hash_fast_t), l_new_item); uint64_t l_main_branch_length = PVT(l_blocks)->blocks_count - l_cur_branch->connected_block->block_number; - if (s_select_longest_branch(l_blocks, l_cur_branch->connected_block, l_main_branch_length, l_cell)){ + if ( s_select_longest_branch(l_blocks, l_cur_branch->connected_block, l_main_branch_length) ) { dap_chain_block_cache_t *l_bcache_last = HASH_LAST(PVT(l_blocks)->blocks); // Send it to notificator listeners #ifndef DAP_CHAIN_BLOCKS_TEST @@ -1818,7 +1804,7 @@ static dap_chain_atom_verify_res_t s_callback_atom_add(dap_chain_t * a_chain, da ++PVT(l_blocks)->blocks_count; debug_if(s_debug_more, L_DEBUG, "Verified atom %p: ACCEPTED", a_atom); s_add_atom_datums(l_blocks, l_block_cache); - dap_chain_atom_notify(l_cell, &l_block_cache->block_hash, (byte_t*)l_block, a_atom_size); + dap_chain_atom_notify(a_chain, l_block->hdr.cell_id, &l_block_cache->block_hash, (byte_t*)l_block, a_atom_size); dap_chain_atom_add_from_threshold(a_chain); pthread_rwlock_unlock(&PVT(l_blocks)->rwlock); return ret; @@ -1843,15 +1829,8 @@ static dap_chain_atom_verify_res_t s_callback_atom_add(dap_chain_t * a_chain, da case ATOM_FORK:{ #ifndef DAP_CHAIN_BLOCKS_TEST if ( !dap_chain_net_get_load_mode( dap_chain_net_by_id(a_chain->net_id)) ) { - dap_chain_cell_t *l_cell = dap_chain_cell_capture_by_id(a_chain, l_block->hdr.cell_id); - if ( (ret = dap_chain_atom_save(l_cell, a_atom, a_atom_size, a_atom_new ? &l_block_hash : NULL)) < 0 ) { - log_it(L_ERROR, "Can't save atom to file, code %d", ret); - return ATOM_REJECT; - } else if (a_chain->is_mapped) { - l_block = (dap_chain_block_t*)( l_cell->map_pos += sizeof(uint64_t) ); // Switching to mapped area - l_cell->map_pos += a_atom_size; - } - dap_chain_cell_remit(l_cell); + int l_err = dap_chain_atom_save(a_chain, l_block->hdr.cell_id, a_atom, a_atom_size, a_atom_new ? &l_block_hash : NULL, (char**)&l_block); + dap_return_val_if_pass_err(l_err, ATOM_REJECT, "Can't save atom to file, code %d", l_err); ret = ATOM_FORK; } #endif @@ -1892,6 +1871,9 @@ static dap_chain_atom_verify_res_t s_callback_atom_add(dap_chain_t * a_chain, da case ATOM_PASS: debug_if(s_debug_more, L_DEBUG, "... %s is already present", dap_chain_hash_fast_to_str_static(&l_block_hash)); break; + case ATOM_CORRUPTED: + debug_if(s_debug_more, L_DEBUG, "... atom is corrupted.%s", dap_chain_net_get_load_mode(dap_chain_net_by_id(a_chain->net_id)) + ? " The file will be truncated!" : ""); default: debug_if(s_debug_more, L_DEBUG, "Unknown verification ret code %d", ret); break; @@ -1909,6 +1891,7 @@ static dap_chain_atom_verify_res_t s_callback_atom_add(dap_chain_t * a_chain, da static dap_chain_atom_verify_res_t s_callback_atom_verify(dap_chain_t *a_chain, dap_chain_atom_ptr_t a_atom, size_t a_atom_size, dap_chain_hash_fast_t *a_atom_hash) { dap_return_val_if_fail(a_chain && a_atom && a_atom_size && a_atom_hash, ATOM_REJECT); + bool l_load_mode = dap_chain_net_get_load_mode(dap_chain_net_by_id(a_chain->net_id)); dap_chain_cs_blocks_t * l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain); assert(l_blocks); dap_chain_cs_blocks_pvt_t *l_blocks_pvt = PVT(l_blocks); @@ -1917,14 +1900,14 @@ static dap_chain_atom_verify_res_t s_callback_atom_verify(dap_chain_t *a_chain, dap_chain_hash_fast_t l_block_hash = *a_atom_hash; if (sizeof(l_block->hdr) >= a_atom_size) { - log_it(L_WARNING, "Size of block %s is %zd that is equal or less then block's header size %zd", + log_it(L_WARNING, "Block %s size %zd <= block header size %zd", dap_hash_fast_to_str_static(a_atom_hash), a_atom_size, sizeof(l_block->hdr)); - return ATOM_REJECT; + return l_load_mode ? ATOM_CORRUPTED : ATOM_REJECT; } size_t l_offset = dap_chain_block_get_sign_offset(l_block, a_atom_size); if (!l_offset) { log_it(L_WARNING, "Block %s with size %zu parsing error", dap_hash_fast_to_str_static(a_atom_hash), a_atom_size); - return ATOM_REJECT; + return l_load_mode ? ATOM_CORRUPTED : ATOM_REJECT; } if ((l_block->hdr.version >= 2 || /* Old bug, crutch for it */ l_block->hdr.meta_n_datum_n_signs_size != l_offset) && l_block->hdr.meta_n_datum_n_signs_size + sizeof(l_block->hdr) != a_atom_size) { @@ -1934,7 +1917,7 @@ static dap_chain_atom_verify_res_t s_callback_atom_verify(dap_chain_t *a_chain, if (!l_hash_found) { log_it(L_WARNING, "Incorrect size %zu of block %s, expected %zu", l_block->hdr.meta_n_datum_n_signs_size + sizeof(l_block->hdr), dap_hash_fast_to_str_static(a_atom_hash), a_atom_size); - return ATOM_REJECT; + return l_load_mode ? ATOM_CORRUPTED : ATOM_REJECT; } } while (sizeof(l_block->hdr) + l_offset + sizeof(dap_sign_t) < a_atom_size) { @@ -1951,7 +1934,7 @@ static dap_chain_atom_verify_res_t s_callback_atom_verify(dap_chain_t *a_chain, if (!l_hash_found) { log_it(L_WARNING, "Incorrect size %zu of block %s, expected %zu", l_offset + sizeof(l_block->hdr), dap_hash_fast_to_str_static(a_atom_hash), a_atom_size); - return ATOM_REJECT; + return l_load_mode ? ATOM_CORRUPTED : ATOM_REJECT; } } diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c index 431f3f0b90..e52d88fd87 100644 --- a/modules/type/dag/dap_chain_cs_dag.c +++ b/modules/type/dag/dap_chain_cs_dag.c @@ -78,14 +78,11 @@ typedef struct dap_chain_cs_dag_blocked { typedef struct dap_chain_cs_dag_pvt { pthread_mutex_t events_mutex; - dap_chain_cs_dag_event_item_t * events; - dap_chain_cs_dag_event_item_t * datums; - dap_chain_cs_dag_event_item_t * events_treshold; - dap_chain_cs_dag_event_item_t * events_treshold_conflicted; - dap_chain_cs_dag_event_item_t * events_lasts_unlinked; + dap_chain_cs_dag_event_item_t *events_prefetched, *events, *events_treshold, *events_treshold_conflicted, *events_lasts_unlinked, *datums; dap_chain_cs_dag_blocked_t *removed_events_from_treshold; dap_interval_timer_t treshold_free_timer; uint64_t tx_count; + bool need_reorder; } dap_chain_cs_dag_pvt_t; #define PVT(a) ((dap_chain_cs_dag_pvt_t *) a->_pvt ) @@ -97,7 +94,9 @@ static void s_threshold_free(dap_chain_cs_dag_t *a_dag); static dap_chain_cs_dag_event_item_t *s_dag_proc_treshold(dap_chain_cs_dag_t *a_dag); // Atomic element organization callbacks -static dap_chain_atom_verify_res_t s_chain_callback_atom_add(dap_chain_t * a_chain, dap_chain_atom_ptr_t , size_t, dap_hash_fast_t *a_atom_hash, bool a_atom_new); // Accept new event in dag +static dap_chain_atom_verify_res_t s_chain_callback_atom_read(dap_chain_t * a_chain, dap_chain_atom_ptr_t , size_t, dap_hash_fast_t *a_atom_hash); +static unsigned s_chain_callback_prefetched_atoms_add(dap_chain_t *a_chain); +static dap_chain_atom_verify_res_t s_chain_callback_atom_add(dap_chain_t * a_chain, dap_chain_atom_ptr_t , size_t, dap_hash_fast_t *a_atom_hash, bool a_atom_new); // Accept new event in dag static dap_chain_atom_ptr_t s_chain_callback_atom_add_from_treshold(dap_chain_t * a_chain, size_t *a_event_size_out); // Accept new event in dag from treshold static dap_chain_atom_verify_res_t s_chain_callback_atom_verify(dap_chain_t * a_chain, dap_chain_atom_ptr_t , size_t, dap_hash_fast_t *a_atom_hash); // Verify new event in dag static size_t s_chain_callback_atom_get_static_hdr_size(void); // Get dag event header size @@ -213,7 +212,10 @@ static int s_chain_cs_dag_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg) pthread_mutexattr_destroy(&l_mutex_attr); // Atom element callbacks + + a_chain->callback_atom_prefetch = s_chain_callback_atom_read; // Prefetching a_chain->callback_atom_add = s_chain_callback_atom_add ; // Accept new element in chain + a_chain->callback_atoms_prefetched_add = s_chain_callback_prefetched_atoms_add; a_chain->callback_atom_add_from_treshold = s_chain_callback_atom_add_from_treshold; // Accept new elements in chain from treshold a_chain->callback_atom_verify = s_chain_callback_atom_verify ; // Verify new element in chain a_chain->callback_atom_get_hdr_static_size = s_chain_callback_atom_get_static_hdr_size; // Get dag event hdr size @@ -400,20 +402,11 @@ static int s_chain_cs_dag_delete(dap_chain_t * a_chain) static int s_dap_chain_add_atom_to_events_table(dap_chain_cs_dag_t *a_dag, dap_chain_cs_dag_event_item_t *a_event_item) { dap_chain_datum_t *l_datum = (dap_chain_datum_t*) dap_chain_cs_dag_event_get_datum(a_event_item->event, a_event_item->event_size); - if (!l_datum) { - log_it(L_WARNING, "Corrupted event, failed to extract datum from event."); - return -2; - } - if(a_event_item->event_size < sizeof(l_datum->header) ){ - log_it(L_WARNING, "Corrupted event, too small to fit datum in it"); - return -1; - } - size_t l_datum_size = dap_chain_datum_size(l_datum); - size_t l_datum_size_max = dap_chain_cs_dag_event_get_datum_size_maximum(a_event_item->event, a_event_item->event_size); - if(l_datum_size >l_datum_size_max ){ - log_it(L_WARNING, "Corrupted event, too big size %zd in header when event's size max is only %zd", l_datum_size, l_datum_size_max); - return -1; - } + dap_return_val_if_fail_err( l_datum, -2, "Corrupted event, failed to extract datum" ); + dap_return_val_if_pass_err( a_event_item->event_size < sizeof(l_datum->header), -1, "Corrupted event, size too small"); + size_t l_datum_size = dap_chain_datum_size(l_datum), + l_datum_size_max = dap_chain_cs_dag_event_get_datum_size_maximum(a_event_item->event, a_event_item->event_size); + dap_return_val_if_pass_err( l_datum_size > l_datum_size_max, -1, "Event size exeeds max size permitted, %zd > %zd", l_datum_size, l_datum_size_max ); dap_hash_fast_t l_datum_hash; dap_chain_datum_calc_hash(l_datum, &l_datum_hash); int l_ret = dap_chain_datum_add(a_dag->chain, l_datum, l_datum_size, &l_datum_hash, NULL); @@ -432,12 +425,9 @@ static int s_dap_chain_add_atom_to_events_table(dap_chain_cs_dag_t *a_dag, dap_c HASH_ADD_BYHASHVALUE(hh_datums, PVT(a_dag)->datums, datum_hash, sizeof(l_datum_hash), l_hash_item_hashv, a_event_item); pthread_mutex_unlock(&PVT(a_dag)->events_mutex); - if (s_debug_more) { - char l_buf_hash[DAP_CHAIN_HASH_FAST_STR_SIZE] = {'\0'}; - dap_chain_hash_fast_to_str(&a_event_item->hash, l_buf_hash, sizeof(l_buf_hash)); - log_it(L_INFO, "Dag event %s checked, ret code %d : %s", l_buf_hash, l_ret, - l_ret ? dap_chain_net_verify_datum_err_code_to_str(l_datum, l_ret) : "Ok"); - } + debug_if(s_debug_more, L_INFO, "Dag event %s checked, ret code %d : %s", + dap_chain_hash_fast_to_str_static(&a_event_item->hash), l_ret, + l_ret ? dap_chain_net_verify_datum_err_code_to_str(l_datum, l_ret) : "Ok"); return l_ret; } @@ -454,6 +444,71 @@ static int s_sort_event_item(dap_chain_cs_dag_event_item_t* a, dap_chain_cs_dag_ return a->ts_created < b->ts_created ? -1 : a->ts_created == b->ts_created ? 0 : 1; } +static dap_chain_atom_verify_res_t s_dag_event_integrity_check(dap_chain_cs_dag_t *a_dag, uint64_t a_chain_id, dap_chain_cs_dag_event_t *a_event, + size_t a_event_size, dap_chain_hash_fast_t *a_atom_hash) +{ + dap_return_val_if_pass_err( a_event_size < sizeof(dap_chain_cs_dag_event_t), ATOM_CORRUPTED, + "Too small event size %zu", a_event_size ); + dap_return_val_if_pass_err( a_event->header.version, ATOM_CORRUPTED, + "Unsupported event version %u", a_event->header.version ); + dap_return_val_if_fail_err( a_event->header.chain_id.uint64 == a_chain_id, ATOM_CORRUPTED, + "Wrong chain id %zu", a_event->header.chain_id.uint64 ); + if ( a_dag->hal ) { + dap_chain_cs_dag_hal_item_t *l_hash_search = NULL; + HASH_FIND(hh, a_dag->hal, a_atom_hash, sizeof(*a_atom_hash), l_hash_search); + if (l_hash_search) + return ATOM_ACCEPT; + } + size_t l_atom_size = dap_chain_cs_dag_event_calc_size(a_event, a_event_size); + dap_return_val_if_fail_err( l_atom_size == a_event_size, ATOM_CORRUPTED, + "Invalid event size, %zu != %zu", l_atom_size, a_event_size ); + return ATOM_PASS; +} + +static dap_chain_atom_verify_res_t s_chain_callback_atom_read(dap_chain_t *a_chain, dap_chain_atom_ptr_t a_atom, size_t a_atom_size, dap_chain_hash_fast_t *a_atom_hash) +{ + dap_chain_cs_dag_t *l_dag = DAP_CHAIN_CS_DAG(a_chain); + dap_chain_cs_dag_event_t *l_event = (dap_chain_cs_dag_event_t*)a_atom, *l_tmp; + dap_chain_atom_verify_res_t l_verif = s_dag_event_integrity_check(l_dag, a_chain->id.uint64, l_event, a_atom_size, a_atom_hash); + dap_return_val_if_pass_err( l_verif == ATOM_CORRUPTED, l_verif, "Event %s is corrupted", dap_hash_fast_to_str_static(a_atom_hash) ); + + dap_chain_cs_dag_event_item_t *l_event_item = NULL; + unsigned hashval = 0; + static dap_time_t l_last_ts = 0; + HASH_VALUE(a_atom_hash, sizeof(*a_atom_hash), hashval); + HASH_FIND_BYHASHVALUE(hh, PVT(l_dag)->events_prefetched, a_atom_hash, sizeof(*a_atom_hash), hashval, l_event_item); + if (!l_event_item) { + l_event_item = DAP_NEW(dap_chain_cs_dag_event_item_t); + *l_event_item = (dap_chain_cs_dag_event_item_t) { + .hash = *a_atom_hash, + .event = a_chain->is_mapped ? l_event : DAP_DUP_SIZE(l_event, a_atom_size), + .event_size = a_atom_size, + .ts_created = l_event->header.ts_created + }; + HASH_ADD_BYHASHVALUE(hh, PVT(l_dag)->events_prefetched, hash, sizeof(*a_atom_hash), hashval, l_event_item); + if ( l_last_ts > l_event_item->ts_created ) + PVT(l_dag)->need_reorder = true; + l_last_ts = l_event_item->ts_created; + } + return ATOM_ACCEPT; +} + +static unsigned s_chain_callback_prefetched_atoms_add(dap_chain_t *a_chain) { + dap_chain_cs_dag_t *l_dag = DAP_CHAIN_CS_DAG(a_chain); + if ( PVT(l_dag)->need_reorder ) { + HASH_SORT( PVT(l_dag)->events_prefetched, s_sort_event_item ); + PVT(l_dag)->need_reorder = false; + } + unsigned i = 0, q = HASH_COUNT(PVT(l_dag)->events_prefetched); + dap_chain_cs_dag_event_item_t *l_event_item, *l_tmp; + HASH_ITER(hh, PVT(l_dag)->events_prefetched, l_event_item, l_tmp) { + HASH_DEL(PVT(l_dag)->events_prefetched, l_event_item); + s_chain_callback_atom_add(a_chain, l_event_item->event, l_event_item->event_size, &l_event_item->datum_hash, false); + a_chain->load_progress = (int)((float)++i/q * 100 + 0.5); + } + return i; +} + /** * @brief s_chain_callback_atom_add Accept new event in dag * @param a_chain DAG object @@ -463,20 +518,19 @@ static int s_sort_event_item(dap_chain_cs_dag_event_item_t* a, dap_chain_cs_dag_ */ 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, dap_hash_fast_t *a_atom_hash, bool a_atom_new) { - dap_chain_cs_dag_t * l_dag = DAP_CHAIN_CS_DAG(a_chain); - dap_chain_cs_dag_event_t * l_event = (dap_chain_cs_dag_event_t *) a_atom; + dap_chain_cs_dag_t *l_dag = DAP_CHAIN_CS_DAG(a_chain); + dap_chain_cs_dag_event_t * l_event = (dap_chain_cs_dag_event_t*)a_atom; - dap_chain_hash_fast_t l_event_hash = *a_atom_hash; - debug_if(s_debug_more, L_DEBUG, "Processing event: %s ... (size %zd)", dap_chain_hash_fast_to_str_static(&l_event_hash), a_atom_size); + debug_if(s_debug_more, L_DEBUG, "Processing event: %s ... (size %zd)", dap_chain_hash_fast_to_str_static(a_atom_hash), a_atom_size); pthread_mutex_lock(&PVT(l_dag)->events_mutex); // check if we already have this event - dap_chain_atom_verify_res_t ret = s_dap_chain_check_if_event_is_present(PVT(l_dag)->events, &l_event_hash) || - s_dap_chain_check_if_event_is_present(PVT(l_dag)->events_treshold, &l_event_hash) ? ATOM_PASS : ATOM_ACCEPT; + dap_chain_atom_verify_res_t ret = s_dap_chain_check_if_event_is_present(PVT(l_dag)->events, a_atom_hash) || + s_dap_chain_check_if_event_is_present(PVT(l_dag)->events_treshold, a_atom_hash) ? ATOM_PASS : ATOM_ACCEPT; // verify hashes and consensus switch (ret) { case ATOM_ACCEPT: - ret = s_chain_callback_atom_verify(a_chain, a_atom, a_atom_size, &l_event_hash); + ret = s_chain_callback_atom_verify(a_chain, a_atom, a_atom_size, a_atom_hash); if (ret == ATOM_MOVE_TO_THRESHOLD) { if (!s_threshold_enabled /*&& !dap_chain_net_get_load_mode(dap_chain_net_by_id(a_chain->net_id))*/) ret = ATOM_REJECT; @@ -490,28 +544,30 @@ static dap_chain_atom_verify_res_t s_chain_callback_atom_add(dap_chain_t * a_cha default: break; } - 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_CRITICAL, "%s", c_error_memory_alloc); - pthread_mutex_unlock(&PVT(l_dag)->events_mutex); - return ATOM_REJECT; + bool l_load_mode = dap_chain_net_get_load_mode(dap_chain_net_by_id(a_chain->net_id)); + dap_chain_cs_dag_event_item_t *l_event_item; + if (l_load_mode) { + l_event_item = (dap_chain_cs_dag_event_item_t*)(a_atom_hash); // Guaranteed by C1x §6.7.2.1.13 + l_event_item->ts_added = dap_time_now(); + } else { + l_event_item = DAP_NEW(dap_chain_cs_dag_event_item_t); + *l_event_item = (dap_chain_cs_dag_event_item_t) { + .hash = *a_atom_hash, + .ts_added = dap_time_now(), + .event = a_chain->is_mapped ? l_event : DAP_DUP_SIZE(l_event, a_atom_size), + .event_size = a_atom_size, + .ts_created = l_event->header.ts_created + }; } - *l_event_item = (dap_chain_cs_dag_event_item_t) { - .hash = l_event_hash, - .ts_added = dap_time_now(), - .event = a_chain->is_mapped ? l_event : DAP_DUP_SIZE(l_event, a_atom_size), - .event_size = a_atom_size, - .ts_created = l_event->header.ts_created - }; switch (ret) { case ATOM_MOVE_TO_THRESHOLD: { dap_chain_cs_dag_blocked_t *el = NULL; - HASH_FIND(hh, PVT(l_dag)->removed_events_from_treshold, &l_event_hash, sizeof(dap_chain_hash_fast_t), el); + HASH_FIND(hh, PVT(l_dag)->removed_events_from_treshold, a_atom_hash, sizeof(dap_chain_hash_fast_t), el); if (!el) { - if ( a_chain->is_mapped && dap_chain_net_get_load_mode(dap_chain_net_by_id(a_chain->net_id)) ) + if ( a_chain->is_mapped && l_load_mode ) l_event_item->mapped_region = (char*)l_event; - HASH_ADD(hh, PVT(l_dag)->events_treshold, hash, sizeof(l_event_hash), l_event_item); + HASH_ADD(hh, PVT(l_dag)->events_treshold, hash, sizeof(*a_atom_hash), l_event_item); debug_if(s_debug_more, L_DEBUG, "... added to threshold"); } else { ret = ATOM_REJECT; @@ -520,15 +576,12 @@ static dap_chain_atom_verify_res_t s_chain_callback_atom_add(dap_chain_t * a_cha break; } case ATOM_ACCEPT: { - dap_chain_cell_t *l_cell = dap_chain_cell_find_by_id(a_chain, l_event->header.cell_id); - if ( !dap_chain_net_get_load_mode( dap_chain_net_by_id(a_chain->net_id)) ) { - if ( dap_chain_atom_save(l_cell, a_atom, a_atom_size, a_atom_new ? &l_event_hash : NULL) < 0 ) { - log_it(L_ERROR, "Can't save atom to file"); + if ( !l_load_mode ) { + int l_err = dap_chain_atom_save(a_chain, l_event->header.cell_id, a_atom, a_atom_size, a_atom_new ? a_atom_hash : NULL, (char**)&l_event_item->event); + if (l_err) { + log_it(L_ERROR, "Can't save atom to file, code %d", l_err); ret = ATOM_REJECT; break; - } else if (a_chain->is_mapped) { - l_event_item->event = (dap_chain_cs_dag_event_t*)( l_cell->map_pos += sizeof(uint64_t) ); - l_cell->map_pos += a_atom_size; } } int l_consensus_check = s_dap_chain_add_atom_to_events_table(l_dag, l_event_item); @@ -546,19 +599,9 @@ static dap_chain_atom_verify_res_t s_chain_callback_atom_add(dap_chain_t * a_cha debug_if(s_debug_more, L_WARNING, "... added with ledger code %d", l_consensus_check); break; } - - dap_chain_cs_dag_event_item_t *l_tail = HASH_LAST(PVT(l_dag)->events); - if (l_tail && l_tail->ts_created > l_event->header.ts_created) { - DAP_CHAIN_PVT(a_chain)->need_reorder = true; - - HASH_ADD_INORDER(hh, PVT(l_dag)->events, hash, sizeof(l_event_item->hash), l_event_item, s_sort_event_item); - dap_chain_cs_dag_event_item_t *it = PVT(l_dag)->events; - for (uint64_t i = 0; it; it = it->hh.next) // renumber chain events - it->event_number = ++i; - } else - HASH_ADD(hh, PVT(l_dag)->events, hash, sizeof(l_event_item->hash), l_event_item); + s_dag_events_lasts_process_new_last_event(l_dag, l_event_item); - dap_chain_atom_notify(l_cell, &l_event_item->hash, (const byte_t*)l_event_item->event, l_event_item->event_size); + dap_chain_atom_notify(l_dag->chain, l_event_item->event->header.cell_id, &l_event_item->hash, (const byte_t*)l_event_item->event, l_event_item->event_size); dap_chain_atom_add_from_threshold(a_chain); } break; default: @@ -745,60 +788,39 @@ dap_chain_cs_dag_event_t* dap_chain_cs_dag_find_event_by_hash(dap_chain_cs_dag_t */ static dap_chain_atom_verify_res_t s_chain_callback_atom_verify(dap_chain_t *a_chain, dap_chain_atom_ptr_t a_atom, size_t a_atom_size, dap_chain_hash_fast_t *a_atom_hash) { - dap_chain_cs_dag_t * l_dag = DAP_CHAIN_CS_DAG(a_chain); - dap_chain_cs_dag_event_t * l_event = (dap_chain_cs_dag_event_t *) a_atom; - dap_chain_atom_verify_res_t res = ATOM_ACCEPT; - pthread_mutex_t *l_events_mutex = &PVT(l_dag)->events_mutex; - if (a_atom_size < sizeof(dap_chain_cs_dag_event_t)) { - log_it(L_WARNING, "Too small event size %zu, less than event header", a_atom_size); - return ATOM_REJECT; - } - if (l_event->header.version) { - log_it(L_WARNING, "Unsupported event version, possible corrupted event"); - return ATOM_REJECT; - } - if (l_event->header.chain_id.uint64 != a_chain->id.uint64) { - log_it(L_WARNING, "Event from another chain, possible corrupted event"); - return ATOM_REJECT; - } - dap_chain_hash_fast_t l_event_hash = *a_atom_hash; - // Hard accept list - if (l_dag->hal) { - dap_chain_cs_dag_hal_item_t *l_hash_found = NULL; - pthread_mutex_lock(l_events_mutex); - HASH_FIND(hh, l_dag->hal, &l_event_hash, sizeof(l_event_hash), l_hash_found); - pthread_mutex_unlock(l_events_mutex); - if (l_hash_found) { + dap_chain_cs_dag_event_t *l_event = (dap_chain_cs_dag_event_t*)a_atom; + dap_chain_cs_dag_t *l_dag = DAP_CHAIN_CS_DAG(a_chain); + if ( dap_chain_net_get_load_mode(dap_chain_net_by_id(a_chain->net_id)) ) { + if ( l_dag->hal ) { + /* We should check HAL twice, because we can't tell HAL'ed event from passed after prefetching */ + dap_chain_cs_dag_hal_item_t *l_hash_search = NULL; + HASH_FIND(hh, l_dag->hal, a_atom_hash, sizeof(*a_atom_hash), l_hash_search); + if (l_hash_search) + return ATOM_ACCEPT; + } + } else + switch ( s_dag_event_integrity_check(l_dag, a_chain->id.uint64, l_event, a_atom_size, a_atom_hash) ) { + case ATOM_ACCEPT: return ATOM_ACCEPT; + case ATOM_CORRUPTED: + return ATOM_REJECT; + default: + break; } - } - size_t l_atom_size = dap_chain_cs_dag_event_calc_size(l_event, a_atom_size); - if (l_atom_size != a_atom_size) { - log_it(L_WARNING, "Event size %zu not equal to expected %zu", l_atom_size, a_atom_size); - return ATOM_REJECT; - } - + dap_chain_atom_verify_res_t res = ATOM_ACCEPT; + pthread_mutex_t *l_events_mutex = &PVT(l_dag)->events_mutex; // genesis or seed mode - if (l_event->header.hash_count == 0){ - if(s_seed_mode && !PVT(l_dag)->events){ - log_it(L_NOTICE,"Accepting genesis event"); + if ( !l_event->header.hash_count ) { + if ( s_seed_mode ) /* TODO: lock with mutex too. Is this yet used?...*/ + return PVT(l_dag)->events + ? log_it(L_NOTICE,"Treating event %s as genesis. Time to turn seed mode off!", dap_hash_fast_to_str_static(a_atom_hash)), ATOM_ACCEPT + : ( log_it(L_ERROR, "Genesis event is already present! Turn off seed mode and try again!"), ATOM_REJECT ); + if ( l_dag->is_static_genesis_event ) { + dap_return_val_if_pass_err( memcmp( a_atom_hash, &l_dag->static_genesis_event_hash, sizeof(*a_atom_hash) ), + /* l_load_mode ? ATOM_CORRUPTED : */ ATOM_REJECT, "Wrong genesis event: preconfigured \"%s\" != \"%s\"", + dap_hash_fast_to_str_static(&l_dag->static_genesis_event_hash), dap_hash_fast_to_str_static(a_atom_hash) ); + debug_if(s_debug_more, L_INFO, "Accepting static genesis event \"%s\"", dap_hash_fast_to_str_static(a_atom_hash)); return ATOM_ACCEPT; - }else if(s_seed_mode){ - log_it(L_WARNING,"Cant accept genesis event: already present data in DAG, ->events is not NULL"); - return ATOM_REJECT; - } - - if (l_dag->is_static_genesis_event ){ - if ( memcmp( &l_event_hash, &l_dag->static_genesis_event_hash, sizeof(l_event_hash) ) != 0 ){ - char l_event_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE], l_genesis_event_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; - dap_chain_hash_fast_to_str(&l_event_hash, l_event_hash_str, sizeof(l_event_hash_str)); - dap_chain_hash_fast_to_str(&l_dag->static_genesis_event_hash, l_genesis_event_hash_str, sizeof(l_genesis_event_hash_str)); - log_it(L_WARNING, "Wrong genesis event %s (staticly predefined %s)",l_event_hash_str, l_genesis_event_hash_str); - return ATOM_REJECT; - } else { - debug_if(s_debug_more, L_INFO, "Accepting static genesis event"); - return ATOM_ACCEPT; - } } } @@ -821,10 +843,7 @@ static dap_chain_atom_verify_res_t s_chain_callback_atom_verify(dap_chain_t *a_c } //consensus - if (res == ATOM_ACCEPT && l_dag->callback_cs_verify(l_dag, l_event, a_atom_hash)) - res = ATOM_REJECT; - - return res; + return res == ATOM_ACCEPT && l_dag->callback_cs_verify(l_dag, l_event, a_atom_hash) ? ATOM_REJECT : res; } /** @@ -937,16 +956,13 @@ dap_chain_cs_dag_event_item_t* s_dag_proc_treshold(dap_chain_cs_dag_t * a_dag) if (ret == DAP_THRESHOLD_OK) { debug_if(s_debug_more, L_DEBUG, "Processing event (threshold): %s...", dap_chain_hash_fast_to_str_static(&l_event_item->hash)); - dap_chain_cell_t *l_cell = dap_chain_cell_find_by_id(a_dag->chain, l_event_item->event->header.cell_id); if ( !l_event_item->mapped_region ) { - if ( dap_chain_atom_save(l_cell, (const byte_t*)l_event_item->event, l_event_item->event_size, NULL) < 0 ) { - log_it(L_CRITICAL, "Can't move atom from threshold to file"); + int l_err = dap_chain_atom_save(a_dag->chain, l_event_item->event->header.cell_id, (const byte_t*)l_event_item->event, + l_event_item->event_size, NULL, (char**)&l_event_item->event); + if (l_err) + log_it(L_CRITICAL, "Can't move atom from threshold to file, code %d", l_err); res = false; break; - } else if (a_dag->chain->is_mapped) { - l_event_item->event = (dap_chain_cs_dag_event_t*)( l_cell->map_pos += sizeof(uint64_t) ); - l_cell->map_pos += l_event_item->event_size; - } } int l_add_res = s_dap_chain_add_atom_to_events_table(a_dag, l_event_item); HASH_DEL(PVT(a_dag)->events_treshold, l_event_item); @@ -954,7 +970,7 @@ dap_chain_cs_dag_event_item_t* s_dag_proc_treshold(dap_chain_cs_dag_t * a_dag) HASH_ADD(hh, PVT(a_dag)->events, hash, sizeof(l_event_item->hash), l_event_item); s_dag_events_lasts_process_new_last_event(a_dag, l_event_item); debug_if(s_debug_more, L_INFO, "... moved from threshold to chain"); - dap_chain_atom_notify(l_cell, &l_event_item->hash, (byte_t*)l_event_item->event, l_event_item->event_size); + dap_chain_atom_notify(a_dag->chain, l_event_item->event->header.cell_id, &l_event_item->hash, (byte_t*)l_event_item->event, l_event_item->event_size); res = true; } else { // TODO clear other threshold items linked with this one @@ -1428,7 +1444,7 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply) } } // write events to file and delete events from db - if(l_list_to_del) { + /* if(l_list_to_del) { if (dap_chain_cell_file_update(l_chain->cells) > 0) { // delete events from db dap_list_t *l_el; @@ -1438,7 +1454,7 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply) } dap_chain_cell_close(l_chain->cells); dap_list_free(l_list_to_del); - } + } */ // TODO! // Cleaning up dap_global_db_objs_delete(l_objs, l_objs_size); -- GitLab From 9db9eff68591179b8886e5d92d8be9ec23a08f7c Mon Sep 17 00:00:00 2001 From: "Constantin P." <papizh.konstantin@demlabs.net> Date: Tue, 18 Feb 2025 12:52:20 +0700 Subject: [PATCH 07/11] Build fix --- dap-sdk | 2 +- modules/chain/dap_chain_cell.c | 25 ++++++++++--------- .../consensus/esbocs/dap_chain_cs_esbocs.c | 2 +- modules/ledger/dap_chain_ledger.c | 10 +++++--- modules/net/dap_chain_net.c | 2 +- .../dap_chain_net_srv_emit_delegate.c | 2 +- modules/type/dag/dap_chain_cs_dag.c | 3 ++- 7 files changed, 25 insertions(+), 21 deletions(-) diff --git a/dap-sdk b/dap-sdk index 64b2cd4990..825fe16538 160000 --- a/dap-sdk +++ b/dap-sdk @@ -1 +1 @@ -Subproject commit 64b2cd4990a59c3af91e8f1402d4cfd468bd90bc +Subproject commit 825fe16538c62b1c4732b16a415c9cb966ff6085 diff --git a/modules/chain/dap_chain_cell.c b/modules/chain/dap_chain_cell.c index 7df6254238..46236b6d1b 100644 --- a/modules/chain/dap_chain_cell.c +++ b/modules/chain/dap_chain_cell.c @@ -221,6 +221,7 @@ DAP_STATIC_INLINE int s_cell_close(dap_chain_cell_t *a_cell) { } //pthread_rwlock_unlock(&a_cell->storage_rwlock); //pthread_rwlock_destroy(&a_cell->storage_rwlock); + return 0; } /** @@ -236,8 +237,8 @@ void dap_chain_cell_close(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id) a_cell_id.uint64, a_chain->net_name, a_chain->name); s_cell_close(l_cell); HASH_DEL(a_chain->cells, l_cell); - DAP_DELETE(l_cell); dap_chain_cell_remit(l_cell); + DAP_DELETE(l_cell); } void dap_chain_cell_close_all(dap_chain_t *a_chain) { @@ -295,11 +296,11 @@ DAP_STATIC_INLINE int s_cell_load_from_file(dap_chain_cell_t *a_cell) dap_chain_atom_ptr_t l_atom; dap_hash_fast_t l_atom_hash; if (a_cell->chain->is_mapped) { - for ( off_t l_vol_rest = 0; l_pos + sizeof(uint64_t) < l_full_size; ++q, l_pos += sizeof(uint64_t) + l_el_size ) { + for ( off_t l_vol_rest = 0; l_pos + sizeof(uint64_t) < (size_t)l_full_size; ++q, l_pos += sizeof(uint64_t) + l_el_size ) { l_vol_rest = (off_t)( a_cell->mapping->volume->base + a_cell->mapping->volume->size - a_cell->mapping->cursor - sizeof(uint64_t) ); - if ( l_vol_rest <= 0 || (uint64_t)l_vol_rest < ( l_el_size = *(uint64_t*)a_cell->mapping->cursor ) ) + if ( l_vol_rest <= 0 || l_vol_rest < ( l_el_size = *(uint64_t*)a_cell->mapping->cursor ) ) dap_return_val_if_pass_err( s_cell_map_new_volume(a_cell, l_pos, true), -7, "Error on mapping a new volume" ); - if ( !l_el_size || l_el_size > (size_t)(l_full_size - l_pos) ) + if ( !l_el_size || l_el_size > l_full_size - l_pos ) break; l_atom = (dap_chain_atom_ptr_t)(a_cell->mapping->cursor + sizeof(uint64_t)); dap_hash_fast(l_atom, l_el_size, &l_atom_hash); @@ -307,7 +308,7 @@ DAP_STATIC_INLINE int s_cell_load_from_file(dap_chain_cell_t *a_cell) ? a_cell->chain->callback_atom_prefetch(a_cell->chain, l_atom, l_el_size, &l_atom_hash) : a_cell->chain->callback_atom_add(a_cell->chain, l_atom, l_el_size, &l_atom_hash, false); if ( l_verif == ATOM_CORRUPTED ) { - log_it(L_ERROR, "Atom #%d is corrupted, can't proceed with loading chain \"%s : %s\" cell 0x%016"DAP_UINT64_FORMAT_X"", + log_it(L_ERROR, "Atom #%ld is corrupted, can't proceed with loading chain \"%s : %s\" cell 0x%016"DAP_UINT64_FORMAT_X"", q, a_cell->chain->net_name, a_cell->chain->name, a_cell->id.uint64); l_ret = 8; break; @@ -335,7 +336,7 @@ DAP_STATIC_INLINE int s_cell_load_from_file(dap_chain_cell_t *a_cell) break; } l_read = fread((void*)l_atom, 1, l_el_size, a_cell->file_storage); - if (l_read != l_el_size) { + if (l_read != (size_t)l_el_size) { log_it(L_ERROR, "Read only %lu of %zu bytes, stop cell loading", l_read, l_el_size); DAP_DELETE(l_atom); l_ret = 10; @@ -347,7 +348,7 @@ DAP_STATIC_INLINE int s_cell_load_from_file(dap_chain_cell_t *a_cell) : a_cell->chain->callback_atom_add(a_cell->chain, l_atom, l_el_size, &l_atom_hash, false); DAP_DELETE(l_atom); if ( l_verif == ATOM_CORRUPTED ) { - log_it(L_ERROR, "Atom #%d is corrupted, can't proceed with loading chain \"%s : %s\" cell 0x%016"DAP_UINT64_FORMAT_X"", + log_it(L_ERROR, "Atom #%ld is corrupted, can't proceed with loading chain \"%s : %s\" cell 0x%016"DAP_UINT64_FORMAT_X"", q, a_cell->chain->net_name, a_cell->chain->name, a_cell->id.uint64); l_ret = 11; break; @@ -383,7 +384,7 @@ DAP_STATIC_INLINE int s_cell_open(dap_chain_t *a_chain, const char *a_filename, dap_chain_cell_id_t l_cell_id = { }; { /* Check filename */ char l_fmt[20] = "", l_ext[ sizeof(CELL_FILE_EXT) ] = "", l_ext2 = '\0'; - snprintf(l_fmt, sizeof(l_fmt), "%s%d%s", "%"DAP_UINT64_FORMAT_x".%", sizeof(CELL_FILE_EXT) - 1, "[^.].%c"); + snprintf(l_fmt, sizeof(l_fmt), "%s%lu%s", "%"DAP_UINT64_FORMAT_x".%", sizeof(CELL_FILE_EXT) - 1, "[^.].%c"); switch ( sscanf(a_filename, l_fmt, &l_cell_id.uint64, l_ext, &l_ext2) ) { case 3: @@ -478,19 +479,19 @@ static int s_cell_file_atom_add(dap_chain_cell_t *a_cell, dap_chain_atom_ptr_t a if (a_cell->chain->is_mapped) { off_t l_pos = !fseeko(a_cell->file_storage, 0, SEEK_END) ? ftello(a_cell->file_storage) : -1; dap_return_val_if_pass_err(l_pos < 0, -1, "Can't get \"%s : %s\" cell 0x%016"DAP_UINT64_FORMAT_X" size, error %d", - a_cell->chain->net_name, a_cell->chain->name, a_cell->id, errno); + a_cell->chain->net_name, a_cell->chain->name, a_cell->id.uint64, errno); if ( a_atom_size + sizeof(uint64_t) > (size_t)(a_cell->mapping->volume->base + a_cell->mapping->volume->size - a_cell->mapping->cursor) ) dap_return_val_if_pass_err( s_cell_map_new_volume(a_cell, l_pos, false), -2, "Failed to create new map volume for \"%s : %s\" cell 0x%016"DAP_UINT64_FORMAT_X"", - a_cell->chain->net_name, a_cell->chain->name, a_cell->id + a_cell->chain->net_name, a_cell->chain->name, a_cell->id.uint64 ); } dap_return_val_if_fail_err( fwrite(&a_atom_size, sizeof(a_atom_size), 1, a_cell->file_storage) == 1 && fwrite(a_atom, a_atom_size, 1, a_cell->file_storage) == 1, -3, "Can't write atom [%zu b] to \"%s : %s\" cell 0x%016"DAP_UINT64_FORMAT_X", error %d: \"%s\"", - a_atom_size, a_cell->chain->net_name, a_cell->chain->name, a_cell->id, errno, dap_strerror(errno) + a_atom_size, a_cell->chain->net_name, a_cell->chain->name, a_cell->id.uint64, errno, dap_strerror(errno) ); fflush(a_cell->file_storage); @@ -532,7 +533,7 @@ int dap_chain_cell_file_append(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_ dap_return_val_if_fail(a_atom && a_atom_size && a_chain, -1); dap_chain_cell_t *l_cell = dap_chain_cell_capture_by_id(a_chain, a_cell_id); dap_return_val_if_fail_err(l_cell, -2, "Cell #%"DAP_UINT64_FORMAT_x" not found in chain \"%s : %s\"", - a_cell_id, a_chain->net_name, a_chain->name); + a_cell_id.uint64, a_chain->net_name, a_chain->name); //pthread_rwlock_wrlock(&l_cell->storage_rwlock); int l_err = s_cell_file_atom_add(l_cell, a_atom, a_atom_size, a_atom_map); if (l_err) diff --git a/modules/consensus/esbocs/dap_chain_cs_esbocs.c b/modules/consensus/esbocs/dap_chain_cs_esbocs.c index 0c0668acb6..b642862d4d 100644 --- a/modules/consensus/esbocs/dap_chain_cs_esbocs.c +++ b/modules/consensus/esbocs/dap_chain_cs_esbocs.c @@ -264,7 +264,7 @@ static int s_callback_new(dap_chain_t *a_chain, dap_config_t *a_chain_cfg) dap_chain_net_t *l_net = dap_chain_net_by_id(a_chain->net_id); int l_dot_pos = strlen(l_auth_certs_prefix), l_len = l_dot_pos + 16, l_pos2 = 0; char l_cert_name[l_len]; - strncpy(l_cert_name, l_auth_certs_prefix, l_dot_pos); + dap_strncpy(l_cert_name, l_auth_certs_prefix, l_dot_pos); for (i = 0; i < l_auth_certs_count; ++i) { dap_cert_t *l_cert_cur; l_pos2 = snprintf(l_cert_name + l_dot_pos, 16, ".%u", i); diff --git a/modules/ledger/dap_chain_ledger.c b/modules/ledger/dap_chain_ledger.c index 2b6b213fb9..b4a8535db7 100644 --- a/modules/ledger/dap_chain_ledger.c +++ b/modules/ledger/dap_chain_ledger.c @@ -246,10 +246,12 @@ static dap_ledger_t *dap_ledger_handle_new(void) { dap_ledger_t *l_ledger = DAP_NEW_Z_RET_VAL_IF_FAIL(dap_ledger_t, NULL); dap_ledger_private_t *l_ledger_pvt = l_ledger->_internal = DAP_NEW_Z_RET_VAL_IF_FAIL(dap_ledger_private_t, NULL, l_ledger); - - l_ledger_pvt->ledger_rwlock = l_ledger_pvt->tokens_rwlock = l_ledger_pvt->threshold_txs_rwlock - = l_ledger_pvt->balance_accounts_rwlock = l_ledger_pvt->stake_lock_rwlock = l_ledger_pvt->rewards_rwlock - = PTHREAD_RWLOCK_INITIALIZER; + pthread_rwlock_init(&l_ledger_pvt->ledger_rwlock, NULL); + pthread_rwlock_init(&l_ledger_pvt->tokens_rwlock, NULL); + pthread_rwlock_init(&l_ledger_pvt->threshold_txs_rwlock, NULL); + pthread_rwlock_init(&l_ledger_pvt->balance_accounts_rwlock, NULL); + pthread_rwlock_init(&l_ledger_pvt->stake_lock_rwlock, NULL); + pthread_rwlock_init(&l_ledger_pvt->rewards_rwlock, NULL); return l_ledger; } diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c index 72ea0e13f2..3cf22a25ad 100644 --- a/modules/net/dap_chain_net.c +++ b/modules/net/dap_chain_net.c @@ -815,7 +815,7 @@ void dap_chain_net_load_all() l_nets_count = i; } for ( i = 0; i < l_nets_count; l_err = pthread_join(l_tids[i++], NULL) ) { - debug_if(l_err, L_ERROR, "Thread %d join error %d: \"%s\"", l_err, dap_strerror(l_err)); + debug_if(l_err, L_ERROR, "Thread %d join error %d: \"%s\"", i, l_err, dap_strerror(l_err)); } dap_timerfd_delete(l_load_notify_timer->worker, l_load_notify_timer->esocket_uuid); } diff --git a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c index a10cf022ac..4b2e0769f3 100644 --- a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c +++ b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c @@ -415,7 +415,7 @@ static dap_chain_datum_tx_t *s_taking_tx_sign(json_object *a_json_arr_reply, dap m_sign_fail(ERROR_TX_MISMATCH, "Requested conditional transaction restrict provided sign key"); size_t l_my_pkey_size = 0; byte_t *l_my_pkey = dap_enc_key_serialize_pub_key(a_enc_key, &l_my_pkey_size); - if (l_my_pkey) + if (!l_my_pkey) m_sign_fail(ERROR_COMPOSE, "Can't serialize sign public key"); size_t l_tsd_hashes_count = l_cond->tsd_size / (sizeof(dap_tsd_t) + sizeof(dap_hash_fast_t)); size_t l_signs_limit = l_tsd_hashes_count * 2; diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c index e52d88fd87..c4421022f9 100644 --- a/modules/type/dag/dap_chain_cs_dag.c +++ b/modules/type/dag/dap_chain_cs_dag.c @@ -959,10 +959,11 @@ dap_chain_cs_dag_event_item_t* s_dag_proc_treshold(dap_chain_cs_dag_t * a_dag) if ( !l_event_item->mapped_region ) { int l_err = dap_chain_atom_save(a_dag->chain, l_event_item->event->header.cell_id, (const byte_t*)l_event_item->event, l_event_item->event_size, NULL, (char**)&l_event_item->event); - if (l_err) + if (l_err) { log_it(L_CRITICAL, "Can't move atom from threshold to file, code %d", l_err); res = false; break; + } } int l_add_res = s_dap_chain_add_atom_to_events_table(a_dag, l_event_item); HASH_DEL(PVT(a_dag)->events_treshold, l_event_item); -- GitLab From 982ef4ef7568490ce36e068b1a22ccbe5134b3e0 Mon Sep 17 00:00:00 2001 From: "Constantin P." <papizh.konstantin@demlabs.net> Date: Tue, 18 Feb 2025 13:56:54 +0700 Subject: [PATCH 08/11] ... --- modules/type/blocks/dap_chain_cs_blocks.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c index ccf9d057f6..684248faa7 100644 --- a/modules/type/blocks/dap_chain_cs_blocks.c +++ b/modules/type/blocks/dap_chain_cs_blocks.c @@ -1728,8 +1728,6 @@ static dap_chain_atom_verify_res_t s_callback_atom_add(dap_chain_t * a_chain, da dap_chain_net_t *l_net = dap_chain_net_by_id(a_chain->net_id); assert(l_net); #ifndef DAP_CHAIN_BLOCKS_TEST - dap_chain_net_t *l_net = dap_chain_net_by_id(a_chain->net_id); - assert(l_net); if ( !dap_chain_net_get_load_mode(l_net) ) { int l_err = dap_chain_atom_save(a_chain, l_block->hdr.cell_id, a_atom, a_atom_size, a_atom_new ? &l_block_hash : NULL, (char**)&l_block); if (l_err) { -- GitLab From b7b5f520c79ff700de02adec6648ce8f8d3a5450 Mon Sep 17 00:00:00 2001 From: Roman Khlopkov <roman.khlopkov@demlabs.net> Date: Tue, 18 Feb 2025 15:31:05 +0700 Subject: [PATCH 09/11] [*] Sub update --- dap-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dap-sdk b/dap-sdk index 825fe16538..e85a4e785c 160000 --- a/dap-sdk +++ b/dap-sdk @@ -1 +1 @@ -Subproject commit 825fe16538c62b1c4732b16a415c9cb966ff6085 +Subproject commit e85a4e785cd64395685ecbb9df24830a1ccb4dcf -- GitLab From b29b40f33a23954d0da07580225dbf013b4d19ca Mon Sep 17 00:00:00 2001 From: Roman Khlopkov <roman.khlopkov@demlabs.net> Date: Tue, 18 Feb 2025 16:04:33 +0700 Subject: [PATCH 10/11] [*] Test repair --- modules/chain/tests/dap_chain_ledger_tests.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/chain/tests/dap_chain_ledger_tests.c b/modules/chain/tests/dap_chain_ledger_tests.c index 18f949b6b7..6c284f7f95 100644 --- a/modules/chain/tests/dap_chain_ledger_tests.c +++ b/modules/chain/tests/dap_chain_ledger_tests.c @@ -1025,7 +1025,7 @@ void dap_ledger_test_run(void){ dap_assert_PIF(dap_chain_cs_create(l_chain_main, &l_cfg) == 0, "Chain esbocs cs creating: "); DL_APPEND(l_net->pub.chains, l_chain_main); - dap_assert_PIF(!dap_ledger_decree_init(l_net->pub.ledger), "Decree initialization:"); + dap_ledger_decree_init(l_net->pub.ledger); char *l_seed_ph = "H58i9GJKbn91238937^#$t6cjdf"; size_t l_seed_ph_size = strlen(l_seed_ph); -- GitLab From de4d0e3522e1abf77d8c7a68613d63516802f1ed Mon Sep 17 00:00:00 2001 From: Roman Khlopkov <roman.khlopkov@demlabs.net> Date: Tue, 18 Feb 2025 16:12:01 +0700 Subject: [PATCH 11/11] [*] Blocks test repair --- modules/type/blocks/dap_chain_cs_blocks.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c index 684248faa7..253c1ad2dd 100644 --- a/modules/type/blocks/dap_chain_cs_blocks.c +++ b/modules/type/blocks/dap_chain_cs_blocks.c @@ -1726,8 +1726,8 @@ static dap_chain_atom_verify_res_t s_callback_atom_add(dap_chain_t * a_chain, da switch (ret) { case ATOM_ACCEPT:{ dap_chain_net_t *l_net = dap_chain_net_by_id(a_chain->net_id); - assert(l_net); #ifndef DAP_CHAIN_BLOCKS_TEST + assert(l_net); if ( !dap_chain_net_get_load_mode(l_net) ) { int l_err = dap_chain_atom_save(a_chain, l_block->hdr.cell_id, a_atom, a_atom_size, a_atom_new ? &l_block_hash : NULL, (char**)&l_block); if (l_err) { @@ -1924,7 +1924,8 @@ static dap_chain_atom_verify_res_t s_callback_atom_add(dap_chain_t * a_chain, da static dap_chain_atom_verify_res_t s_callback_atom_verify(dap_chain_t *a_chain, dap_chain_atom_ptr_t a_atom, size_t a_atom_size, dap_chain_hash_fast_t *a_atom_hash) { dap_return_val_if_fail(a_chain && a_atom && a_atom_size && a_atom_hash, ATOM_REJECT); - bool l_load_mode = dap_chain_net_get_load_mode(dap_chain_net_by_id(a_chain->net_id)); + dap_chain_net_t *l_net = dap_chain_net_by_id(a_chain->net_id); + bool l_load_mode = l_net ? dap_chain_net_get_load_mode(l_net) : false; dap_chain_cs_blocks_t * l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain); assert(l_blocks); dap_chain_cs_blocks_pvt_t *l_blocks_pvt = PVT(l_blocks); -- GitLab