From 18a97f903b71fff89ee3c76dede40dc1c0ee3998 Mon Sep 17 00:00:00 2001
From: "alexey.stratulat" <alexey.stratulat@demlabs.net>
Date: Mon, 16 Jan 2023 06:34:25 +0000
Subject: [PATCH] Backport 7693

---
 dap-sdk                             |  2 +-
 modules/type/dag/dap_chain_cs_dag.c | 61 ++++++++++++++++++++++++++---
 modules/wallet/dap_chain_wallet.c   | 10 ++---
 3 files changed, 62 insertions(+), 11 deletions(-)

diff --git a/dap-sdk b/dap-sdk
index db02d76ec8..024a62ba53 160000
--- a/dap-sdk
+++ b/dap-sdk
@@ -1 +1 @@
-Subproject commit db02d76ec8415fd426bc401eafa92c776712eb45
+Subproject commit 024a62ba532fb809e88129c9bd47a4a88e3587ac
diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c
index 53bed5336b..5925364fb9 100644
--- a/modules/type/dag/dap_chain_cs_dag.c
+++ b/modules/type/dag/dap_chain_cs_dag.c
@@ -65,6 +65,11 @@ typedef struct dap_chain_cs_dag_event_item {
     UT_hash_handle hh;
 } dap_chain_cs_dag_event_item_t;
 
+typedef struct dap_chain_cs_dag_blocked {
+    dap_chain_hash_fast_t hash;
+    UT_hash_handle hh;
+}dap_chain_cs_dag_blocked_t;
+
 
 typedef struct dap_chain_cs_dag_pvt {
     pthread_rwlock_t events_rwlock;
@@ -73,13 +78,16 @@ typedef struct dap_chain_cs_dag_pvt {
     dap_chain_cs_dag_event_item_t * events_treshold;
     dap_chain_cs_dag_event_item_t * events_treshold_conflicted;
     dap_chain_cs_dag_event_item_t * events_lasts_unlinked;
+    dap_chain_cs_dag_blocked_t *removed_events_from_treshold;
     dap_interval_timer_t mempool_timer;
+    dap_interval_timer_t treshold_fee_timer;
 } dap_chain_cs_dag_pvt_t;
 
 #define PVT(a) ((dap_chain_cs_dag_pvt_t *) a->_pvt )
 #define DAG_ROUND_CURRENT_KEY "round_current"
 
 static void s_dap_chain_cs_dag_purge(dap_chain_t *a_chain);
+static void s_dap_chain_cs_dag_threshold_free(dap_chain_cs_dag_t *a_dag);
 dap_chain_cs_dag_event_item_t* dap_chain_cs_dag_proc_treshold(dap_chain_cs_dag_t * a_dag, dap_ledger_t * a_ledger);
 
 // Atomic element organization callbacks
@@ -304,6 +312,9 @@ int dap_chain_cs_dag_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg)
     DAP_DELETE(l_current_round);
     dap_global_db_get_all_raw(l_dag->gdb_group_events_round_new, 0, 0, s_dag_rounds_events_iter, l_dag);
     PVT(l_dag)->mempool_timer = dap_interval_timer_create(15000, (dap_timer_callback_t)dap_chain_node_mempool_process_all, a_chain);
+    PVT(l_dag)->events_treshold = NULL;
+    PVT(l_dag)->events_treshold_conflicted = NULL;
+    PVT(l_dag)->treshold_fee_timer = dap_interval_timer_create(900000, (dap_timer_callback_t)s_dap_chain_cs_dag_threshold_free, l_dag);
     if (l_dag->is_single_line)
         log_it (L_NOTICE, "DAG chain initialized (single line)");
     else
@@ -312,6 +323,39 @@ int dap_chain_cs_dag_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg)
     return 0;
 }
 
