From b2e337bef380ec03a00e177faf42ac201768a8f5 Mon Sep 17 00:00:00 2001 From: "roman.padenkov" <roman.padenkov@demlabs.net> Date: Wed, 13 Sep 2023 13:57:38 +0000 Subject: [PATCH] Hotfix 9408+ --- dap-sdk | 2 +- modules/channel/chain/dap_stream_ch_chain.c | 2 +- modules/common/dap_chain_datum_tx_items.c | 7 +- .../consensus/esbocs/dap_chain_cs_esbocs.c | 2 +- modules/net/dap_chain_node_cli_cmd.c | 6 +- modules/type/blocks/dap_chain_cs_blocks.c | 271 +++++++++--------- modules/type/dag/dap_chain_cs_dag.c | 80 ++---- 7 files changed, 174 insertions(+), 196 deletions(-) diff --git a/dap-sdk b/dap-sdk index 5c5f3376d3..3ef80ce7ee 160000 --- a/dap-sdk +++ b/dap-sdk @@ -1 +1 @@ -Subproject commit 5c5f3376d3cb3d53c582d82e472cdffce256aac8 +Subproject commit 3ef80ce7eefc7777c7fbb94101419318e7c59fce diff --git a/modules/channel/chain/dap_stream_ch_chain.c b/modules/channel/chain/dap_stream_ch_chain.c index 33e6e1c559..27efe47aee 100644 --- a/modules/channel/chain/dap_stream_ch_chain.c +++ b/modules/channel/chain/dap_stream_ch_chain.c @@ -783,7 +783,7 @@ static void s_gdb_in_pkt_proc_set_raw_callback(dap_global_db_context_t *a_global struct sync_request *l_sync_req = (struct sync_request*) a_arg; if( a_rc != 0){ - log_it(L_ERROR, "Can't save GlobalDB request, code %d", a_rc); + debug_if(s_debug_more, L_ERROR, "Can't save GlobalDB request, code %d", a_rc); dap_worker_exec_callback_inter(a_global_db_context->queue_worker_callback_input[l_sync_req->worker->id], s_gdb_in_pkt_error_worker_callback, l_sync_req); }else{ diff --git a/modules/common/dap_chain_datum_tx_items.c b/modules/common/dap_chain_datum_tx_items.c index 22ef1f623d..22a5c15573 100644 --- a/modules/common/dap_chain_datum_tx_items.c +++ b/modules/common/dap_chain_datum_tx_items.c @@ -787,11 +787,10 @@ uint8_t *dap_chain_datum_tx_item_get_nth(dap_chain_datum_tx_t *a_tx, dap_chain_t { uint8_t *l_tx_item = NULL; int l_item_idx = 0; - for (int l_type_idx = 0; l_type_idx <= a_item_idx; l_type_idx++) { + for (int l_type_idx = 0; l_type_idx <= a_item_idx; ++l_type_idx, ++l_item_idx) { l_tx_item = dap_chain_datum_tx_item_get(a_tx, &l_item_idx, a_type, NULL); if (!l_tx_item) break; - ++l_item_idx; } return l_tx_item; } @@ -809,9 +808,9 @@ dap_chain_tx_out_cond_t *dap_chain_datum_tx_out_cond_get(dap_chain_datum_tx_t *a dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_OUT_ALL, NULL), *l_item; int l_prev_cond_idx = a_out_num ? *a_out_num : 0; dap_chain_tx_out_cond_t *l_res = NULL; - DL_FOREACH(l_list_out_items, l_item) { + for (dap_list_t *l_item = l_list_out_items; l_item; l_item = l_item->next, ++l_prev_cond_idx) { // Start from *a_out_num + 1 item if a_out_num != NULL - if (a_out_num && l_prev_cond_idx++ < *a_out_num) + if (a_out_num && l_prev_cond_idx < *a_out_num) continue; if (*(byte_t*)l_item->data == TX_ITEM_TYPE_OUT_COND && ((dap_chain_tx_out_cond_t*)l_item->data)->header.subtype == a_cond_type) { diff --git a/modules/consensus/esbocs/dap_chain_cs_esbocs.c b/modules/consensus/esbocs/dap_chain_cs_esbocs.c index e9db643116..a574c1cb71 100644 --- a/modules/consensus/esbocs/dap_chain_cs_esbocs.c +++ b/modules/consensus/esbocs/dap_chain_cs_esbocs.c @@ -959,7 +959,7 @@ static uint64_t s_session_calc_current_round_id(dap_chain_esbocs_session_t *a_se static int s_signs_sort_callback(const void *a_sign1, const void *a_sign2) { dap_sign_t *l_sign1 = (dap_sign_t*)((dap_list_t*)a_sign1)->data, - *l_sign2 = (dap_sign_t*)((dap_list_t*)a_sign1)->data; + *l_sign2 = (dap_sign_t*)((dap_list_t*)a_sign2)->data; if (!l_sign1 || !l_sign2) { log_it(L_CRITICAL, "Invalid element"); return 0; diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c index 1f8d035bf0..960a8009d9 100644 --- a/modules/net/dap_chain_node_cli_cmd.c +++ b/modules/net/dap_chain_node_cli_cmd.c @@ -525,10 +525,10 @@ static int node_info_dump_with_reply(dap_chain_net_t * a_net, dap_chain_node_add int l_ret = 0; dap_string_t *l_string_reply = dap_string_new("Node dump:"); - if (a_addr || a_alias) { + if ((a_addr && a_addr->uint64) || a_alias) { dap_chain_node_addr_t *l_addr = a_alias ? dap_chain_node_alias_find(a_net, a_alias) - : a_addr && a_addr->uint64 ? DAP_DUP(a_addr) : NULL; + : DAP_DUP(a_addr); if (!l_addr) { log_it(L_ERROR, "Node address with specified params not found"); @@ -5920,7 +5920,7 @@ int com_tx_history(int a_argc, char ** a_argv, char **a_str_reply) DAP_DELETE(l_addr_str); DAP_DELETE(l_str_out); } else - l_str_ret = l_str_out; + dap_string_append_printf(l_str_ret, "%s", l_str_out); dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_str_ret->str); dap_string_free(l_str_ret, true); return 0; diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c index 9f4f7a121e..8f13d23ab3 100644 --- a/modules/type/blocks/dap_chain_cs_blocks.c +++ b/modules/type/blocks/dap_chain_cs_blocks.c @@ -54,23 +54,16 @@ struct cs_blocks_hal_item { typedef struct dap_chain_cs_blocks_pvt { - pthread_rwlock_t rwlock; // Parent link dap_chain_cs_blocks_t * cs_blocks; // All the blocks are here. In feature should be limited with 1000 when the rest would be loaded from file when needs them dap_chain_block_cache_t * blocks; - dap_chain_block_cache_t * blocks_tx_treshold; // Chunks treshold dap_chain_block_chunks_t * chunks; - - pthread_rwlock_t datums_rwlock; dap_chain_block_datum_index_t *datum_index; // To find datum in blocks - // General links - dap_chain_block_cache_t * block_cache_first; // Mapped area start - dap_chain_block_cache_t * block_cache_last; // Last block in mapped area dap_chain_hash_fast_t genesis_block_hash; dap_chain_hash_fast_t static_genesis_block_hash; @@ -80,9 +73,9 @@ typedef struct dap_chain_cs_blocks_pvt bool is_celled; dap_timerfd_t *fill_timer; - pthread_rwlock_t datums_lock; uint64_t fill_timeout; + pthread_rwlock_t rwlock, datums_rwlock; struct cs_blocks_hal_item *hal; } dap_chain_cs_blocks_pvt_t; @@ -260,7 +253,7 @@ int dap_chain_cs_blocks_new(dap_chain_t * a_chain, dap_config_t * a_chain_config } l_cs_blocks->_pvt = l_cs_blocks_pvt; pthread_rwlock_init(&l_cs_blocks_pvt->rwlock,NULL); - pthread_rwlock_init(&l_cs_blocks_pvt->datums_lock, NULL); + pthread_rwlock_init(&l_cs_blocks_pvt->datums_rwlock, NULL); const char * l_genesis_blocks_hash_str = dap_config_get_item_str_default(a_chain_config,"blocks","genesis_block",NULL); if ( l_genesis_blocks_hash_str ){ @@ -460,8 +453,9 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply) pthread_rwlock_wrlock( &PVT(l_blocks)->rwlock ); if ( l_blocks->block_new ) DAP_DELETE( l_blocks->block_new ); - l_blocks->block_new = dap_chain_block_new(PVT(l_blocks)->block_cache_last ? - &PVT(l_blocks)->block_cache_last->block_hash : NULL, + dap_chain_block_cache_t *l_bcache_last = PVT(l_blocks)->blocks ? PVT(l_blocks)->blocks->hh.tbl->tail->prev : NULL; + l_bcache_last = l_bcache_last ? l_bcache_last->hh.next : PVT(l_blocks)->blocks; + l_blocks->block_new = dap_chain_block_new(l_bcache_last ? &l_bcache_last->block_hash : NULL, &l_blocks->block_new_size); pthread_rwlock_unlock( &PVT(l_blocks)->rwlock ); } break; @@ -867,7 +861,8 @@ static void s_callback_delete(dap_chain_t * a_chain) l_blocks->callback_delete(l_blocks); pthread_rwlock_unlock(&PVT(l_blocks)->rwlock); pthread_rwlock_destroy(&PVT(l_blocks)->rwlock); - pthread_rwlock_destroy(&PVT(l_blocks)->datums_lock); + pthread_rwlock_destroy(&PVT(l_blocks)->datums_rwlock); + dap_chain_block_chunks_delete(PVT(l_blocks)->chunks); DAP_DEL_Z(l_blocks->_inheritor); DAP_DEL_Z(l_blocks->_pvt); log_it(L_INFO, "Block destructed"); @@ -883,6 +878,7 @@ static void s_callback_cs_blocks_purge(dap_chain_t *a_chain) DAP_DELETE(l_block->block); dap_chain_block_cache_delete(l_block); } + PVT(l_blocks)->blocks_count = 0; pthread_rwlock_unlock(&PVT(l_blocks)->rwlock); dap_chain_block_datum_index_t *l_datum_index = NULL, *l_datum_index_tmp = NULL; @@ -893,11 +889,8 @@ static void s_callback_cs_blocks_purge(dap_chain_t *a_chain) l_datum_index = NULL; } pthread_rwlock_unlock(&PVT(l_blocks)->datums_rwlock); - PVT(l_blocks)->blocks_count = 0; dap_chain_block_chunks_delete(PVT(l_blocks)->chunks); - PVT(l_blocks)->block_cache_last = NULL; - PVT(l_blocks)->block_cache_first = NULL; dap_chain_cell_delete_all(a_chain); PVT(l_blocks)->chunks = dap_chain_block_chunks_create(l_blocks); } @@ -960,22 +953,15 @@ static int s_add_atom_datums(dap_chain_cs_blocks_t *a_blocks, dap_chain_block_ca static int s_add_atom_to_blocks(dap_chain_cs_blocks_t *a_blocks, dap_chain_block_cache_t *a_block_cache ) { int l_res = 0; - pthread_rwlock_wrlock( &PVT(a_blocks)->rwlock ); + //pthread_rwlock_wrlock( &PVT(a_blocks)->rwlock ); // do lock in calling context! l_res = s_add_atom_datums(a_blocks, a_block_cache); debug_if(s_debug_more, L_DEBUG, "Block %s checked, %s", a_block_cache->block_hash_str, - l_res == (int)a_block_cache->datum_count ? - "all correct" : "but ledger declined"); - //All correct, no matter for result - HASH_ADD(hh, PVT(a_blocks)->blocks,block_hash,sizeof (a_block_cache->block_hash), a_block_cache); - PVT(a_blocks)->blocks_count++; - if (! (PVT(a_blocks)->block_cache_first ) ) - PVT(a_blocks)->block_cache_first = a_block_cache; - if (PVT(a_blocks)->block_cache_last) - PVT(a_blocks)->block_cache_last->next = a_block_cache; - a_block_cache->prev = PVT(a_blocks)->block_cache_last; - PVT(a_blocks)->block_cache_last = a_block_cache; - pthread_rwlock_unlock( &PVT(a_blocks)->rwlock ); - return 1; + l_res == (int)a_block_cache->datum_count ? "all correct" : "but ledger declined"); + // Ignore addition result for now + HASH_ADD(hh, PVT(a_blocks)->blocks, block_hash, sizeof (a_block_cache->block_hash), a_block_cache); + ++PVT(a_blocks)->blocks_count; + //pthread_rwlock_unlock( &PVT(a_blocks)->rwlock ); // do unlock in calling context! + return /* l_res */ 0; } @@ -987,7 +973,7 @@ static void s_bft_consensus_setup(dap_chain_cs_blocks_t * a_blocks) { bool l_was_chunks_changed = false; // Compare all chunks with chain's tail - for(dap_chain_block_chunk_t * l_chunk = PVT(a_blocks)->chunks->chunks_last ; l_chunk; l_chunk=l_chunk->prev ){ + for (dap_chain_block_chunk_t *l_chunk = PVT(a_blocks)->chunks->chunks_last ; l_chunk; l_chunk=l_chunk->prev ){ size_t l_chunk_length = HASH_COUNT(l_chunk->block_cache_hash); dap_chain_block_cache_t * l_block_cache_chunk_top_prev = dap_chain_block_cs_cache_get_by_hash(a_blocks,&l_chunk->block_cache_top->prev_hash); dap_chain_block_cache_t * l_block_cache= l_block_cache_chunk_top_prev; @@ -1014,7 +1000,7 @@ static void s_bft_consensus_setup(dap_chain_cs_blocks_t * a_blocks) if(l_block_cache->next) l_block_cache->next->prev = l_block_cache->prev; HASH_DEL(PVT(a_blocks)->blocks,l_block_cache); - PVT(a_blocks)->blocks_count--; + --PVT(a_blocks)->blocks_count; pthread_rwlock_unlock(& PVT(a_blocks)->rwlock); dap_chain_block_chunks_add(PVT(a_blocks)->chunks,l_block_cache); } @@ -1058,61 +1044,49 @@ static dap_chain_atom_verify_res_t s_callback_atom_add(dap_chain_t * a_chain, da dap_chain_block_t * l_block = (dap_chain_block_t *) a_atom; size_t l_block_size = a_atom_size; - pthread_rwlock_wrlock(&PVT(l_blocks)->datums_lock); dap_chain_hash_fast_t l_block_hash; dap_hash_fast(l_block, l_block_size, &l_block_hash); - dap_chain_block_cache_t * l_block_cache = dap_chain_block_cs_cache_get_by_hash(l_blocks, &l_block_hash); - if (l_block_cache ){ - debug_if(s_debug_more, L_DEBUG, "... already present in blocks %s", l_block_cache->block_hash_str); - pthread_rwlock_unlock(&PVT(l_blocks)->datums_lock); + + dap_chain_block_cache_t * l_block_cache = NULL; + pthread_rwlock_wrlock(& PVT(l_blocks)->rwlock); + HASH_FIND(hh, PVT(l_blocks)->blocks, &l_block_hash, sizeof(l_block_hash), l_block_cache); + if (l_block_cache) { + debug_if(s_debug_more, L_DEBUG, "... %s is already present", l_block_cache->block_hash_str); + pthread_rwlock_unlock(&PVT(l_blocks)->rwlock); return ATOM_PASS; } else { l_block_cache = dap_chain_block_cache_new(l_blocks, &l_block_hash, l_block, l_block_size); if (!l_block_cache) { log_it(L_DEBUG, "... corrupted block"); - pthread_rwlock_unlock(&PVT(l_blocks)->datums_lock); + pthread_rwlock_unlock(&PVT(l_blocks)->rwlock); return ATOM_REJECT; } debug_if(s_debug_more, L_DEBUG, "... new block %s", l_block_cache->block_hash_str); } - pthread_rwlock_unlock(&PVT(l_blocks)->datums_lock); - // verify hashes and consensus - dap_chain_atom_verify_res_t ret = s_callback_atom_verify (a_chain, a_atom, a_atom_size); - - if (ret == ATOM_MOVE_TO_THRESHOLD) { - //log_it(L_ATT, "Booo!"); - ret = ATOM_REJECT; // TODO remove it when threshold will work - } - - if( ret == ATOM_ACCEPT){ - int l_consensus_check = s_add_atom_to_blocks(l_blocks, l_block_cache); - if(l_consensus_check == 1){ - debug_if(s_debug_more, L_DEBUG, "... added"); - }else if (l_consensus_check == DAP_CHAIN_CS_VERIFY_CODE_TX_NO_PREVIOUS){ - pthread_rwlock_wrlock( &PVT(l_blocks)->rwlock ); - HASH_ADD(hh, PVT(l_blocks)->blocks_tx_treshold, block_hash, sizeof(l_block_cache->block_hash), l_block_cache); - pthread_rwlock_unlock( &PVT(l_blocks)->rwlock ); - debug_if(s_debug_more, L_DEBUG, "... tresholded for tx ledger"); - }else{ - debug_if(s_debug_more, L_WARNING, "... error adding (code %d)", l_consensus_check); - ret = ATOM_REJECT; - } - // !TODO make chunks add to blocks - }else if(ret == ATOM_MOVE_TO_THRESHOLD){ - if (dap_chain_block_cs_cache_get_by_hash(l_blocks, &l_block_hash)) { - // if it was concurrent atom processed before - dap_chain_block_cache_delete(l_block_cache); - return ATOM_PASS; + dap_chain_atom_verify_res_t ret = s_callback_atom_verify(a_chain, a_atom, a_atom_size); + switch (ret) { + case ATOM_ACCEPT: + s_add_atom_to_blocks(l_blocks, l_block_cache); + debug_if(s_debug_more, L_DEBUG, "Verified atom %p: ACCEPTED", a_atom); + break; + case ATOM_MOVE_TO_THRESHOLD: + // TODO: reimplement and enable threshold for blocks +/* { + debug_if(s_debug_more, L_DEBUG, "Verified atom %p: THRESHOLDED", a_atom); + break; } - dap_chain_block_chunks_add( PVT(l_blocks)->chunks,l_block_cache); - //dap_chain_block_chunks_sort(PVT(l_blocks)->chunks); - }else if (ret == ATOM_REJECT ){ +*/ + ret = ATOM_REJECT; + case ATOM_REJECT: dap_chain_block_cache_delete(l_block_cache); + debug_if(s_debug_more, L_DEBUG, "Verified atom %p: REJECTED", a_atom); + break; + default: + debug_if(s_debug_more, L_DEBUG, "Unknown verification ret code %d", ret); + break; } - debug_if(s_debug_more, L_DEBUG, "Verified atom %p: %s", a_atom, ret == ATOM_ACCEPT ? "accepted" : - (ret == ATOM_REJECT ? "rejected" : "thresholded")); - //s_bft_consensus_setup(l_blocks); + pthread_rwlock_unlock(&PVT(l_blocks)->rwlock); return ret; } @@ -1192,9 +1166,12 @@ static dap_chain_atom_verify_res_t s_callback_atom_verify(dap_chain_t * a_chain, log_it(L_WARNING,"Cant accept genesis block: already present data in blockchain"); return ATOM_REJECT; } - } else if (!PVT(l_blocks)->block_cache_last || - !dap_hash_fast_compare(&PVT(l_blocks)->block_cache_last->block_hash, &l_block_prev_hash)) - return ATOM_MOVE_TO_THRESHOLD; + } else { + dap_chain_block_cache_t *l_bcache_last = PVT(l_blocks)->blocks ? PVT(l_blocks)->blocks->hh.tbl->tail->prev : NULL; + l_bcache_last = l_bcache_last ? l_bcache_last->hh.next : PVT(l_blocks)->blocks; + if (!l_bcache_last || !dap_hash_fast_compare(&l_bcache_last->block_hash, &l_block_prev_hash)) + return ATOM_MOVE_TO_THRESHOLD; + } return ATOM_ACCEPT; } @@ -1346,20 +1323,28 @@ static dap_chain_datum_t** s_callback_atom_get_datums(dap_chain_atom_ptr_t a_ato */ static dap_chain_atom_ptr_t s_callback_atom_iter_get_first( dap_chain_atom_iter_t * a_atom_iter, size_t *a_atom_size ) { - if(! a_atom_iter){ - log_it(L_ERROR, "NULL iterator on input for atom_iter_get_first function"); + if(!a_atom_iter) { + log_it(L_CRITICAL, "Invalid argument"); return NULL; } dap_chain_cs_blocks_t * l_blocks = DAP_CHAIN_CS_BLOCKS(a_atom_iter->chain); dap_chain_cs_blocks_pvt_t *l_blocks_pvt = l_blocks ? PVT(l_blocks) : NULL; assert(l_blocks_pvt); - a_atom_iter->cur_item = l_blocks_pvt->block_cache_first; - a_atom_iter->cur = l_blocks_pvt->block_cache_first ? l_blocks_pvt->block_cache_first->block : NULL; - a_atom_iter->cur_size = l_blocks_pvt->block_cache_first ? l_blocks_pvt->block_cache_first->block_size : 0; - a_atom_iter->cur_hash = l_blocks_pvt->block_cache_first ? &l_blocks_pvt->block_cache_first->block_hash : NULL; - + //pthread_rwlock_rdlock(&l_blocks_pvt->rwlock); + a_atom_iter->cur_item = l_blocks_pvt->blocks; + if (a_atom_iter->cur_item) { + a_atom_iter->cur = l_blocks_pvt->blocks->block; + a_atom_iter->cur_size = l_blocks_pvt->blocks->block_size; + a_atom_iter->cur_hash = &l_blocks_pvt->blocks->block_hash; + } else { + a_atom_iter->cur = NULL; + a_atom_iter->cur_size = 0; + a_atom_iter->cur_hash = NULL; + } + //pthread_rwlock_unlock(&l_blocks_pvt->rwlock); if (a_atom_size) *a_atom_size = a_atom_iter->cur_size; + return a_atom_iter->cur; } @@ -1369,27 +1354,26 @@ static dap_chain_atom_ptr_t s_callback_atom_iter_get_first( dap_chain_atom_iter_ * @param a_atom_size * @return */ -static dap_chain_atom_ptr_t s_callback_atom_iter_get_next( dap_chain_atom_iter_t * a_atom_iter,size_t *a_atom_size ) +static dap_chain_atom_ptr_t s_callback_atom_iter_get_next(dap_chain_atom_iter_t * a_atom_iter,size_t *a_atom_size ) { assert(a_atom_iter); assert(a_atom_iter->cur_item); - dap_chain_block_cache_t * l_cur_cache =(dap_chain_block_cache_t *) a_atom_iter->cur_item; - a_atom_iter->cur_item = l_cur_cache = l_cur_cache->next; - if (l_cur_cache){ - a_atom_iter->cur = l_cur_cache->block; - a_atom_iter->cur_size = l_cur_cache->block_size; - a_atom_iter->cur_hash = &l_cur_cache->block_hash; - if(a_atom_size) - *a_atom_size = l_cur_cache->block_size; - return l_cur_cache->block; + dap_chain_block_cache_t *l_next_item = ((dap_chain_block_cache_t*)a_atom_iter->cur_item)->hh.next; + a_atom_iter->cur_item = l_next_item; + if (a_atom_iter->cur_item) { + a_atom_iter->cur = l_next_item->block; + a_atom_iter->cur_size = l_next_item->block_size; + a_atom_iter->cur_hash = &l_next_item->block_hash; + } else { + a_atom_iter->cur = NULL; + a_atom_iter->cur_size = 0; + a_atom_iter->cur_hash = NULL; } - a_atom_iter->cur = NULL; - a_atom_iter->cur_size = 0; - a_atom_iter->cur_hash = NULL; - if (a_atom_size) - *a_atom_size = 0; - return NULL; + if(a_atom_size) + *a_atom_size = a_atom_iter->cur_size; + + return a_atom_iter->cur; } /** @@ -1399,29 +1383,29 @@ static dap_chain_atom_ptr_t s_callback_atom_iter_get_next( dap_chain_atom_iter_t * @param a_links_size_ptr * @return */ -static dap_chain_atom_ptr_t *s_callback_atom_iter_get_links( dap_chain_atom_iter_t * a_atom_iter , size_t *a_links_size, size_t ** a_links_size_ptr ) +static dap_chain_atom_ptr_t *s_callback_atom_iter_get_links(dap_chain_atom_iter_t *a_atom_iter , size_t *a_links_size, size_t **a_links_size_ptr) { assert(a_atom_iter); assert(a_links_size); assert(a_links_size_ptr); - if (a_atom_iter->cur_item){ - dap_chain_block_cache_t * l_block_cache =(dap_chain_block_cache_t *) a_atom_iter->cur_item; - if (l_block_cache->links_hash_count){ - *a_links_size_ptr = DAP_NEW_Z_SIZE( size_t, l_block_cache->links_hash_count*sizeof (size_t)); - *a_links_size = l_block_cache->links_hash_count; - dap_chain_atom_ptr_t * l_ret = DAP_NEW_Z_SIZE(dap_chain_atom_ptr_t, l_block_cache->links_hash_count *sizeof (dap_chain_atom_ptr_t) ); - for (size_t i = 0; i< l_block_cache->links_hash_count; i ++){ - dap_chain_cs_blocks_t *l_cs_blocks = (dap_chain_cs_blocks_t *)l_block_cache->_inheritor; - dap_chain_block_cache_t *l_link = dap_chain_block_cs_cache_get_by_hash(l_cs_blocks, &l_block_cache->links_hash[i]); - assert(l_link); - (*a_links_size_ptr)[i] = l_link->block_size; - l_ret[i] = l_link->block; - } - return l_ret; - }else - return NULL; - }else + if (!a_atom_iter->cur_item) { return NULL; + } + dap_chain_block_cache_t * l_block_cache =(dap_chain_block_cache_t *) a_atom_iter->cur_item; + if (!l_block_cache->links_hash_count) { + return NULL; + } + *a_links_size_ptr = DAP_NEW_Z_SIZE(size_t, l_block_cache->links_hash_count * sizeof(size_t)); + *a_links_size = l_block_cache->links_hash_count; + dap_chain_atom_ptr_t *l_ret = DAP_NEW_Z_SIZE(dap_chain_atom_ptr_t, l_block_cache->links_hash_count * sizeof(dap_chain_atom_ptr_t)); + for (size_t i = 0; i < l_block_cache->links_hash_count; ++i){ + dap_chain_cs_blocks_t *l_cs_blocks = (dap_chain_cs_blocks_t *)l_block_cache->_inheritor; + dap_chain_block_cache_t *l_link = dap_chain_block_cs_cache_get_by_hash(l_cs_blocks, &l_block_cache->links_hash[i]); + assert(l_link); + (*a_links_size_ptr)[i] = l_link->block_size; + l_ret[i] = l_link->block; + } + return l_ret; } /** @@ -1433,15 +1417,18 @@ static dap_chain_atom_ptr_t *s_callback_atom_iter_get_links( dap_chain_atom_iter */ static dap_chain_atom_ptr_t *s_callback_atom_iter_get_lasts( dap_chain_atom_iter_t *a_atom_iter, size_t *a_links_size, size_t **a_lasts_size_ptr) { - assert(a_atom_iter); + if(!a_atom_iter) { + log_it(L_CRITICAL, "Invalid argument"); + return NULL; + } + dap_chain_block_cache_t *l_blocks = PVT(DAP_CHAIN_CS_BLOCKS(a_atom_iter->chain))->blocks; + dap_chain_block_cache_t *l_block_cache_last = l_blocks ? l_blocks->hh.tbl->tail->prev : NULL; + l_block_cache_last = l_block_cache_last ? l_block_cache_last->hh.next : l_blocks; - dap_chain_block_cache_t *l_block_cache_last = PVT(DAP_CHAIN_CS_BLOCKS(a_atom_iter->chain))->block_cache_last; if (l_block_cache_last) { a_atom_iter->cur = l_block_cache_last->block; a_atom_iter->cur_size = l_block_cache_last->block_size; a_atom_iter->cur_hash = &l_block_cache_last->block_hash; - if (a_links_size) - *a_links_size = 1; if (a_lasts_size_ptr) { *a_lasts_size_ptr = DAP_NEW_Z(size_t); if (!a_lasts_size_ptr) { @@ -1450,22 +1437,27 @@ static dap_chain_atom_ptr_t *s_callback_atom_iter_get_lasts( dap_chain_atom_iter } (*a_lasts_size_ptr)[0] = l_block_cache_last->block_size; } + if (a_links_size) + *a_links_size = 1; dap_chain_atom_ptr_t *l_ret = DAP_NEW_Z(dap_chain_atom_ptr_t); if (!l_ret) { - log_it(L_CRITICAL, "Memory allocation error"); + log_it(L_CRITICAL, "Memory allocation error"); + if (a_lasts_size_ptr) + DAP_DEL_Z(*a_lasts_size_ptr); return NULL; } l_ret[0] = l_block_cache_last->block; return l_ret; + } else { + a_atom_iter->cur = NULL; + a_atom_iter->cur_size = 0; + a_atom_iter->cur_hash = NULL; + if (a_links_size) + *a_links_size = 0; + if (a_lasts_size_ptr) + *a_lasts_size_ptr = NULL; + return NULL; } - a_atom_iter->cur = NULL; - a_atom_iter->cur_size = 0; - a_atom_iter->cur_hash = NULL; - if (a_links_size) - *a_links_size = 0; - if (a_lasts_size_ptr) - *a_lasts_size_ptr = NULL; - return NULL; } /** @@ -1543,14 +1535,14 @@ static dap_chain_block_t *s_new_block_move(dap_chain_cs_blocks_t *a_blocks, size size_t l_ret_size = 0; dap_chain_block_t *l_ret = NULL; dap_chain_cs_blocks_pvt_t *l_blocks_pvt = PVT(a_blocks); - pthread_rwlock_wrlock(&l_blocks_pvt->datums_lock); + pthread_rwlock_wrlock(&l_blocks_pvt->rwlock); if ( a_blocks->block_new ) { l_ret = a_blocks->block_new; l_ret_size = a_blocks->block_new_size; a_blocks->block_new = NULL; a_blocks->block_new_size = 0; } - pthread_rwlock_unlock(&l_blocks_pvt->datums_lock); + pthread_rwlock_unlock(&l_blocks_pvt->rwlock); if (a_new_block_size) *a_new_block_size = l_ret_size; return l_ret; @@ -1569,7 +1561,7 @@ static size_t s_callback_add_datums(dap_chain_t *a_chain, dap_chain_datum_t **a_ dap_chain_cs_blocks_pvt_t *l_blocks_pvt = PVT(l_blocks); size_t l_datum_processed = 0; - pthread_rwlock_wrlock(&l_blocks_pvt->datums_lock); + pthread_rwlock_wrlock(&l_blocks_pvt->rwlock); for (size_t i = 0; i < a_datums_count; ++i) { dap_chain_datum_t *l_datum = a_datums[i]; size_t l_datum_size = dap_chain_datum_size(l_datum); @@ -1582,7 +1574,9 @@ static size_t s_callback_add_datums(dap_chain_t *a_chain, dap_chain_datum_t **a_ break; } if (!l_blocks->block_new) { - l_blocks->block_new = dap_chain_block_new(&l_blocks_pvt->block_cache_last->block_hash, &l_blocks->block_new_size); + dap_chain_block_cache_t *l_bcache_last = l_blocks_pvt->blocks ? l_blocks_pvt->blocks->hh.tbl->tail->prev : NULL; + l_bcache_last = l_bcache_last ? l_bcache_last->hh.next : l_blocks_pvt->blocks; + l_blocks->block_new = dap_chain_block_new(&l_bcache_last->block_hash, &l_blocks->block_new_size); l_blocks->block_new->hdr.cell_id.uint64 = a_chain->cells->id.uint64; l_blocks->block_new->hdr.chain_id.uint64 = l_blocks->chain->id.uint64; } @@ -1590,7 +1584,7 @@ static size_t s_callback_add_datums(dap_chain_t *a_chain, dap_chain_datum_t **a_ l_blocks->block_new_size = dap_chain_block_datum_add(&l_blocks->block_new, l_blocks->block_new_size, l_datum, l_datum_size); l_datum_processed++; } - pthread_rwlock_unlock(&l_blocks_pvt->datums_lock); + pthread_rwlock_unlock(&l_blocks_pvt->rwlock); return l_datum_processed; } @@ -1602,8 +1596,11 @@ static size_t s_callback_add_datums(dap_chain_t *a_chain, dap_chain_datum_t **a_ static size_t s_callback_count_atom(dap_chain_t *a_chain) { dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain); - dap_chain_cs_blocks_pvt_t *l_blocks_pvt = PVT(l_blocks); - return l_blocks_pvt->blocks_count; + size_t l_ret = 0; + pthread_rwlock_rdlock(&PVT(l_blocks)->rwlock); + l_ret = PVT(l_blocks)->blocks_count; + pthread_rwlock_unlock(&PVT(l_blocks)->rwlock); + return l_ret; } /** @@ -1618,7 +1615,9 @@ static dap_list_t *s_callback_get_atoms(dap_chain_t *a_chain, size_t a_count, si { dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain); dap_chain_cs_blocks_pvt_t *l_blocks_pvt = PVT(l_blocks); + pthread_rwlock_rdlock(&PVT(l_blocks)->rwlock); if (!l_blocks_pvt->blocks) { + pthread_rwlock_unlock(&PVT(l_blocks)->rwlock); return NULL; } size_t l_offset = a_count * (a_page - 1); @@ -1626,6 +1625,7 @@ static dap_list_t *s_callback_get_atoms(dap_chain_t *a_chain, size_t a_count, si if (a_page < 2) l_offset = 0; if (l_offset > l_count){ + pthread_rwlock_unlock(&PVT(l_blocks)->rwlock); return NULL; } dap_list_t *l_list = NULL; @@ -1661,5 +1661,6 @@ static dap_list_t *s_callback_get_atoms(dap_chain_t *a_chain, size_t a_count, si l_counter++; } } + pthread_rwlock_unlock(&PVT(l_blocks)->rwlock); return l_list; } diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c index 69afdc5ea7..dc5a5215d5 100644 --- a/modules/type/dag/dap_chain_cs_dag.c +++ b/modules/type/dag/dap_chain_cs_dag.c @@ -138,8 +138,7 @@ static dap_list_t *s_dap_chain_callback_get_txs(dap_chain_t *a_chain, size_t a_c static size_t s_dap_chain_callback_get_count_atom(dap_chain_t *a_chain); static dap_list_t *s_callback_get_atoms(dap_chain_t *a_chain, size_t a_count, size_t a_page, bool a_reverse); -static bool s_seed_mode = false; -static bool s_debug_more = false; +static bool s_seed_mode = false, s_debug_more = false, s_threshold_enabled = false; /** * @brief dap_chain_cs_dag_init @@ -149,9 +148,10 @@ int dap_chain_cs_dag_init() { srand((unsigned int) time(NULL)); dap_chain_cs_type_add( "dag", dap_chain_cs_dag_new ); - s_seed_mode = dap_config_get_item_bool_default(g_config,"general","seed_mode",false); - s_debug_more = dap_config_get_item_bool_default(g_config,"dag","debug_more",false); - + s_seed_mode = dap_config_get_item_bool_default(g_config, "general", "seed_mode", false); + s_debug_more = dap_config_get_item_bool_default(g_config, "dag", "debug_more", false); + s_threshold_enabled = dap_config_get_item_bool_default(g_config, "dag", "threshold_enabled",false); + debug_if(s_debug_more, L_DEBUG, "Thresholding %s", s_threshold_enabled ? "enabled" : "disabled"); dap_cli_server_cmd_add ("dag", s_cli_dag, "DAG commands", "dag event create -net <net_name> -chain <chain_name> -datum <datum_hash> [-H {hex | base58(default)}]\n" "\tCreate event from datum mempool element\n\n" @@ -425,7 +425,7 @@ void dap_chain_cs_dag_delete(dap_chain_t * a_chain) } -static int s_dap_chain_add_datum(dap_chain_cs_dag_t *a_dag, dap_chain_cs_dag_event_item_t *a_event_item) +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(a_event_item->event_size< sizeof(l_datum->header) ){ @@ -455,20 +455,13 @@ static int s_dap_chain_add_datum(dap_chain_cs_dag_t *a_dag, dap_chain_cs_dag_eve 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); - return l_ret; -} - -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) -{ - int l_ledger_res = s_dap_chain_add_datum(a_dag, a_event_item); 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_DEBUG,"Dag event %s checked, add it to ledger", l_buf_hash); - if (l_ledger_res != 0) - log_it(L_WARNING,"Dag event %s checked, but ledger declined: code %d", l_buf_hash, l_ledger_res); + 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"); } - return l_ledger_res; + return l_ret; } static bool s_dap_chain_check_if_event_is_present(dap_chain_cs_dag_event_item_t * a_hash_table, const dap_chain_hash_fast_t * hash) { @@ -521,71 +514,59 @@ static dap_chain_atom_verify_res_t s_chain_callback_atom_add(dap_chain_t * a_cha // 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_item->hash) || s_dap_chain_check_if_event_is_present(PVT(l_dag)->events_treshold, &l_event_item->hash) ? ATOM_PASS : ATOM_ACCEPT; - pthread_mutex_unlock(l_events_mutex); // verify hashes and consensus switch (ret) { case ATOM_ACCEPT: ret = s_chain_callback_atom_verify(a_chain, a_atom, a_atom_size); - if (ret == ATOM_MOVE_TO_THRESHOLD && !dap_chain_net_get_load_mode(dap_chain_net_by_id(a_chain->net_id))) - ret = ATOM_REJECT; /* TODO: A temporary fix for memory consumption */ - if(s_debug_more) - log_it(L_DEBUG, "Verified atom %p: %s", a_atom, ret == ATOM_ACCEPT ? "accepted" : - (ret == ATOM_REJECT ? "rejected" : "thresholded")); + 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; + } + debug_if(s_debug_more, L_DEBUG, "Verified atom %p: %s", a_atom, dap_chain_atom_verify_res_str[ret]); break; case ATOM_PASS: - if(s_debug_more) { - log_it(L_DEBUG, "Atom already present"); - } + debug_if(s_debug_more, L_DEBUG, "Atom already present"); DAP_DELETE(l_event_item); + pthread_mutex_unlock(l_events_mutex); return ret; default: break; } switch (ret) { - case ATOM_MOVE_TO_THRESHOLD: - pthread_mutex_lock(l_events_mutex); + 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_item->hash, sizeof(dap_chain_hash_fast_t), el); if (!el) { HASH_ADD(hh, PVT(l_dag)->events_treshold, hash, sizeof(l_event_item->hash), l_event_item); - - if (s_debug_more) - log_it(L_DEBUG, "... added to threshold"); + debug_if(s_debug_more, L_DEBUG, "... added to threshold"); } else { ret = ATOM_REJECT; - if (s_debug_more) - log_it(L_DEBUG, "... rejected because the atom was removed from the threshold."); + debug_if(s_debug_more, L_DEBUG, "... rejected because the atom was removed from the threshold."); } - pthread_mutex_unlock(l_events_mutex); break; + } case ATOM_ACCEPT: { int l_consensus_check = s_dap_chain_add_atom_to_events_table(l_dag, l_event_item); switch (l_consensus_check) { case 0: - if(s_debug_more) - log_it(L_DEBUG, "... added"); + debug_if(s_debug_more, L_DEBUG, "... added"); break; case DAP_CHAIN_CS_VERIFY_CODE_TX_NO_PREVIOUS: case DAP_CHAIN_CS_VERIFY_CODE_TX_NO_EMISSION: - if(s_debug_more) - log_it(L_DEBUG, "... ledger tresholded"); + debug_if(s_debug_more, L_DEBUG, "... ledger tresholded"); break; case DAP_CHAIN_DATUM_CA: - if(s_debug_more) - log_it(L_DEBUG, "... DATUM_CA"); + debug_if(s_debug_more, L_DEBUG, "... DATUM_CA"); break; case DAP_CHAIN_DATUM_CUSTOM: - if(s_debug_more) - log_it(L_DEBUG, "... DATUM_CUSTOM"); + debug_if(s_debug_more, L_DEBUG, "... DATUM_CUSTOM"); break; default: - if (s_debug_more) - log_it(L_WARNING, "... added with ledger code %d", l_consensus_check); + debug_if(s_debug_more, L_WARNING, "... added with ledger code %d", l_consensus_check); break; } - pthread_mutex_lock(l_events_mutex); dap_chain_cs_dag_event_item_t *l_tail = PVT(l_dag)->events ? PVT(l_dag)->events->hh.tbl->tail->prev : NULL; if (!l_tail) l_tail = PVT(l_dag)->events; @@ -598,12 +579,12 @@ static dap_chain_atom_verify_res_t s_chain_callback_atom_add(dap_chain_t * a_cha 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); - pthread_mutex_unlock(l_events_mutex); } break; default: DAP_DELETE(l_event_item); // Neither added, nor freed break; } + pthread_mutex_unlock(l_events_mutex); return ret; } @@ -808,13 +789,11 @@ static dap_chain_atom_verify_res_t s_chain_callback_atom_verify(dap_chain_t * a_ dap_chain_atom_verify_res_t res = ATOM_ACCEPT; pthread_mutex_t *l_events_mutex = &PVT(l_dag)->events_mutex; if (l_event->header.version) { - if (s_debug_more) - log_it(L_WARNING, "Unsupported event version, possible corrupted event"); + debug_if(s_debug_more, L_WARNING, "Unsupported event version, possible corrupted event"); return ATOM_REJECT; } if (l_event->header.chain_id.uint64 != a_chain->id.uint64) { - if (s_debug_more) - log_it(L_WARNING, "Event from another chain, possible corrupted event"); + debug_if(s_debug_more, L_WARNING, "Event from another chain, possible corrupted event"); return ATOM_REJECT; } @@ -831,8 +810,7 @@ static dap_chain_atom_verify_res_t s_chain_callback_atom_verify(dap_chain_t * a_ } } if (!s_event_verify_size(l_event, a_atom_size)) { - if (s_debug_more) - log_it(L_WARNING,"Event size not equal to expected"); + debug_if(s_debug_more, L_WARNING,"Event size not equal to expected"); return ATOM_REJECT; } -- GitLab