From c1c8413cccbc60920e048ef91155fed02f4cc644 Mon Sep 17 00:00:00 2001
From: Roman Khlopkov <roman.khlopkov@demlabs.net>
Date: Mon, 27 Sep 2021 15:06:44 +0000
Subject: [PATCH] hotfix-4943

---
 modules/chain/dap_chain_ledger.c              | 15 +--
 modules/consensus/none/dap_chain_cs_none.c    | 14 +--
 modules/global-db/dap_chain_global_db.c       | 99 +++++++++++--------
 .../global-db/dap_chain_global_db_driver.c    |  2 +
 modules/global-db/dap_chain_global_db_hist.c  |  5 +-
 modules/mempool/dap_chain_mempool.c           |  4 +-
 modules/net/dap_chain_net.c                   |  2 +-
 modules/net/dap_chain_node_cli_cmd.c          |  1 -
 8 files changed, 83 insertions(+), 59 deletions(-)

diff --git a/modules/chain/dap_chain_ledger.c b/modules/chain/dap_chain_ledger.c
index 4bea5bc0e3..03a5b5ae66 100644
--- a/modules/chain/dap_chain_ledger.c
+++ b/modules/chain/dap_chain_ledger.c
@@ -2245,6 +2245,7 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx,
             } else {
                 wallet_balance = DAP_NEW_Z(dap_ledger_wallet_balance_t);
                 wallet_balance->key = l_wallet_balance_key;
+                strcpy(wallet_balance->token_ticker, l_token_ticker);
                 uint128_t l_add = dap_chain_uint128_from(l_value);
                 wallet_balance->balance = dap_uint128_add(wallet_balance->balance, l_add);
                 if(s_debug_more)
@@ -2410,7 +2411,7 @@ void dap_chain_ledger_purge(dap_ledger_t *a_ledger)
         DAP_DELETE(l_item_current->tx);
         HASH_DEL(l_ledger_priv->ledger_items, l_item_current);
         dap_chain_hash_fast_to_str(&l_item_current->tx_hash_fast, l_hash_str, l_hash_str_size);
-        dap_chain_global_db_gr_del(l_hash_str, l_gdb_group);
+        dap_chain_global_db_gr_del(dap_strdup(l_hash_str), l_gdb_group);
         DAP_DELETE(l_item_current);
     }
     DAP_DELETE(l_gdb_group);
@@ -2420,7 +2421,7 @@ void dap_chain_ledger_purge(dap_ledger_t *a_ledger)
     HASH_ITER(hh, l_ledger_priv->treshold_txs, l_item_current, l_item_tmp) {
         HASH_DEL(l_ledger_priv->treshold_txs, l_item_current);
         dap_chain_hash_fast_to_str(&l_item_current->tx_hash_fast, l_hash_str, l_hash_str_size);
-        dap_chain_global_db_gr_del(l_hash_str, l_gdb_group);
+        dap_chain_global_db_gr_del(dap_strdup(l_hash_str), l_gdb_group);
         DAP_DELETE(l_item_current->tx);
         DAP_DELETE(l_item_current);
     }
@@ -2432,7 +2433,6 @@ void dap_chain_ledger_purge(dap_ledger_t *a_ledger)
     HASH_ITER(hh, l_ledger_priv->balance_accounts, l_balance_current, l_balance_tmp) {
         HASH_DEL(l_ledger_priv->balance_accounts, l_balance_current);
         dap_chain_global_db_gr_del(l_balance_current->key, l_gdb_group);
-        DAP_DELETE(l_balance_current->key);
         DAP_DELETE(l_balance_current);
     }
     DAP_DELETE(l_gdb_group);
@@ -2443,7 +2443,7 @@ void dap_chain_ledger_purge(dap_ledger_t *a_ledger)
     HASH_ITER(hh, l_ledger_priv->treshold_emissions, l_emission_current, l_emission_tmp) {
         HASH_DEL(l_ledger_priv->treshold_emissions, l_emission_current);
         dap_chain_hash_fast_to_str(&l_emission_current->datum_token_emission_hash, l_hash_str, l_hash_str_size);
-        dap_chain_global_db_gr_del(l_hash_str, l_emissions_gdb_group);
+        dap_chain_global_db_gr_del(dap_strdup(l_hash_str), l_emissions_gdb_group);
         DAP_DELETE(l_emission_current->datum_token_emission);
         DAP_DELETE(l_emission_current);
     }