+static void s_dap_chain_cs_dag_threshold_free(dap_chain_cs_dag_t *a_dag) {
+    dap_chain_cs_dag_pvt_t *l_pvt = PVT(a_dag);
+    dap_chain_cs_dag_event_item_t *l_current = NULL, *l_tmp = NULL;
+    dap_nanotime_t  l_time_cut_off = dap_nanotime_now() - dap_nanotime_from_sec(7200); //7200 sec = 2 hours.
+    pthread_rwlock_wrlock(&l_pvt->events_rwlock);
+    //Fee treshold
+    HASH_ITER(hh, l_pvt->events_treshold, l_current, l_tmp) {
+        if (l_current->ts_added < l_time_cut_off) {
+            dap_chain_cs_dag_blocked_t *l_el = DAP_NEW(dap_chain_cs_dag_blocked_t);
+            l_el->hash = l_current->hash;
+            HASH_ADD(hh, l_pvt->removed_events_from_treshold, hash, sizeof(dap_chain_hash_fast_t), l_el);
+            char *l_hash_dag = dap_hash_fast_to_str_new(&l_current->hash);
+            DAP_DELETE(l_current->event);
+            HASH_DEL(l_pvt->events_treshold, l_current);
+            DAP_DELETE(l_current);
+            log_it(L_NOTICE, "Removed DAG event with %s hash from trashold.", l_hash_dag);
+            DAP_DELETE(l_hash_dag);
+        }
+    }
+    //Fee treshold conflicted
+    HASH_ITER(hh, l_pvt->events_treshold_conflicted, l_current, l_tmp) {
+        if (l_current->ts_added < l_time_cut_off) {
+            char *l_hash_dag = dap_hash_fast_to_str_new(&l_current->hash);
+            DAP_DELETE(l_current->event);
+            HASH_DEL(l_pvt->events_treshold_conflicted, l_current);
+            DAP_DELETE(l_current);
+            log_it(L_NOTICE, "Removed DAG event with %s hash from trashold.", l_hash_dag);
+            DAP_DELETE(l_hash_dag);
+        }
+    }
+    pthread_rwlock_unlock(&l_pvt->events_rwlock);
+}
+
 static void s_dap_chain_cs_dag_purge(dap_chain_t *a_chain)
 {
     dap_chain_cs_dag_pvt_t *l_dag_pvt = PVT(DAP_CHAIN_CS_DAG(a_chain));
@@ -485,10 +529,19 @@ static dap_chain_atom_verify_res_t s_chain_callback_atom_add(dap_chain_t * a_cha
     switch (ret) {
     case ATOM_MOVE_TO_THRESHOLD:
         pthread_rwlock_wrlock(l_events_rwlock);
-        HASH_ADD(hh, PVT(l_dag)->events_treshold, hash, sizeof(l_event_item->hash), l_event_item);
+        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");
+        } else {
+            ret = ATOM_REJECT;
+            if (s_debug_more)
+                log_it(L_DEBUG, "... rejected because the atom was removed from the threshold.");
+        }
         pthread_rwlock_unlock(l_events_rwlock);
-        if(s_debug_more)
-            log_it(L_DEBUG, "... added to threshold");
         break;
     case ATOM_ACCEPT: {
         int l_consensus_check = s_dap_chain_add_atom_to_events_table(l_dag, a_chain->ledger, l_event_item);
@@ -1914,8 +1967,6 @@ static dap_list_t *s_callback_get_atoms(dap_chain_t *a_chain, size_t a_count, si
         if (l_counter >= l_offset){
             dap_chain_cs_dag_event_t *l_event = ptr->event;
             l_list = dap_list_append(l_list, l_event);
-//            void *l_size_event = DAP_NEW(size_t);
-            //memcpy(l_size_event, &ptr->event_size, sizeof(size_t));
             l_list = dap_list_append(l_list, &ptr->event_size);
         }
         l_counter++;
diff --git a/modules/wallet/dap_chain_wallet.c b/modules/wallet/dap_chain_wallet.c
index f273743b8f..78ee7b9038 100644
--- a/modules/wallet/dap_chain_wallet.c
+++ b/modules/wallet/dap_chain_wallet.c
@@ -583,12 +583,12 @@ enum {
     WALLET$SZ_IOV_NR
 };
 
-    if ( !a_wallet )
-        return  log_it(L_ERROR, "Wallet is null, can't save it to file!"), -EINVAL;
+if ( !a_wallet )
+    return  log_it(L_ERROR, "Wallet is null, can't save it to file!"), -EINVAL;
 
-    if ( a_pass )
-        if ( !(l_enc_key = dap_enc_key_new_generate(DAP_ENC_KEY_TYPE_GOST_OFB, NULL, 0, a_pass, strlen(a_pass), 0)) )
-            return  log_it(L_ERROR, "Error create key context"), -EINVAL;
+if ( a_pass )
+    if ( !(l_enc_key = dap_enc_key_new_generate(DAP_ENC_KEY_TYPE_GOST_OFB, NULL, 0, a_pass, strlen(a_pass), 0)) )
+        return  log_it(L_ERROR, "Error create key context"), -EINVAL;
 
 #ifdef DAP_OS_WINDOWS
     if ((l_fh = CreateFile(l_wallet_internal->file_name, GENERIC_WRITE, /*FILE_SHARE_READ | FILE_SHARE_WRITE */ 0, NULL, CREATE_NEW,
-- 
GitLab