From 19a503a570237e1bf4328f3791d481d2384d9d98 Mon Sep 17 00:00:00 2001
From: "daniil.frolov" <daniil.frolov@demlabs.net>
Date: Mon, 3 Jun 2024 18:05:53 +0700
Subject: [PATCH] ...

---
 modules/type/blocks/dap_chain_cs_blocks.c     |  36 ++--
 .../blocks/include/dap_chain_block_cache.h    |   6 +
 .../type/blocks/tests/dap_chain_blocks_test.c | 179 ++++++++----------
 3 files changed, 107 insertions(+), 114 deletions(-)

diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c
index 58655503a9..751fd145cc 100644
--- a/modules/type/blocks/dap_chain_cs_blocks.c
+++ b/modules/type/blocks/dap_chain_cs_blocks.c
@@ -61,7 +61,7 @@ typedef struct dap_chain_cs_blocks_pvt
     dap_chain_block_cache_t * blocks;
 
     size_t forked_br_cnt;
-    dap_list_t **forked_branches; // list of lists with atoms in side branches
+    dap_chain_block_forked_branch_t **forked_branches; // list of lists with atoms in side branches
 
     // Chunks treshold
     dap_chain_block_chunks_t * chunks;
@@ -1549,14 +1549,13 @@ 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;
+    dap_chain_block_forked_branch_t *l_longest_branch_cache_ptr = l_branch ? (dap_chain_block_forked_branch_t*)l_branch->data : NULL;
     uint64_t l_longest_branch_length = current_block_idx;
     while (l_branch){
-        dap_list_t **l_current_branch_ptr = (dap_list_t **)l_branch->data;
-        uint64_t l_branch_length = dap_list_length(*l_current_branch_ptr);
+        uint64_t l_branch_length = dap_list_length(((dap_chain_block_forked_branch_t*)l_branch->data)->forked_branch_atoms);
         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_longest_branch_cache_ptr = (dap_chain_block_forked_branch_t*)l_branch->data;
         }
         l_branch = l_branch->next;
     }
@@ -1578,7 +1577,7 @@ static void s_select_longest_branch(dap_chain_cs_blocks_t * a_blocks, dap_chain_
             }
 
         // Next we add all atoms into HT and their datums into storages
-        dap_list_t * new_main_branch = *l_longest_branch_ptr;
+        dap_list_t * new_main_branch = l_longest_branch_cache_ptr->forked_branch_atoms;
         while(new_main_branch){
             dap_chain_block_cache_t *l_curr_atom = (dap_chain_block_cache_t *)(new_main_branch->data);
             ++PVT(l_blocks)->blocks_count;
@@ -1587,11 +1586,8 @@ static void s_select_longest_branch(dap_chain_cs_blocks_t * a_blocks, dap_chain_
             s_add_atom_datums(l_blocks, l_curr_atom);
             new_main_branch = new_main_branch->next;
         }
-        dap_list_free(*l_longest_branch_ptr);
-        *l_longest_branch_ptr = l_new_forked_branch;
-
-        // a_bcache->forked_branches = dap_list_remove(a_bcache->forked_branches, l_longest_branch_ptr);
-        
+        dap_list_free(l_longest_branch_cache_ptr->forked_branch_atoms);
+        l_longest_branch_cache_ptr->forked_branch_atoms = l_new_forked_branch;
     }
 }
 