@@ -2457,12 +2457,12 @@ void dap_chain_ledger_purge(dap_ledger_t *a_ledger)
         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_chain_hash_fast_to_str(&l_emission_current->datum_token_emission_hash, l_hash_str, l_hash_str_size);
-            dap_chain_global_db_gr_del(l_hash_str, l_emissions_gdb_group);
+            dap_chain_global_db_gr_del(dap_strdup(l_hash_str), l_emissions_gdb_group);
             DAP_DELETE(l_emission_current->datum_token_emission);
             DAP_DELETE(l_emission_current);
         }
         pthread_rwlock_unlock(&l_token_current->token_emissions_rwlock);
-        dap_chain_global_db_gr_del(l_token_current->ticker, l_gdb_group);
+        dap_chain_global_db_gr_del(dap_strdup(l_token_current->ticker), l_gdb_group);
         DAP_DELETE(l_token_current->datum_token);
         pthread_rwlock_destroy(&l_token_current->token_emissions_rwlock);
         DAP_DELETE(l_token_current);
@@ -2560,6 +2560,9 @@ uint128_t dap_chain_ledger_calc_balance(dap_ledger_t *a_ledger, const dap_chain_
         if(s_debug_more)
             log_it (L_INFO,"Found address in cache with balance %"DAP_UINT64_FORMAT_U"", l_balance_item->balance);
         l_ret = l_balance_item->balance;
+    } else {
+        if (s_debug_more)
+            log_it (L_WARNING, "Balance item %s not found", l_wallet_balance_key);
     }
     DAP_DELETE(l_addr);
     DAP_DELETE(l_wallet_balance_key);
diff --git a/modules/consensus/none/dap_chain_cs_none.c b/modules/consensus/none/dap_chain_cs_none.c
index ca35315759..a4ece1bc76 100644
--- a/modules/consensus/none/dap_chain_cs_none.c
+++ b/modules/consensus/none/dap_chain_cs_none.c
@@ -317,23 +317,19 @@ static dap_chain_atom_verify_res_t s_chain_callback_atom_add(dap_chain_t * a_cha
     switch (l_datum->header.type_id) {
         case DAP_CHAIN_DATUM_TOKEN_DECL:{
             dap_chain_datum_token_t *l_token = (dap_chain_datum_token_t*) l_datum->data;
-            dap_chain_ledger_token_load(a_chain->ledger,l_token, l_datum->header.data_size);
+            if (dap_chain_ledger_token_load(a_chain->ledger,l_token, l_datum->header.data_size))
+                return ATOM_REJECT;
         }break;
         case DAP_CHAIN_DATUM_TOKEN_EMISSION: {
             dap_chain_datum_token_emission_t *l_token_emission = (dap_chain_datum_token_emission_t*) l_datum->data;
-            dap_chain_ledger_token_emission_load(a_chain->ledger, l_token_emission, l_datum->header.data_size);
+            if (dap_chain_ledger_token_emission_load(a_chain->ledger, l_token_emission, l_datum->header.data_size))
+                return ATOM_REJECT;
         }break;
         case DAP_CHAIN_DATUM_TX:{
             dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*) l_datum->data;
-            //if ( !l_gdb_priv->is_load_mode ) // If its not load module but mempool proc
-            //    l_tx->header.ts_created = time(NULL);
-            //if(dap_chain_datum_tx_get_size(l_tx) == l_datum->header.data_size){
-
-            // don't save bad transactions to base
+            // No trashhold herr, don't save bad transactions to base
             if(dap_chain_ledger_tx_load(a_chain->ledger, l_tx) != 1)
                 return ATOM_REJECT;
-            //}else
-            //    return -2;
         }break;
         default: return ATOM_REJECT;
     }
