From b9cf41929f5be29cbda2e6ad0b0ffe3d6aef558c Mon Sep 17 00:00:00 2001
From: "roman.padenkov" <roman.padenkov@demlabs.net>
Date: Fri, 24 Mar 2023 10:49:31 +0000
Subject: [PATCH] Hotfix 8350

---
 modules/mempool/dap_chain_mempool.c       |  8 +++-
 modules/type/blocks/dap_chain_cs_blocks.c | 57 ++++++++++++++---------
 2 files changed, 42 insertions(+), 23 deletions(-)

diff --git a/modules/mempool/dap_chain_mempool.c b/modules/mempool/dap_chain_mempool.c
index 728049abe1..b8e892c4f6 100644
--- a/modules/mempool/dap_chain_mempool.c
+++ b/modules/mempool/dap_chain_mempool.c
@@ -286,7 +286,13 @@ char *dap_chain_mempool_tx_coll_fee_create(dap_enc_key_t *a_key_from,const dap_c
     dap_chain_addr_t            l_addr_fee = {};
     dap_chain_t                 *l_chain = NULL;
 
-    l_chain = DAP_CHAIN_CS_BLOCKS((dap_chain_block_cache_t *)a_block_list->data)->chain;
+    if(a_block_list)
+        l_chain = DAP_CHAIN_CS_BLOCKS((dap_chain_block_cache_t *)a_block_list->data)->chain;
+    else
+    {
+        log_it(L_WARNING, "There aren't block hash");
+        return NULL;
+    }
     bool l_net_fee_used = dap_chain_net_tx_get_fee(l_chain->net_id, &l_net_fee, &l_addr_fee);
     //add tx
     if (NULL == (l_tx = dap_chain_datum_tx_create())) {
diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c
index 43623741f6..bff5afaabb 100644
--- a/modules/type/blocks/dap_chain_cs_blocks.c
+++ b/modules/type/blocks/dap_chain_cs_blocks.c
@@ -66,6 +66,7 @@ typedef struct dap_chain_cs_blocks_pvt
     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;
 
     uint64_t blocks_count;
     uint64_t difficulty;
@@ -119,7 +120,7 @@ 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 );  //    Get list of linked blocks
 //Get list of hashes
-static dap_list_t *s_block_parse_str_list(const char * a_hash_str,size_t * a_hash_size, dap_chain_t * l_chain);
+static dap_list_t *s_block_parse_str_list(const char * a_hash_str,size_t * a_hash_size, dap_chain_t * a_chain, dap_cert_t * a_cert);
 
 // Delete iterator
 static void s_callback_atom_iter_delete(dap_chain_atom_iter_t * a_atom_iter );                  //    Get the fisrt block
@@ -244,7 +245,13 @@ int dap_chain_cs_blocks_new(dap_chain_t * a_chain, dap_config_t * a_chain_config
         }
     }
     l_cs_blocks_pvt->is_celled = dap_config_get_item_bool_default(a_chain_config,"blocks","is_celled",false);
-
+    const char * l_static_genesis_blocks_hash_str = dap_config_get_item_str_default(a_chain_config,"blocks","static_genesis_block",NULL);
+    if ( l_static_genesis_blocks_hash_str ){
+        int lhr;
+        if ( (lhr= dap_chain_hash_fast_from_str(l_static_genesis_blocks_hash_str,&l_cs_blocks_pvt->static_genesis_block_hash) )!= 0 ){
+            log_it( L_ERROR, "Can't read hash from static_genesis_block \"%s\", ret code %d ", l_static_genesis_blocks_hash_str, lhr);
+        }
+    }
     l_cs_blocks_pvt->chunks = dap_chain_block_chunks_create(l_cs_blocks);
 
     l_cs_blocks_pvt->fill_timeout = dap_config_get_item_uint64_default(a_chain_config, "blocks", "fill_timeout", 60) * 1000; // 1 min
@@ -721,32 +728,19 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply)
                         "Corrupted certificate \"%s\" without keys certificate", l_cert_name );
                 return -20;
             }
-            dap_pkey_t *l_pub_key = NULL;
-            if(l_cert) {
-                l_pub_key = dap_pkey_from_enc_key(l_cert->enc_key);
-            }
 
             if(!l_hash_str){
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block fee collect' requires parameter '-hashes'");
                 return -21;
             }
-            l_block_list = s_block_parse_str_list(l_hash_str, &l_hashes_count,l_chain);
+            l_block_list = s_block_parse_str_list(l_hash_str, &l_hashes_count,l_chain,l_cert);
 
             if(!l_hashes_count){
                 dap_cli_server_cmd_set_reply_text(a_str_reply,
                         "Block fee collection requires at least one hash to create a transaction");
                 return -22;
             }