@@ -1647,12 +1643,13 @@ static dap_chain_atom_verify_res_t s_callback_atom_add(dap_chain_t * a_chain, da
                     // Check forked branches
                     dap_list_t * l_forked_branches = l_prev_bcache->forked_branches;
                     while(l_forked_branches){
-                        dap_list_t **l_current_branch = (dap_list_t**)l_forked_branches->data;
-                        dap_chain_block_cache_t * l_branch_last_bcache = (dap_chain_block_cache_t *)(dap_list_last(*l_current_branch))->data;
+                        dap_chain_block_forked_branch_t *l_cur_branch_cache = (dap_chain_block_forked_branch_t*)l_forked_branches->data;
+                        dap_chain_block_cache_t * l_branch_last_bcache = (dap_chain_block_cache_t *)(dap_list_last(l_cur_branch_cache->forked_branch_atoms))->data;
                         if(dap_hash_fast_compare(&l_branch_last_bcache->block_hash, &l_block_prev_hash)){
-                            *l_current_branch = dap_list_append(*l_current_branch, l_block_cache);
+                            l_cur_branch_cache->forked_branch_atoms = dap_list_append(l_cur_branch_cache->forked_branch_atoms, l_block_cache);
                             s_select_longest_branch(l_blocks, l_prev_bcache, l_current_item_index);
                             pthread_rwlock_unlock(&PVT(l_blocks)->rwlock);
+                            debug_if(s_debug_more, L_DEBUG, "Verified atom %p: ACCEPTED to a forked branch.", a_atom);
                             return ATOM_FORK;
                         }
                         l_forked_branches = l_forked_branches->next;
@@ -1688,12 +1685,15 @@ static dap_chain_atom_verify_res_t s_callback_atom_add(dap_chain_t * a_chain, da
         HASH_FIND(hh, PVT(l_blocks)->blocks, &l_block_prev_hash, sizeof(dap_hash_fast_t), l_prev_bcache);
         if (l_prev_bcache && dap_hash_fast_compare(&l_prev_bcache->block_hash, &l_block_prev_hash)){
             // make forked branch list
+            dap_chain_block_forked_branch_t *forked_branch_cache = DAP_NEW_Z(dap_chain_block_forked_branch_t);
             dap_list_t *forked_branch = NULL;
             forked_branch = dap_list_append(forked_branch, l_block_cache);
+            forked_branch_cache->connected_block = l_prev_bcache;
+            forked_branch_cache->forked_branch_atoms = forked_branch;
             PVT(l_blocks)->forked_br_cnt++;
             PVT(l_blocks)->forked_branches = DAP_REALLOC_COUNT(PVT(l_blocks)->forked_branches, PVT(l_blocks)->forked_br_cnt);
-            PVT(l_blocks)->forked_branches[PVT(l_blocks)->forked_br_cnt-1] = forked_branch;
-            l_prev_bcache->forked_branches = dap_list_append(l_prev_bcache->forked_branches, &PVT(l_blocks)->forked_branches[PVT(l_blocks)->forked_br_cnt-1]);
+            PVT(l_blocks)->forked_branches[PVT(l_blocks)->forked_br_cnt-1] = forked_branch_cache;
+            l_prev_bcache->forked_branches = dap_list_append(l_prev_bcache->forked_branches, PVT(l_blocks)->forked_branches[PVT(l_blocks)->forked_br_cnt-1]);
             pthread_rwlock_unlock(& PVT(l_blocks)->rwlock);
             debug_if(s_debug_more, L_DEBUG, "Fork is made successfuly.");
             return ATOM_FORK;
@@ -1803,8 +1803,8 @@ static dap_chain_atom_verify_res_t s_callback_atom_verify(dap_chain_t * a_chain,
                 // Check forked branches
                 dap_list_t * l_forked_branches = l_prev_bcache->forked_branches;
                 while(l_forked_branches){
-                    dap_list_t ** forked_branch = (dap_list_t **)l_forked_branches->data;                    
-                    dap_chain_block_cache_t *l_forked_branch_last_block = (dap_chain_block_cache_t *)(dap_list_last(*forked_branch)->data);
+                    dap_list_t *forked_branch = ((dap_chain_block_forked_branch_t *)l_forked_branches->data)->forked_branch_atoms;                    
+                    dap_chain_block_cache_t *l_forked_branch_last_block = (dap_chain_block_cache_t *)(dap_list_last(forked_branch)->data);
                     if(l_forked_branch_last_block && dap_hash_fast_compare(&l_forked_branch_last_block->block_hash, &l_block_prev_hash)){
                         pthread_rwlock_unlock(& PVT(l_blocks)->rwlock);
                         return ATOM_ACCEPT;
diff --git a/modules/type/blocks/include/dap_chain_block_cache.h b/modules/type/blocks/include/dap_chain_block_cache.h
index b7cdf1e380..a5166c3698 100644
--- a/modules/type/blocks/include/dap_chain_block_cache.h
+++ b/modules/type/blocks/include/dap_chain_block_cache.h
@@ -71,6 +71,12 @@ typedef struct dap_chain_block_cache {
     UT_hash_handle hh;
 } dap_chain_block_cache_t;
 
+
+typedef struct dap_chain_block_forked_branch {
+    dap_chain_block_cache_t *connected_block; // pointer to a block connected with this forked branch
+    dap_list_t *forked_branch_atoms;
+} dap_chain_block_forked_branch_t;
+
 int dap_chain_block_cache_init();
 void dap_chain_block_cache_deinit();
 
diff --git a/modules/type/blocks/tests/dap_chain_blocks_test.c b/modules/type/blocks/tests/dap_chain_blocks_test.c
index 9a8a9db06e..15c8487040 100644
--- a/modules/type/blocks/tests/dap_chain_blocks_test.c
+++ b/modules/type/blocks/tests/dap_chain_blocks_test.c
@@ -8,6 +8,41 @@
 #include "dap_chain_cs.h"
 // #include "dap_chain_cs_blocks.h"
 
+dap_hash_fast_t dap_chain_block_test_add_new_block (dap_hash_fast_t *a_prev_block_hash, dap_chain_t *a_chain)
+{
+    size_t l_block_size = 0;
+    dap_hash_fast_t l_block_hash = {};
+    dap_chain_block_t * l_block = dap_chain_block_new(a_prev_block_hash, &l_block_size);
+    dap_assert_PIF(l_block != NULL, "Creating of block:");
+    dap_hash_fast(l_block, l_block_size, &l_block_hash);
+    // dap_test_msg("Created genesis block %s", dap_chain_hash_fast_to_str_static(&l_block_hash));
+    dap_chain_atom_verify_res_t ret_val = a_chain->callback_atom_add(a_chain, (dap_chain_atom_ptr_t)l_block, l_block_size, &l_block_hash);
+    dap_assert_PIF( (ret_val == ATOM_ACCEPT || ret_val == ATOM_FORK), "Adding of block: ");
+
+    return l_block_hash;
+}
+
+bool dap_chain_block_test_compare_chain_hash_lists(dap_chain_t* a_chain, dap_list_t* a_atoms_hash_list)
+{
+    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 = a_chain->callback_atom_iter_create(a_chain, l_cell_id, NULL);
+    dap_list_t *l_branch_temp = NULL;
+    dap_chain_atom_ptr_t l_atom = a_chain->callback_atom_iter_get(l_iter, DAP_CHAIN_ITER_OP_FIRST, &l_atom_size_from_iter);
+    for (dap_list_t *l_branch_temp = a_atoms_hash_list; l_branch_temp && l_atom; 
+        l_branch_temp = l_branch_temp->next, l_atom = a_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));
+        if (!dap_hash_fast_compare(l_iter->cur_hash, (dap_hash_fast_t*)l_branch_temp->data)){
+            a_chain->callback_atom_iter_delete(l_iter);
+            return false;
+        }
+
+    }
+    a_chain->callback_atom_iter_delete(l_iter);
+    return true;
+}
+
 void dap_chain_blocks_test()
 {
     dap_test_msg("Start of cs block testing...");
@@ -24,142 +59,94 @@ void dap_chain_blocks_test()
     dap_config_t l_cfg = {};
     dap_assert_PIF(dap_chain_cs_create(l_chain, &l_cfg) == 0, "Chain cs creating: ");
 
-    size_t l_block_size = 0;
-    dap_chain_block_t *l_block = NULL;
     dap_hash_fast_t l_forked_block_hash = {};
     dap_hash_fast_t l_block_hash = {};
     dap_list_t *l_first_branch_atoms_list = NULL;
     dap_list_t *l_second_branch_atoms_list = NULL;
+    dap_list_t *l_third_branch_atoms_list = NULL;
 
-    l_block = dap_chain_block_new(NULL, &l_block_size);
-    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 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_test_msg("Add genesis block...");
+    l_block_hash = dap_chain_block_test_add_new_block (NULL, l_chain);
     dap_hash_fast_t *l_block_hash_copy = DAP_DUP(&l_block_hash);
     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_third_branch_atoms_list = dap_list_append(l_third_branch_atoms_list, l_block_hash_copy);
 
-    l_block = dap_chain_block_new(&l_block_hash, &l_block_size);
-    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 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: ");
+    dap_test_msg("Add second block...");
+    l_block_hash = dap_chain_block_test_add_new_block (&l_block_hash, l_chain);
     l_block_hash_copy = DAP_DUP(&l_block_hash);
     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_third_branch_atoms_list = dap_list_append(l_third_branch_atoms_list, l_block_hash_copy);
     l_forked_block_hash = l_block_hash;
 
+    dap_test_msg("Add 2 blocks to main branch...");
     for (int i = 0; i < 2; i++){
-        l_block = dap_chain_block_new(&l_block_hash, &l_block_size);
-        // 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_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(&l_block_hash);
+        l_block_hash = dap_chain_block_test_add_new_block (&l_block_hash, l_chain);
+        l_block_hash_copy = DAP_DUP(&l_block_hash);
         l_first_branch_atoms_list = dap_list_append(l_first_branch_atoms_list, l_block_hash_copy);
     }
     
+    dap_assert_PIF(dap_chain_block_test_compare_chain_hash_lists(l_chain, l_first_branch_atoms_list), "Check chain after atoms adding to the main branch ");
 
-    // 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_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_FORK, "Adding of forked block: ");
+    /* ========================== Forked branches testing ======================= */
+    /* ========================== Add first forked branch ======================= */
+    dap_test_msg("Add forked branch...");
+    l_block_hash = dap_chain_block_test_add_new_block (&l_forked_block_hash, l_chain);
     l_block_hash_copy = DAP_DUP(&l_block_hash);
     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);
-    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: ");
-    }
-
-
-    // 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_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_FORK, "Adding of forked block: ");
+    dap_test_msg("Add another atom to the forked branch...");
+    l_block_hash = dap_chain_block_test_add_new_block (&l_block_hash, l_chain);
     l_block_hash_copy = DAP_DUP(&l_block_hash);
     l_second_branch_atoms_list = dap_list_append(l_second_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_assert_PIF(dap_chain_block_test_compare_chain_hash_lists(l_chain, l_first_branch_atoms_list), "Check branches is not switched: ");
 
-    // 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_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_FORK, "Adding of forked block: ");
+    dap_test_msg("Add third atom to the forked branch...");
+    l_block_hash = dap_chain_block_test_add_new_block (&l_block_hash, l_chain);
     l_block_hash_copy = DAP_DUP(&l_block_hash);
     l_second_branch_atoms_list = dap_list_append(l_second_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_assert_PIF(dap_chain_block_test_compare_chain_hash_lists(l_chain, l_second_branch_atoms_list), "Check branches is switched: ");
 
-    // 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_FORK, "Adding of forked block: ");
+    dap_test_msg("Add block to former main branch");
+    l_block_hash = dap_chain_block_test_add_new_block ((dap_hash_fast_t*)dap_list_last(l_first_branch_atoms_list)->data, l_chain);
     l_block_hash_copy = DAP_DUP(&l_block_hash);
     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_assert_PIF(dap_chain_block_test_compare_chain_hash_lists(l_chain, l_second_branch_atoms_list), "Check branches is not switched: ");
 
-    // 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_FORK, "Adding of forked block: ");
+
+    dap_test_msg("Add another block to former main branch");
+    l_block_hash = dap_chain_block_test_add_new_block (&l_block_hash, l_chain);
     l_block_hash_copy = DAP_DUP(&l_block_hash);
     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_assert_PIF(dap_chain_block_test_compare_chain_hash_lists(l_chain, l_first_branch_atoms_list), "Check branches is switched: ");
+
+
+    /* ========================== Add second forked branch ======================= */
+    dap_test_msg("Add atom to second forked branch...");
+    l_block_hash = dap_chain_block_test_add_new_block (&l_forked_block_hash, l_chain);
+    l_block_hash_copy = DAP_DUP(&l_block_hash);
+    l_third_branch_atoms_list = dap_list_append(l_third_branch_atoms_list, l_block_hash_copy);
+
+    for (int i = 0; i < 3; i++){
+        dap_test_msg("Add atom to second forked branch...");
+        l_block_hash = dap_chain_block_test_add_new_block (&l_block_hash, l_chain);
+        l_block_hash_copy = DAP_DUP(&l_block_hash);
+        l_third_branch_atoms_list = dap_list_append(l_third_branch_atoms_list, l_block_hash_copy);
     }
 
-    dap_pass_msg("Fork handling test: ")
+    dap_assert_PIF(dap_chain_block_test_compare_chain_hash_lists(l_chain, l_first_branch_atoms_list), "Check branches is not switched: ");
 
-    l_chain->callback_atom_iter_delete(l_iter);
+    dap_test_msg("Add 5th atom to second forked branch...");
+    l_block_hash = dap_chain_block_test_add_new_block (&l_block_hash, l_chain);
+    l_block_hash_copy = DAP_DUP(&l_block_hash);
+    l_third_branch_atoms_list = dap_list_append(l_third_branch_atoms_list, l_block_hash_copy);
 
-    
+    dap_assert_PIF(dap_chain_block_test_compare_chain_hash_lists(l_chain, l_third_branch_atoms_list), "Check branches is switched: ");
 
+    dap_pass_msg("Fork handling test: ")
 }
\ No newline at end of file
-- 
GitLab