diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c index c5db0ec1f322984960f1707b84adf87e59216a54..c96dc2a2c0e402985d25dfb847fc5a8e1a78bb00 100644 --- a/modules/type/blocks/dap_chain_cs_blocks.c +++ b/modules/type/blocks/dap_chain_cs_blocks.c @@ -1471,28 +1471,32 @@ static void s_select_longest_branch(dap_chain_cs_blocks_t * a_blocks, dap_chain_ // Find longest forked branch dap_list_t *l_branch = a_bcache->forked_branches; dap_list_t *l_longest_branch_ptr = l_branch ? (dap_list_t *)l_branch->data : NULL; - uint64_t l_longest_branch_length = (HASH_CNT(hh, a_bcache) - current_block_idx + 1); + uint64_t l_longest_branch_length = current_block_idx; while (l_branch){ - if (dap_list_length((dap_list_t *)l_branch->data) > l_longest_branch_length){ - l_longest_branch_length = dap_list_length((dap_list_t *)l_branch->data); + uint64_t l_branch_length = dap_list_length((dap_list_t *)l_branch->data); + if (l_branch_length > l_longest_branch_length){ + l_longest_branch_length = l_branch_length; l_longest_branch_ptr = (dap_list_t *)l_branch->data; } l_branch = l_branch->next; } - // pthread_rwlock_wrlock(& PVT(l_blocks)->rwlock); - if ((HASH_CNT(hh, a_bcache) - current_block_idx + 1) < l_longest_branch_length){ + if (current_block_idx < l_longest_branch_length){ // Switch branches dap_list_t *l_new_forked_branch = NULL; // First we must to remove all blocks from main branch to forked // branch and delete all datums in this atoms from storages - dap_chain_block_cache_t *l_atom, *l_tmp; - HASH_ITER(hh, (dap_chain_block_cache_t *)a_bcache->hh.next, l_atom, l_tmp){ - l_new_forked_branch = dap_list_append(l_new_forked_branch, l_atom); - HASH_DEL(a_bcache, l_atom); - --PVT(l_blocks)->blocks_count; - s_delete_atom_datums(l_blocks, l_atom); - } + dap_chain_block_cache_t *l_atom = (dap_chain_block_cache_t *)a_bcache->hh.tbl->tail->prev, + *l_tmp = (dap_chain_block_cache_t *)a_bcache; + unsigned l_curr_index; + for (l_atom = l_atom->hh.next, l_curr_index = 0; + current_block_idx > l_curr_index; l_atom = l_atom->hh.prev, l_curr_index++){ + l_new_forked_branch = dap_list_prepend(l_new_forked_branch, l_atom); + HASH_DEL(a_bcache, l_atom); + --PVT(l_blocks)->blocks_count; + s_delete_atom_datums(l_blocks, l_atom); + } + a_bcache->forked_branches = dap_list_append(a_bcache->forked_branches, l_new_forked_branch); // Next we add all atoms into HT and their datums into storages dap_list_t * new_main_branch = l_longest_branch_ptr; @@ -1505,8 +1509,9 @@ static void s_select_longest_branch(dap_chain_cs_blocks_t * a_blocks, dap_chain_ new_main_branch = new_main_branch->next; } dap_list_free(l_longest_branch_ptr); + a_bcache->forked_branches = dap_list_remove(a_bcache->forked_branches, l_longest_branch_ptr); + } - // pthread_rwlock_unlock(& PVT(l_blocks)->rwlock); } /** @@ -1545,7 +1550,9 @@ static dap_chain_atom_verify_res_t s_callback_atom_add(dap_chain_t * a_chain, da pthread_rwlock_wrlock(& PVT(l_blocks)->rwlock); l_prev_bcache = l_block_pvt->blocks ? l_block_pvt->blocks->hh.tbl->tail->prev : NULL; if (l_prev_bcache){ - for (l_prev_bcache = l_prev_bcache ? l_prev_bcache->hh.next : PVT(l_blocks)->blocks; l_prev_bcache && l_current_item_index < DAP_FORK_MAX_DEPTH; l_current_item_index++, l_prev_bcache = l_prev_bcache->hh.prev){ + for (l_prev_bcache = l_prev_bcache->hh.next; + l_prev_bcache && l_current_item_index < DAP_FORK_MAX_DEPTH; + l_current_item_index++, l_prev_bcache = l_prev_bcache->hh.prev){ if (l_prev_bcache && dap_hash_fast_compare(&l_prev_bcache->block_hash, &l_block_prev_hash)){ ++PVT(l_blocks)->blocks_count; HASH_ADD(hh, PVT(l_blocks)->blocks, block_hash, sizeof(l_block_cache->block_hash), l_block_cache); @@ -1570,7 +1577,6 @@ static dap_chain_atom_verify_res_t s_callback_atom_add(dap_chain_t * a_chain, da l_forked_branches = l_forked_branches->next; } } - l_current_item_index++; } } else { HASH_ADD(hh, PVT(l_blocks)->blocks, block_hash, sizeof(l_block_cache->block_hash), l_block_cache); diff --git a/modules/type/blocks/tests/dap_chain_blocks_test.c b/modules/type/blocks/tests/dap_chain_blocks_test.c index 3913392f60a00a50b62378b223b16c9ce89f12a4..5c844ba1632b9921703e10db3d8023b652c31055 100644 --- a/modules/type/blocks/tests/dap_chain_blocks_test.c +++ b/modules/type/blocks/tests/dap_chain_blocks_test.c @@ -32,19 +32,19 @@ void dap_chain_blocks_test() dap_list_t *l_second_branch_atoms_list = NULL; l_block = dap_chain_block_new(NULL, &l_block_size); - dap_assert(l_block != NULL, "Creating of genesis block:"); + dap_assert_PIF(l_block != NULL, "Creating of genesis block:"); dap_hash_fast(l_block, l_block_size, &l_block_hash); - dap_test_msg("Created block %s", dap_chain_hash_fast_to_str_static(&l_block_hash)); - dap_assert(l_chain->callback_atom_add(l_chain, (dap_chain_atom_ptr_t)l_block, l_block_size, &l_block_hash) == ATOM_ACCEPT, "Adding of genesis block: "); + // dap_test_msg("Created genesis block %s", dap_chain_hash_fast_to_str_static(&l_block_hash)); + dap_assert_PIF(l_chain->callback_atom_add(l_chain, (dap_chain_atom_ptr_t)l_block, l_block_size, &l_block_hash) == ATOM_ACCEPT, "Adding of genesis block: "); dap_hash_fast_t *l_block_hash_copy = DAP_DUP_SIZE(&l_block_hash, sizeof(dap_hash_fast_t)); l_first_branch_atoms_list = dap_list_append(l_first_branch_atoms_list, l_block_hash_copy); l_second_branch_atoms_list = dap_list_append(l_second_branch_atoms_list, l_block_hash_copy); l_block = dap_chain_block_new(&l_block_hash, &l_block_size); - dap_assert(l_block != NULL, "Creating of second block:"); + dap_assert_PIF(l_block != NULL, "Creating of second block:"); dap_hash_fast(l_block, l_block_size, &l_block_hash); - dap_test_msg("Created block %s", dap_chain_hash_fast_to_str_static(&l_block_hash)); - dap_assert(l_chain->callback_atom_add(l_chain, (dap_chain_atom_ptr_t)l_block, l_block_size, &l_block_hash) == ATOM_ACCEPT, "Adding of second block: "); + // dap_test_msg("Created second block %s", dap_chain_hash_fast_to_str_static(&l_block_hash)); + dap_assert_PIF(l_chain->callback_atom_add(l_chain, (dap_chain_atom_ptr_t)l_block, l_block_size, &l_block_hash) == ATOM_ACCEPT, "Adding of second block: "); l_block_hash_copy = DAP_DUP_SIZE(&l_block_hash, sizeof(dap_hash_fast_t)); l_first_branch_atoms_list = dap_list_append(l_first_branch_atoms_list, l_block_hash_copy); l_second_branch_atoms_list = dap_list_append(l_second_branch_atoms_list, l_block_hash_copy); @@ -52,10 +52,10 @@ void dap_chain_blocks_test() for (int i = 0; i < 2; i++){ l_block = dap_chain_block_new(&l_block_hash, &l_block_size); - dap_assert(l_block != NULL, "Creating of block:"); + // dap_assert_PIF(l_block != NULL, "Creating of block:"); dap_hash_fast(l_block, l_block_size, &l_block_hash); - dap_test_msg("Created block %s", dap_chain_hash_fast_to_str_static(&l_block_hash)); - dap_assert(l_chain->callback_atom_add(l_chain, (dap_chain_atom_ptr_t)l_block, l_block_size, &l_block_hash) == ATOM_ACCEPT, "Adding of block: "); + // dap_test_msg("Created block %s", dap_chain_hash_fast_to_str_static(&l_block_hash)); + dap_assert_PIF(l_chain->callback_atom_add(l_chain, (dap_chain_atom_ptr_t)l_block, l_block_size, &l_block_hash) == ATOM_ACCEPT, "Adding of block: "); dap_hash_fast_t *l_block_hash_copy = DAP_DUP_SIZE(&l_block_hash, sizeof(dap_hash_fast_t)); l_first_branch_atoms_list = dap_list_append(l_first_branch_atoms_list, l_block_hash_copy); } @@ -64,67 +64,105 @@ void dap_chain_blocks_test() dap_test_msg("Add forked block from %s", dap_chain_hash_fast_to_str_static(&l_forked_block_hash)); l_block_size = 0; l_block = dap_chain_block_new(&l_forked_block_hash, &l_block_size); - dap_assert(l_block != NULL, "Creating of forked block:"); + // dap_assert_PIF(l_block != NULL, "Creating of forked block:"); dap_hash_fast(l_block, l_block_size, &l_block_hash); - dap_test_msg("Created block %s", dap_chain_hash_fast_to_str_static(&l_block_hash)); - dap_assert(l_chain->callback_atom_add(l_chain, (dap_chain_atom_ptr_t)l_block, l_block_size, &l_block_hash) == ATOM_ACCEPT, "Adding of forked block: "); + // dap_test_msg("Created block %s", dap_chain_hash_fast_to_str_static(&l_block_hash)); + dap_assert_PIF(l_chain->callback_atom_add(l_chain, (dap_chain_atom_ptr_t)l_block, l_block_size, &l_block_hash) == ATOM_ACCEPT, "Adding of forked block: "); l_block_hash_copy = DAP_DUP_SIZE(&l_block_hash, sizeof(dap_hash_fast_t)); l_second_branch_atoms_list = dap_list_append(l_second_branch_atoms_list, l_block_hash_copy); dap_chain_cell_id_t l_cell_id = {.uint64 = 1}; size_t l_atom_size_from_iter = 0; dap_chain_atom_iter_t *l_iter = l_chain->callback_atom_iter_create(l_chain, l_cell_id, NULL); - l_chain->callback_atom_iter_get(l_iter, DAP_CHAIN_ITER_OP_FIRST, &l_atom_size_from_iter); - dap_list_t *l_branch_temp = l_first_branch_atoms_list; - dap_assert_PIF(dap_hash_fast_compare(l_iter->cur_hash, (dap_hash_fast_t*)l_branch_temp->data), "Check adding block into forked branch: "); - l_branch_temp = l_branch_temp->next; - while (l_branch_temp && l_chain->callback_atom_iter_get(l_iter, DAP_CHAIN_ITER_OP_NEXT, &l_atom_size_from_iter)){ - dap_test_msg("Check block %s", dap_chain_hash_fast_to_str_static(l_iter->cur_hash)); + dap_list_t *l_branch_temp = NULL; + dap_chain_atom_ptr_t l_atom = l_chain->callback_atom_iter_get(l_iter, DAP_CHAIN_ITER_OP_FIRST, &l_atom_size_from_iter); + for (dap_list_t *l_branch_temp = l_first_branch_atoms_list; l_branch_temp && l_atom; + l_branch_temp = l_branch_temp->next, l_atom = l_chain->callback_atom_iter_get(l_iter, DAP_CHAIN_ITER_OP_NEXT, &l_atom_size_from_iter)){ + dap_test_msg("Check block %s and %s", dap_chain_hash_fast_to_str_static(l_iter->cur_hash), + dap_chain_hash_fast_to_str_static((dap_hash_fast_t*)l_branch_temp->data)); dap_assert_PIF(dap_hash_fast_compare(l_iter->cur_hash, (dap_hash_fast_t*)l_branch_temp->data), "Check adding block into forked branch: "); - l_branch_temp = l_branch_temp->next; } dap_test_msg("Add block to forked branch"); l_block_size = 0; l_block = dap_chain_block_new(&l_block_hash, &l_block_size); - dap_assert(l_block != NULL, "Creating of forked block:"); + // dap_assert_PIF(l_block != NULL, "Creating of forked block:"); dap_hash_fast(l_block, l_block_size, &l_block_hash); - dap_test_msg("Created block %s", dap_chain_hash_fast_to_str_static(&l_block_hash)); - dap_assert(l_chain->callback_atom_add(l_chain, (dap_chain_atom_ptr_t)l_block, l_block_size, &l_block_hash) == ATOM_ACCEPT, "Adding of forked block: "); + // dap_test_msg("Created block %s", dap_chain_hash_fast_to_str_static(&l_block_hash)); + dap_assert_PIF(l_chain->callback_atom_add(l_chain, (dap_chain_atom_ptr_t)l_block, l_block_size, &l_block_hash) == ATOM_ACCEPT, "Adding of forked block: "); l_block_hash_copy = DAP_DUP_SIZE(&l_block_hash, sizeof(dap_hash_fast_t)); l_second_branch_atoms_list = dap_list_append(l_second_branch_atoms_list, l_block_hash_copy); - l_chain->callback_atom_iter_get(l_iter, DAP_CHAIN_ITER_OP_FIRST, &l_atom_size_from_iter); - l_branch_temp = l_first_branch_atoms_list; - dap_assert_PIF(dap_hash_fast_compare(l_iter->cur_hash, (dap_hash_fast_t*)l_branch_temp->data), "Check adding block into forked branch: "); - l_branch_temp = l_branch_temp->next; - while (l_branch_temp && l_chain->callback_atom_iter_get(l_iter, DAP_CHAIN_ITER_OP_NEXT, &l_atom_size_from_iter)){ - dap_test_msg("Check block %s", dap_chain_hash_fast_to_str_static(l_iter->cur_hash)); + l_atom = l_chain->callback_atom_iter_get(l_iter, DAP_CHAIN_ITER_OP_FIRST, &l_atom_size_from_iter); + for (dap_list_t *l_branch_temp = l_first_branch_atoms_list; l_branch_temp && l_atom; + l_branch_temp = l_branch_temp->next, l_atom = l_chain->callback_atom_iter_get(l_iter, DAP_CHAIN_ITER_OP_NEXT, &l_atom_size_from_iter)){ + dap_test_msg("Check block %s and %s", dap_chain_hash_fast_to_str_static(l_iter->cur_hash), + dap_chain_hash_fast_to_str_static((dap_hash_fast_t*)l_branch_temp->data)); dap_assert_PIF(dap_hash_fast_compare(l_iter->cur_hash, (dap_hash_fast_t*)l_branch_temp->data), "Check adding block into forked branch: "); - l_branch_temp = l_branch_temp->next; } + dap_test_msg("Add block to forked branch"); l_block_size = 0; l_block = dap_chain_block_new(&l_block_hash, &l_block_size); - dap_assert(l_block != NULL, "Creating of forked block:"); + // dap_assert_PIF(l_block != NULL, "Creating of forked block:"); dap_hash_fast(l_block, l_block_size, &l_block_hash); - dap_test_msg("Created block %s", dap_chain_hash_fast_to_str_static(&l_block_hash)); - dap_assert(l_chain->callback_atom_add(l_chain, (dap_chain_atom_ptr_t)l_block, l_block_size, &l_block_hash) == ATOM_ACCEPT, "Adding of forked block: "); + // dap_test_msg("Created block %s", dap_chain_hash_fast_to_str_static(&l_block_hash)); + dap_assert_PIF(l_chain->callback_atom_add(l_chain, (dap_chain_atom_ptr_t)l_block, l_block_size, &l_block_hash) == ATOM_ACCEPT, "Adding of forked block: "); l_block_hash_copy = DAP_DUP_SIZE(&l_block_hash, sizeof(dap_hash_fast_t)); l_second_branch_atoms_list = dap_list_append(l_second_branch_atoms_list, l_block_hash_copy); - l_chain->callback_atom_iter_get(l_iter, DAP_CHAIN_ITER_OP_FIRST, &l_atom_size_from_iter); - l_branch_temp = l_second_branch_atoms_list; - dap_assert_PIF(dap_hash_fast_compare(l_iter->cur_hash, (dap_hash_fast_t*)l_branch_temp->data), "Check adding block into forked branch: "); - l_branch_temp = l_branch_temp->next; - while (l_branch_temp && l_chain->callback_atom_iter_get(l_iter, DAP_CHAIN_ITER_OP_NEXT, &l_atom_size_from_iter)){ - dap_test_msg("Check block %s", dap_chain_hash_fast_to_str_static(l_iter->cur_hash)); + l_atom = l_chain->callback_atom_iter_get(l_iter, DAP_CHAIN_ITER_OP_FIRST, &l_atom_size_from_iter); + for (dap_list_t *l_branch_temp = l_second_branch_atoms_list; l_branch_temp && l_atom; + l_branch_temp = l_branch_temp->next, l_atom = l_chain->callback_atom_iter_get(l_iter, DAP_CHAIN_ITER_OP_NEXT, &l_atom_size_from_iter)){ + dap_test_msg("Check block %s and %s", dap_chain_hash_fast_to_str_static(l_iter->cur_hash), + dap_chain_hash_fast_to_str_static((dap_hash_fast_t*)l_branch_temp->data)); dap_assert_PIF(dap_hash_fast_compare(l_iter->cur_hash, (dap_hash_fast_t*)l_branch_temp->data), "Check adding block into forked branch: "); - l_branch_temp = l_branch_temp->next; } + dap_test_msg("Add block to former main branch"); + l_block_size = 0; + l_block = dap_chain_block_new((dap_hash_fast_t*)dap_list_last(l_first_branch_atoms_list)->data, &l_block_size); + // dap_assert_PIF(l_block != NULL, "Creating of forked block:"); + dap_hash_fast(l_block, l_block_size, &l_block_hash); + // dap_test_msg("Created block %s", dap_chain_hash_fast_to_str_static(&l_block_hash)); + dap_assert_PIF(l_chain->callback_atom_add(l_chain, (dap_chain_atom_ptr_t)l_block, l_block_size, &l_block_hash) == ATOM_ACCEPT, "Adding of forked block: "); + l_block_hash_copy = DAP_DUP_SIZE(&l_block_hash, sizeof(dap_hash_fast_t)); + l_first_branch_atoms_list = dap_list_append(l_first_branch_atoms_list, l_block_hash_copy); + + l_atom = l_chain->callback_atom_iter_get(l_iter, DAP_CHAIN_ITER_OP_FIRST, &l_atom_size_from_iter); + for (dap_list_t *l_branch_temp = l_second_branch_atoms_list; l_branch_temp && l_atom; + l_branch_temp = l_branch_temp->next, l_atom = l_chain->callback_atom_iter_get(l_iter, DAP_CHAIN_ITER_OP_NEXT, &l_atom_size_from_iter)){ + dap_test_msg("Check block %s and %s", dap_chain_hash_fast_to_str_static(l_iter->cur_hash), + dap_chain_hash_fast_to_str_static((dap_hash_fast_t*)l_branch_temp->data)); + dap_assert_PIF(dap_hash_fast_compare(l_iter->cur_hash, (dap_hash_fast_t*)l_branch_temp->data), "Check adding block into forked branch: "); + } + + dap_test_msg("Add block to former main branch"); + l_block_size = 0; + l_block = dap_chain_block_new((dap_hash_fast_t*)dap_list_last(l_first_branch_atoms_list)->data, &l_block_size); + // dap_assert_PIF(l_block != NULL, "Creating of forked block:"); + dap_hash_fast(l_block, l_block_size, &l_block_hash); + // dap_test_msg("Created block %s", dap_chain_hash_fast_to_str_static(&l_block_hash)); + dap_assert_PIF(l_chain->callback_atom_add(l_chain, (dap_chain_atom_ptr_t)l_block, l_block_size, &l_block_hash) == ATOM_ACCEPT, "Adding of forked block: "); + l_block_hash_copy = DAP_DUP_SIZE(&l_block_hash, sizeof(dap_hash_fast_t)); + l_first_branch_atoms_list = dap_list_append(l_first_branch_atoms_list, l_block_hash_copy); + + l_atom = l_chain->callback_atom_iter_get(l_iter, DAP_CHAIN_ITER_OP_FIRST, &l_atom_size_from_iter); + for (dap_list_t *l_branch_temp = l_first_branch_atoms_list; l_branch_temp && l_atom; + l_branch_temp = l_branch_temp->next, l_atom = l_chain->callback_atom_iter_get(l_iter, DAP_CHAIN_ITER_OP_NEXT, &l_atom_size_from_iter)){ + dap_test_msg("Check block %s and %s", dap_chain_hash_fast_to_str_static(l_iter->cur_hash), + dap_chain_hash_fast_to_str_static((dap_hash_fast_t*)l_branch_temp->data)); + dap_assert_PIF(dap_hash_fast_compare(l_iter->cur_hash, (dap_hash_fast_t*)l_branch_temp->data), "Check adding block into forked branch: "); + } + + dap_pass_msg("Test of one forked branch ") + l_chain->callback_atom_iter_delete(l_iter); + + + + } \ No newline at end of file