diff --git a/modules/global-db/dap_chain_global_db.c b/modules/global-db/dap_chain_global_db.c
index ae0b6c77d3..6f55fe6c1b 100644
--- a/modules/global-db/dap_chain_global_db.c
+++ b/modules/global-db/dap_chain_global_db.c
@@ -468,32 +468,42 @@ static sync_group_item_t *find_item_by_mask(sync_group_item_t *a_items, const ch
 
 void dap_global_db_obj_track_history(void* a_store_data)
 {
-    if (!s_track_history)
-        return;
     dap_store_obj_t *l_obj = (dap_store_obj_t *)a_store_data;
     sync_group_item_t *l_sync_group_item = find_item_by_mask(s_sync_group_items, l_obj->group);
-    if(l_sync_group_item) {
-        lock();
-        dap_db_history_add((char)l_obj->type, l_obj, 1, l_sync_group_item->group_name_for_history);
-        unlock();
+    if (l_sync_group_item) {
         if(l_sync_group_item->callback_notify) {
-            if(l_obj) {
-                l_sync_group_item->callback_notify(l_sync_group_item->callback_arg,
+             l_sync_group_item->callback_notify(l_sync_group_item->callback_arg,
                         (const char)l_obj->type,
                         l_obj->group, l_obj->key,
                         l_obj->value, l_obj->value_len);
-            }
+        }
+        if (!s_track_history) {
+            lock();
+            dap_db_history_add((char)l_obj->type, l_obj, 1, l_sync_group_item->group_name_for_history);
+            unlock();
+        } else {
+            DAP_DELETE(l_obj->key);
+            DAP_DEL_Z(l_obj->value);
         }
     } else { // looking for extra group
         sync_group_item_t *l_sync_extra_group_item = find_item_by_mask(s_sync_group_extra_items, l_obj->group);
         if(l_sync_extra_group_item) {
-            lock();
-            dap_db_history_add((char)l_obj->type, l_obj, 1, l_sync_extra_group_item->group_name_for_history);
-            unlock();
-            if(l_sync_extra_group_item->callback_notify)
+            if(l_sync_extra_group_item->callback_notify) {
                 l_sync_extra_group_item->callback_notify(l_sync_extra_group_item->callback_arg,
                         (const char)l_obj->type, l_obj->group, l_obj->key,
                         l_obj->value, l_obj->value_len);
+            }
+            if (!s_track_history) {
+                lock();
+                dap_db_history_add((char)l_obj->type, l_obj, 1, l_sync_extra_group_item->group_name_for_history);
+                unlock();
+            } else {
+                DAP_DELETE(l_obj->key);
+                DAP_DEL_Z(l_obj->value);
+            }
+        } else {
+            DAP_DELETE(l_obj->key);
+            DAP_DEL_Z(l_obj->value);
         }
     }
 }
@@ -512,9 +522,9 @@ bool dap_chain_global_db_gr_set(char *a_key, void *a_value, size_t a_value_len,
 {
     dap_store_obj_t store_data;
     memset(&store_data, 0, sizeof(dap_store_obj_t));
-    store_data.key = a_key;
-    store_data.value = a_value;
+    store_data.key = dap_strdup(a_key);
     store_data.value_len = (a_value_len == (size_t) -1) ? dap_strlen((const char*) a_value) : a_value_len;
+    store_data.value = store_data.value_len ? DAP_DUP_SIZE(a_value, store_data.value_len) : NULL;
     store_data.group = (char*)a_group;
     store_data.timestamp = time(NULL);
     lock();
@@ -524,9 +534,13 @@ bool dap_chain_global_db_gr_set(char *a_key, void *a_value, size_t a_value_len,
     // Extract prefix if added successfuly, add history log and call notify callback if present
     if(!l_res) {
         // delete info about the deleted entry from the base if one present
-        global_db_gr_del_del(dap_strdup(store_data.key), store_data.group);
+        global_db_gr_del_del(dap_strdup(a_key), a_group);
+        store_data.value = a_value;
+        store_data.key = a_key;
         dap_global_db_obj_track_history(&store_data);
     } else {
+        DAP_DEL_Z(a_value);
+        DAP_DELETE(a_key);
         log_it(L_ERROR, "Save error: %d", l_res);
     }
 
@@ -547,7 +561,7 @@ bool dap_chain_global_db_gr_del(char *a_key,const char *a_group)
         return NULL;
     dap_store_obj_t store_data;
     memset(&store_data, 0, sizeof(dap_store_obj_t));
-    store_data.key = a_key;
+    store_data.key = dap_strdup(a_key);
     store_data.group = (char*)a_group;
     lock();
     int l_res = dap_chain_global_db_driver_delete(&store_data, 1);
@@ -558,7 +572,10 @@ bool dap_chain_global_db_gr_del(char *a_key,const char *a_group)
     }
     // do not add to history if l_res=1 (already deleted)
     if (!l_res) {
+        store_data.key = a_key;
         dap_global_db_obj_track_history(&store_data);
+    } else {
+        DAP_DELETE(a_key);
     }
     return !l_res;
 }
@@ -574,21 +591,34 @@ bool dap_chain_global_db_obj_save(void* a_store_data, size_t a_objs_count)
     if(!a_objs_count)
         return true;
 
+    char *l_keys[a_objs_count];
+    void *l_vals[a_objs_count];
+    for(size_t i = 0; i < a_objs_count; i++) {
+        dap_store_obj_t *l_store_obj = (dap_store_obj_t *)a_store_data + i;
+        l_keys[i] = dap_strdup(l_store_obj->key);
+        l_vals[i] = DAP_DUP_SIZE(l_store_obj->value, l_store_obj->value_len);
+    }
     lock();
     int l_res = dap_chain_global_db_driver_appy(a_store_data, a_objs_count);
     unlock();
 
     for(size_t i = 0; i < a_objs_count; i++) {
-        dap_store_obj_t *a_store_obj = (dap_store_obj_t *)a_store_data + i;
-        if (a_store_obj->type == 'a' && !l_res)
+        dap_store_obj_t *l_store_obj = (dap_store_obj_t *)a_store_data + i;
+        l_store_obj->key = l_keys[i];
+        l_store_obj->value = l_vals[i];
+        if (l_store_obj->type == 'a' && !l_res)
             // delete info about the deleted entry from the base if one present
-            global_db_gr_del_del(a_store_obj->key, a_store_obj->group);
-        else if (a_store_obj->type == 'd' && l_res >= 0)
+            global_db_gr_del_del(dap_strdup(l_store_obj->key), l_store_obj->group);
+        else if (l_store_obj->type == 'd' && l_res >= 0)
             // add to Del group
-            global_db_gr_del_add(a_store_obj->key, a_store_obj->group, a_store_obj->timestamp);
-        if (!l_res)
-        // Extract prefix if added successfuly, add history log and call notify callback if present
-        dap_global_db_obj_track_history(a_store_obj);
+            global_db_gr_del_add(dap_strdup(l_store_obj->key), l_store_obj->group, l_store_obj->timestamp);
+        if (!l_res) {
+            // Extract prefix if added successfuly, add history log and call notify callback if present
+            dap_global_db_obj_track_history(l_store_obj);
+        } else {
+            DAP_DELETE(l_store_obj->key);
+            DAP_DELETE(l_store_obj->value);
+        }
     }
     return !l_res;
 }
@@ -596,6 +626,8 @@ bool dap_chain_global_db_obj_save(void* a_store_data, size_t a_objs_count)
 bool dap_chain_global_db_gr_save(dap_global_db_obj_t* a_objs, size_t a_objs_count, const char *a_group)
 {
     dap_store_obj_t *l_store_data = DAP_NEW_Z_SIZE(dap_store_obj_t, a_objs_count * sizeof(struct dap_store_obj));
+    if (!l_store_data)
+            return false;
     time_t l_timestamp = time(NULL);
     for(size_t q = 0; q < a_objs_count; ++q) {
         dap_store_obj_t *store_data_cur = l_store_data + q;
@@ -606,20 +638,9 @@ bool dap_chain_global_db_gr_save(dap_global_db_obj_t* a_objs, size_t a_objs_coun
         store_data_cur->value_len = a_obj_cur->value_len;
         store_data_cur->timestamp = l_timestamp;
     }
-    if(l_store_data) {
-        lock();
-        //log_it(L_DEBUG,"Added %u objects", a_objs_count);
-        int l_res = dap_chain_global_db_driver_add(l_store_data, a_objs_count);
-        unlock();
-        if(!l_res) {    
-            for(size_t i = 0; i < a_objs_count; i++) {
-                dap_global_db_obj_track_history(l_store_data + i);
-            }
-        }
-        DAP_DELETE(l_store_data);
-        return !l_res;
-    }
-    return false;
+    int l_res = dap_chain_global_db_obj_save(l_store_data, a_objs_count);
+    DAP_DELETE(l_store_data);
+    return l_res;
 }
 
 bool dap_chain_global_db_save(dap_global_db_obj_t* a_objs, size_t a_objs_count)
diff --git a/modules/global-db/dap_chain_global_db_driver.c b/modules/global-db/dap_chain_global_db_driver.c
index ed6511d71d..eddcfa7049 100644
--- a/modules/global-db/dap_chain_global_db_driver.c
+++ b/modules/global-db/dap_chain_global_db_driver.c
@@ -405,10 +405,12 @@ int dap_chain_global_db_driver_appy(pdap_store_obj_t a_store_obj, size_t a_store
             if(l_ret_tmp == 1) {
                 log_it(L_INFO, "item is missing (may be already deleted) %s/%s\n", l_store_obj_cur->group, l_store_obj_cur->key);
                 l_ret = 1;
+                break;
             }
             if(l_ret_tmp < 0) {
                 log_it(L_ERROR, "Can't write item %s/%s (code %d)\n", l_store_obj_cur->group, l_store_obj_cur->key, l_ret_tmp);
                 l_ret -= 1;
+                break;
             }
         }
 
diff --git a/modules/global-db/dap_chain_global_db_hist.c b/modules/global-db/dap_chain_global_db_hist.c
index 66a46cca55..4e79eeda97 100644
--- a/modules/global-db/dap_chain_global_db_hist.c
+++ b/modules/global-db/dap_chain_global_db_hist.c
@@ -101,6 +101,10 @@ bool dap_db_history_add(char a_type, pdap_store_obj_t a_store_obj, size_t a_dap_
         }
         l_keys[i] = NULL;
         l_rec.keys = dap_strjoinv(GLOBAL_DB_HIST_KEY_SEPARATOR, l_keys);
+        for(i = 0; i < a_dap_store_count; i++) {
+            DAP_DELETE(l_keys[i]);
+            DAP_DEL_Z(a_store_obj[i].value);
+        }
         DAP_DELETE(l_keys);
     }
 
@@ -117,7 +121,6 @@ bool dap_db_history_add(char a_type, pdap_store_obj_t a_store_obj, size_t a_dap_
     int l_res = dap_chain_global_db_driver_add(&l_store_data, 1);
     if(l_rec.keys_count > 1)
         DAP_DELETE(l_rec.keys);
-    DAP_DELETE(l_str);
     if(!l_res)
         return true;
     return false;
diff --git a/modules/mempool/dap_chain_mempool.c b/modules/mempool/dap_chain_mempool.c
index b617fc9988..8f93e585f9 100644
--- a/modules/mempool/dap_chain_mempool.c
+++ b/modules/mempool/dap_chain_mempool.c
@@ -334,12 +334,12 @@ int dap_chain_mempool_tx_create_massive( dap_chain_t * a_chain, dap_enc_key_t *a
     //return 0;
     if( dap_chain_global_db_gr_save(l_objs,a_tx_num,l_gdb_group) ) {
         log_it(L_NOTICE, "%u transaction are placed in mempool", a_tx_num);
-        //DAP_DELETE(l_objs);
+        DAP_DELETE(l_objs);
         DAP_DELETE(l_gdb_group);
         return 0;
     }else{
         log_it(L_ERROR, "Can't place %u transactions  in mempool", a_tx_num);
-        //DAP_DELETE(l_objs);
+        DAP_DELETE(l_objs);
         DAP_DELETE(l_gdb_group);
         return -4;
     }
diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c
index b5de41884c..493be4d7d1 100644
--- a/modules/net/dap_chain_net.c
+++ b/modules/net/dap_chain_net.c
@@ -1717,7 +1717,7 @@ int s_net_load(const char * a_net_name, uint16_t a_acl_idx)
                     l_pub_key_data = dap_enc_key_serealize_pub_key(l_cert->enc_key, &l_pub_key_data_size);
                     // save pub key
                     if(l_pub_key_data && l_pub_key_data_size > 0)
-                        dap_chain_global_db_gr_set(dap_strdup("cur-node-addr-pkey"), (uint8_t*) l_pub_key_data, l_pub_key_data_size,
+                        dap_chain_global_db_gr_set(dap_strdup("cur-node-addr-pkey"), DAP_DUP_SIZE(l_pub_key_data, l_pub_key_data_size), l_pub_key_data_size,
                         GROUP_LOCAL_NODE_ADDR);
                 }
             }
diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c
index 62b073dcd2..a4f7858855 100644
--- a/modules/net/dap_chain_node_cli_cmd.c
+++ b/modules/net/dap_chain_node_cli_cmd.c
@@ -3369,7 +3369,6 @@ int com_token_emit(int a_argc, char ** a_argv, void *a_arg_func, char ** a_str_r
         return -2;
     }
     DAP_DELETE(str_reply_tmp);
-    DAP_DELETE(l_datum_tx);
     DAP_DELETE(l_addr);
     return 0;
 }
-- 
GitLab