-            //verification of signatures of all blocks
-            for (dap_list_t *bl = l_block_list; bl; bl = bl->next) {
-                dap_chain_block_cache_t *l_block_cache = (dap_chain_block_cache_t *)bl->data;
-                dap_sign_t * l_sign = dap_chain_block_sign_get(l_block_cache->block, l_block_cache->block_size, 0);
-                if(!dap_pkey_compare_with_sign(l_pub_key, l_sign)){
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Block signature does not match certificate key");
-                    dap_list_free(l_block_list);
-                    return -23;
-                }
-            }
+
             char * l_hash_tx = dap_chain_mempool_tx_coll_fee_create(l_cert->enc_key,l_addr,l_block_list,l_fee_value,l_hash_out_type);
             if (l_hash_tx) {
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "Fee collect TX created succefully, hash=%s\n", l_hash_tx);
@@ -769,7 +763,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply)
     return ret;
 }
 
-static dap_list_t * s_block_parse_str_list(const char * a_hash_str,size_t * a_hash_size, dap_chain_t * l_chain)
+static dap_list_t * s_block_parse_str_list(const char * a_hash_str,size_t * a_hash_size, dap_chain_t * a_chain, dap_cert_t *a_cert)
 {
     dap_list_t *l_block_list = NULL;
     char * l_hashes_tmp_ptrs = NULL;
@@ -777,8 +771,12 @@ static dap_list_t * s_block_parse_str_list(const char * a_hash_str,size_t * a_ha
     char *l_hashes_str = strtok_r(l_hashes_str_dup, ",", &l_hashes_tmp_ptrs);
     dap_chain_hash_fast_t   l_hash_block;
     dap_chain_block_t       *l_block;
-    dap_chain_cs_blocks_t * l_blocks = DAP_CHAIN_CS_BLOCKS(l_chain);
+    dap_chain_cs_blocks_t * l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain);
 
+    dap_pkey_t *l_pub_key = NULL;
+    if(a_cert) {
+        l_pub_key = dap_pkey_from_enc_key(a_cert->enc_key);
+    }
     // First we just calc items
     while(l_hashes_str) {
         l_hashes_str = strtok_r(NULL, ",", &l_hashes_tmp_ptrs);
@@ -797,7 +795,7 @@ static dap_list_t * s_block_parse_str_list(const char * a_hash_str,size_t * a_ha
             return NULL;
         }
         size_t l_block_size = 0;
-        l_block = (dap_chain_block_t*) dap_chain_get_atom_by_hash( l_chain, &l_hash_block, &l_block_size);
+        l_block = (dap_chain_block_t*) dap_chain_get_atom_by_hash( a_chain, &l_hash_block, &l_block_size);
         if(!l_block)
         {
             log_it(L_WARNING,"There aren't any block by this hash");
@@ -806,7 +804,13 @@ static dap_list_t * s_block_parse_str_list(const char * a_hash_str,size_t * a_ha
             return NULL;
         }
         dap_chain_block_cache_t *l_block_cache = dap_chain_block_cs_cache_get_by_hash(l_blocks, &l_hash_block);
-        l_block_list = dap_list_append(l_block_list, l_block_cache);
+        //verification of signatures of all blocks
+        dap_sign_t * l_sign = dap_chain_block_sign_get(l_block_cache->block, l_block_cache->block_size, 0);
+        if(dap_pkey_compare_with_sign(l_pub_key, l_sign))
+            l_block_list = dap_list_append(l_block_list, l_block_cache);
+        else
+             log_it(L_WARNING,"Block %s signature does not match certificate key", l_block_cache->block_hash_str);
+
         l_hashes_str = strtok_r(NULL, ",", &l_hashes_tmp_ptrs);
         l_hashes_pos++;
     }
@@ -1093,6 +1097,8 @@ static dap_chain_atom_verify_res_t s_callback_atom_verify(dap_chain_t * a_chain,
     dap_chain_hash_fast_t l_block_anchor_hash = {0};
     uint64_t l_nonce = 0;
     uint64_t l_nonce2 = 0;
+    dap_chain_hash_fast_t l_block_hash;
+
     dap_chain_block_meta_extract(l_meta, l_meta_count,
                                         &l_block_prev_hash,
                                         &l_block_anchor_hash,
@@ -1112,10 +1118,17 @@ static dap_chain_atom_verify_res_t s_callback_atom_verify(dap_chain_t * a_chain,
     // genesis or seed mode
     if (l_is_genesis) {
         if (!l_blocks_pvt->blocks) {
+            dap_hash_fast(l_block, a_atom_size, &l_block_hash);
             if (s_seed_mode)
                 log_it(L_NOTICE, "Accepting new genesis block");
-            else
+
+            else if(dap_hash_fast_compare(&l_block_hash,&l_blocks_pvt->static_genesis_block_hash)
+                    &&!dap_hash_fast_is_blank(&l_block_hash))
                 log_it(L_NOTICE, "Accepting static genesis block");
+            else{
+                log_it(L_WARNING,"Cant accept genesis block: seed mode not enabled or hash mismatch with static genesis block in configuration");
+                return ATOM_REJECT;
+            }
         } else {
             log_it(L_WARNING,"Cant accept genesis block: already present data in blockchain");
             return ATOM_REJECT;
-- 
GitLab