From 71533e2874a59731ee9c248bb7477f13363c76f7 Mon Sep 17 00:00:00 2001
From: "P. Constantin" <papizh.konstantin@demlabs.net>
Date: Thu, 20 Feb 2025 21:34:17 +0700
Subject: [PATCH 01/10] ...

---
 modules/net/dap_chain_ledger.c | 49 ++++++++++++++--------------------
 1 file changed, 20 insertions(+), 29 deletions(-)

diff --git a/modules/net/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c
index fefa910dec..dd80d57293 100644
--- a/modules/net/dap_chain_ledger.c
+++ b/modules/net/dap_chain_ledger.c
@@ -3464,7 +3464,6 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger,
     
     if(a_tag) dap_ledger_deduct_tx_tag(a_ledger, a_tx, NULL, a_tag, a_action);
     bool l_tax_check = false;
-
     // find all previous transactions
     for (dap_list_t *it = l_list_in; it; it = it->next) {
          dap_ledger_tx_bound_t *l_bound_item = DAP_NEW_Z(dap_ledger_tx_bound_t);
@@ -3981,26 +3980,12 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger,
 
     switch ( HASH_COUNT(l_values_from_prev_tx) ) {
     case 1:
-        l_value_cur = DAP_NEW_Z(dap_ledger_tokenizer_t);
-        if ( !l_value_cur ) {
-            log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-            if ( l_list_bound_items )
-                dap_list_free_full(l_list_bound_items, NULL);
-            HASH_ITER(hh, l_values_from_prev_tx, l_value_cur, l_tmp) {
-                HASH_DEL(l_values_from_prev_tx, l_value_cur);
-                DAP_DELETE(l_value_cur);
-            }
-            return DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY;
-        }
-        dap_stpcpy(l_value_cur->token_ticker, l_token);
-        HASH_ADD_STR(l_values_from_cur_tx, token_ticker, l_value_cur);
         if (!l_main_ticker)
             l_main_ticker = l_value_cur->token_ticker;
         break;
     case 2:
-    case 3:
-        if (l_main_ticker)
-            break;
+    if (l_main_ticker)
+        break;
         HASH_FIND_STR(l_values_from_prev_tx, a_ledger->net->pub.native_ticker, l_value_cur);
         if (l_value_cur) {
             l_value_cur = l_value_cur->hh.next ? l_value_cur->hh.next : l_value_cur->hh.prev;
@@ -4008,6 +3993,7 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger,
         }
         break;
     default:
+    if (!l_main_ticker) {
         dap_list_free_full(l_list_bound_items, NULL);
         HASH_ITER(hh, l_values_from_prev_tx, l_value_cur, l_tmp) {
             HASH_DEL(l_values_from_prev_tx, l_value_cur);
@@ -4015,6 +4001,7 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger,
         }
         return DAP_LEDGER_TX_CHECK_NO_MAIN_TICKER;
     }
+    }
 
     dap_chain_net_srv_stake_item_t *l_key_item = NULL;
     if (l_tax_check) {
@@ -4136,19 +4123,23 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger,
 
     // Check for transaction consistency (sum(ins) == sum(outs))
     if ( !l_err_num && !s_check_hal(a_ledger, a_tx_hash) ) {
-        HASH_ITER(hh, l_values_from_prev_tx, l_value_cur, l_tmp) {
-            HASH_FIND_STR(l_values_from_cur_tx, l_value_cur->token_ticker, l_res);
-            if (!l_res || !EQUAL_256(l_res->sum, l_value_cur->sum) ) {
-                if (s_debug_more) {
-                    char *l_balance = dap_chain_balance_to_coins(l_res ? l_res->sum : uint256_0);
-                    char *l_balance_cur = dap_chain_balance_to_coins(l_value_cur->sum);
-                    log_it(L_ERROR, "Sum of values of out items from current tx (%s) is not equal outs from previous txs (%s) for token %s",
-                            l_balance, l_balance_cur, l_value_cur->token_ticker);
-                    DAP_DELETE(l_balance);
-                    DAP_DELETE(l_balance_cur);
+        if (HASH_COUNT(l_values_from_prev_tx) != HASH_COUNT(l_values_from_cur_tx) ) {
+            l_err_num = DAP_LEDGER_TX_CHECK_SUM_INS_NOT_EQUAL_SUM_OUTS;
+        } else {
+            HASH_ITER(hh, l_values_from_prev_tx, l_value_cur, l_tmp) {
+                HASH_FIND_STR(l_values_from_cur_tx, l_value_cur->token_ticker, l_res);
+                if (!l_res || !EQUAL_256(l_res->sum, l_value_cur->sum) ) {
+                    if (s_debug_more) {
+                        char *l_balance = dap_chain_balance_to_coins(l_res ? l_res->sum : uint256_0);
+                        char *l_balance_cur = dap_chain_balance_to_coins(l_value_cur->sum);
+                        log_it(L_ERROR, "Sum of values of out items from current tx (%s) is not equal outs from previous txs (%s) for token %s",
+                                l_balance, l_balance_cur, l_value_cur->token_ticker);
+                        DAP_DELETE(l_balance);
+                        DAP_DELETE(l_balance_cur);
+                    }
+                    l_err_num = DAP_LEDGER_TX_CHECK_SUM_INS_NOT_EQUAL_SUM_OUTS;
+                    break;
                 }
-                l_err_num = DAP_LEDGER_TX_CHECK_SUM_INS_NOT_EQUAL_SUM_OUTS;
-                break;
             }
         }
     }
-- 
GitLab


From c37b96f5616d5189ca0a00f898039dba44837b3d Mon Sep 17 00:00:00 2001
From: "P. Constantin" <papizh.konstantin@demlabs.net>
Date: Thu, 20 Feb 2025 23:04:42 +0700
Subject: [PATCH 02/10] ...

---
 modules/net/dap_chain_ledger.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/modules/net/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c
index dd80d57293..d7c46592ba 100644
--- a/modules/net/dap_chain_ledger.c
+++ b/modules/net/dap_chain_ledger.c
@@ -3984,8 +3984,8 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger,
             l_main_ticker = l_value_cur->token_ticker;
         break;
     case 2:
-    if (l_main_ticker)
-        break;
+        if (l_main_ticker)
+            break;
         HASH_FIND_STR(l_values_from_prev_tx, a_ledger->net->pub.native_ticker, l_value_cur);
         if (l_value_cur) {
             l_value_cur = l_value_cur->hh.next ? l_value_cur->hh.next : l_value_cur->hh.prev;
@@ -3993,14 +3993,14 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger,
         }
         break;
     default:
-    if (!l_main_ticker) {
-        dap_list_free_full(l_list_bound_items, NULL);
-        HASH_ITER(hh, l_values_from_prev_tx, l_value_cur, l_tmp) {
-            HASH_DEL(l_values_from_prev_tx, l_value_cur);
-            DAP_DELETE(l_value_cur);
+        if (!l_main_ticker) {
+            dap_list_free_full(l_list_bound_items, NULL);
+            HASH_ITER(hh, l_values_from_prev_tx, l_value_cur, l_tmp) {
+                HASH_DEL(l_values_from_prev_tx, l_value_cur);
+                DAP_DELETE(l_value_cur);
+            }
+            return DAP_LEDGER_TX_CHECK_NO_MAIN_TICKER;
         }
-        return DAP_LEDGER_TX_CHECK_NO_MAIN_TICKER;
-    }
     }
 
     dap_chain_net_srv_stake_item_t *l_key_item = NULL;
-- 
GitLab


From f73ae7b909e548de1d3a82c1af481ee2c9f48aeb Mon Sep 17 00:00:00 2001
From: "P. Constantin" <papizh.konstantin@demlabs.net>
Date: Thu, 20 Feb 2025 23:10:32 +0700
Subject: [PATCH 03/10] ...

---
 modules/net/dap_chain_ledger.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/modules/net/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c
index d7c46592ba..1a883dd8dd 100644
--- a/modules/net/dap_chain_ledger.c
+++ b/modules/net/dap_chain_ledger.c
@@ -4123,7 +4123,9 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger,
 
     // Check for transaction consistency (sum(ins) == sum(outs))
     if ( !l_err_num && !s_check_hal(a_ledger, a_tx_hash) ) {
-        if (HASH_COUNT(l_values_from_prev_tx) != HASH_COUNT(l_values_from_cur_tx) ) {
+        if ( HASH_COUNT(l_values_from_prev_tx) != HASH_COUNT(l_values_from_cur_tx) ) {
+            log_it(L_ERROR, "Token tickers IN and OUT mismatch: %u != %u",
+                            HASH_COUNT(l_values_from_prev_tx), HASH_COUNT(l_values_from_cur_tx));
             l_err_num = DAP_LEDGER_TX_CHECK_SUM_INS_NOT_EQUAL_SUM_OUTS;
         } else {
             HASH_ITER(hh, l_values_from_prev_tx, l_value_cur, l_tmp) {
-- 
GitLab


From 5c2905427db2ba32fc99163c7bd1d2bf05ef9d17 Mon Sep 17 00:00:00 2001
From: "Constantin P." <papizh.konstantin@demlabs.net>
Date: Tue, 25 Feb 2025 13:22:57 +0700
Subject: [PATCH 04/10] ...

---
 modules/wallet/dap_chain_wallet_cache.c | 93 ++++++++++++-------------
 1 file changed, 43 insertions(+), 50 deletions(-)

diff --git a/modules/wallet/dap_chain_wallet_cache.c b/modules/wallet/dap_chain_wallet_cache.c
index 7dbc8737d1..eb41af386d 100644
--- a/modules/wallet/dap_chain_wallet_cache.c
+++ b/modules/wallet/dap_chain_wallet_cache.c
@@ -681,12 +681,10 @@ static int s_save_tx_cache_for_addr(dap_chain_t *a_chain, dap_chain_addr_t *a_ad
         uint256_t l_value;
         uint8_t *l_prev_item = NULL;
         int l_prev_idx;
-        uint8_t l_item_type = TX_ITEM_TYPE_ANY;
 
         switch(*l_tx_item) {
         case TX_ITEM_TYPE_IN: {
             l_prev_tx_hash = ((dap_chain_tx_in_t*)l_tx_item)->header.tx_prev_hash;
-            l_prev_idx = ((dap_chain_tx_in_t*)l_tx_item)->header.tx_out_prev_idx;
             if ( dap_hash_fast_is_blank(&l_prev_tx_hash) )
                 continue;
             dap_chain_datum_t *l_prev_datum = a_chain->callback_datum_find_by_hash(a_chain, &l_prev_tx_hash, NULL, NULL);
@@ -695,6 +693,7 @@ static int s_save_tx_cache_for_addr(dap_chain_t *a_chain, dap_chain_addr_t *a_ad
                 log_it(L_ERROR, "Can't find previous transaction by hash \"%s\"", dap_hash_fast_to_str_static(&l_prev_tx_hash));
                 continue;
             }
+            l_prev_idx = ((dap_chain_tx_in_t*)l_tx_item)->header.tx_out_prev_idx;
             l_prev_item = dap_chain_datum_tx_item_get_nth(l_tx_prev, TX_ITEM_TYPE_OUT_ALL, l_prev_idx);
             if (!l_prev_item) {
                 log_it(L_ERROR, "Can't find output %d in tx \"%s\"", l_prev_idx, dap_hash_fast_to_str_static(&l_prev_tx_hash));
@@ -713,20 +712,16 @@ static int s_save_tx_cache_for_addr(dap_chain_t *a_chain, dap_chain_addr_t *a_ad
             default:
                 continue;
             }
-            l_item_type = TX_ITEM_TYPE_IN;
         } break;
         case TX_ITEM_TYPE_OUT_OLD:
             l_addr = ((dap_chain_tx_out_old_t*)l_tx_item)->addr;
-            l_item_type = TX_ITEM_TYPE_OUT_ALL;
             break;
         case TX_ITEM_TYPE_OUT:
             l_addr = ((dap_chain_tx_out_t*)l_tx_item)->addr;
-            l_item_type = TX_ITEM_TYPE_OUT_ALL;
             break;
         case TX_ITEM_TYPE_OUT_EXT:
             l_addr = ((dap_chain_tx_out_ext_t*)l_tx_item)->addr;
             l_multichannel = true;
-            l_item_type = TX_ITEM_TYPE_OUT_ALL;
             break;
         case TX_ITEM_TYPE_OUT_COND:
         /* Make it explicit for possible future STAKE_LOCK adoption */
@@ -737,7 +732,7 @@ static int s_save_tx_cache_for_addr(dap_chain_t *a_chain, dap_chain_addr_t *a_ad
         }
 
         if ( !m_check_addr(l_addr) ) {
-            l_out_idx += (int)(l_item_type == TX_ITEM_TYPE_OUT_ALL);
+            l_out_idx += (int)(*l_tx_item != TX_ITEM_TYPE_IN);
             continue;
         }
 
@@ -755,7 +750,7 @@ static int s_save_tx_cache_for_addr(dap_chain_t *a_chain, dap_chain_addr_t *a_ad
             
             HASH_FIND(hh, l_wallet_item->wallet_txs, a_tx_hash, sizeof(dap_hash_fast_t), l_wallet_tx_item);
             if (!l_wallet_tx_item) {
-                l_wallet_tx_item = DAP_NEW(dap_wallet_tx_cache_t);
+                l_wallet_tx_item = DAP_NEW_Z(dap_wallet_tx_cache_t);
                 *l_wallet_tx_item = (dap_wallet_tx_cache_t){ .tx_hash = *a_tx_hash, .atom_hash = *a_atom_hash, .tx = a_tx,
                     .multichannel = l_multichannel, .ret_code = a_ret_code, .srv_uid = a_srv_uid, .action = a_action };
                 dap_strncpy(l_wallet_tx_item->token_ticker, a_main_token_ticker ? a_main_token_ticker : "0", DAP_CHAIN_TICKER_SIZE_MAX);
@@ -775,48 +770,11 @@ static int s_save_tx_cache_for_addr(dap_chain_t *a_chain, dap_chain_addr_t *a_ad
         }
         default: break;
         }
-        
-
-        switch (l_item_type) {
-        case TX_ITEM_TYPE_OUT_ALL: {
-            switch (a_cache_op) {
-            case 'a': {
-                dap_wallet_tx_cache_output_t *l_out = DAP_NEW(dap_wallet_tx_cache_output_t);
-                *l_out = (dap_wallet_tx_cache_output_t){ .tx_out = l_tx_item, .tx_out_idx = l_out_idx };
-                l_wallet_tx_item->tx_wallet_outputs = dap_list_append(l_wallet_tx_item->tx_wallet_outputs, l_out);
-                /* Add unspent out to cache */ 
-                if (!a_ret_code) {
-                    dap_wallet_cache_unspent_outs_t *l_unspent_out = DAP_NEW(dap_wallet_cache_unspent_outs_t);
-                    *l_unspent_out = (dap_wallet_cache_unspent_outs_t) {
-                        .key = { .tx_hash = *a_tx_hash, .out_idx = l_out_idx },
-                        .output = l_out
-                    };
-                    dap_strncpy(l_unspent_out->token_ticker, *l_tx_item == TX_ITEM_TYPE_OUT_EXT ? ((dap_chain_tx_out_ext_t*)l_tx_item)->token
-                                : a_main_token_ticker ? a_main_token_ticker : "0", DAP_CHAIN_TICKER_SIZE_MAX);                   
-                    HASH_ADD(hh, l_wallet_item->unspent_outputs, key, sizeof(unspent_cache_hh_key), l_unspent_out);
-                }
-                ++l_out_idx;
-            } break;
-            case 'd': {
-                if ( !l_wallet_item->wallet_txs ) {
-                    HASH_DEL(s_wallets_cache, l_wallet_item);
-                    DAP_DELETE(l_wallet_item);
-                }            
-                unspent_cache_hh_key key = { .tx_hash = *a_tx_hash, .out_idx = l_out_idx };
-                dap_wallet_cache_unspent_outs_t *l_item = NULL;
-                HASH_FIND(hh, l_wallet_item->unspent_outputs, &key, sizeof(unspent_cache_hh_key), l_item);
-                if (l_item) {
-                    HASH_DEL(l_wallet_item->unspent_outputs, l_item);
-                    DAP_DELETE(l_item);
-                }
-            } break;
-            default: break;
-            }
-        } break;
-        case TX_ITEM_TYPE_IN: {
+        switch (*l_tx_item) {
+        case TX_ITEM_TYPE_IN:
             switch (a_cache_op) {
             case 'a': {
-                dap_wallet_tx_cache_input_t *l_tx_in = DAP_NEW(dap_wallet_tx_cache_input_t);
+                dap_wallet_tx_cache_input_t *l_tx_in = DAP_NEW_Z(dap_wallet_tx_cache_input_t);
                 *l_tx_in = (dap_wallet_tx_cache_input_t) { .tx_prev_hash = l_prev_tx_hash, .tx_out_prev_idx = l_prev_idx, .value = l_value };
                 l_wallet_tx_item->tx_wallet_inputs = dap_list_append(l_wallet_tx_item->tx_wallet_inputs, l_tx_in);
                 /* Delete unspent out from cache */
@@ -848,8 +806,43 @@ static int s_save_tx_cache_for_addr(dap_chain_t *a_chain, dap_chain_addr_t *a_ad
             } break;
             default: break;
             }
-        } break;
-        default: break;
+            break;
+        default:
+            switch (a_cache_op) {
+            case 'a': {
+                dap_wallet_tx_cache_output_t *l_out = DAP_NEW(dap_wallet_tx_cache_output_t);
+                *l_out = (dap_wallet_tx_cache_output_t){ .tx_out = l_tx_item, .tx_out_idx = l_out_idx };
+                l_wallet_tx_item->tx_wallet_outputs = dap_list_append(l_wallet_tx_item->tx_wallet_outputs, l_out);
+                /* Add unspent out to cache */ 
+                if (!a_ret_code) {
+                    dap_wallet_cache_unspent_outs_t *l_unspent_out = DAP_NEW(dap_wallet_cache_unspent_outs_t);
+                    *l_unspent_out = (dap_wallet_cache_unspent_outs_t) {
+                        .key = { .tx_hash = *a_tx_hash, .out_idx = l_out_idx },
+                        .output = l_out
+                    };
+                    dap_strncpy(l_unspent_out->token_ticker, *l_tx_item == TX_ITEM_TYPE_OUT_EXT ? ((dap_chain_tx_out_ext_t*)l_tx_item)->token
+                                : a_main_token_ticker ? a_main_token_ticker : "0", DAP_CHAIN_TICKER_SIZE_MAX);                   
+                    HASH_ADD(hh, l_wallet_item->unspent_outputs, key, sizeof(unspent_cache_hh_key), l_unspent_out);
+                }
+                ++l_out_idx;
+            } break;
+            case 'd': {
+                if ( !l_wallet_item->wallet_txs ) {
+                    HASH_DEL(s_wallets_cache, l_wallet_item);
+                    DAP_DELETE(l_wallet_item);
+                }            
+                unspent_cache_hh_key key = { .tx_hash = *a_tx_hash, .out_idx = l_out_idx };
+                dap_wallet_cache_unspent_outs_t *l_item = NULL;
+                HASH_FIND(hh, l_wallet_item->unspent_outputs, &key, sizeof(unspent_cache_hh_key), l_item);
+                if (l_item) {
+                    HASH_DEL(l_wallet_item->unspent_outputs, l_item);
+                    DAP_DELETE(l_item);
+                }
+            } break;
+            default:
+                break;
+            }
+            break;
         }
         pthread_rwlock_unlock(&s_wallet_cache_rwlock);
     }
-- 
GitLab


From a6420a2ede54ec688250fb0866367f9da5673461 Mon Sep 17 00:00:00 2001
From: "Constantin P." <papizh.konstantin@demlabs.net>
Date: Tue, 25 Feb 2025 19:01:49 +0700
Subject: [PATCH 05/10] ...

---
 modules/wallet/dap_chain_wallet_cache.c | 33 ++++++++++++++-----------
 1 file changed, 18 insertions(+), 15 deletions(-)

diff --git a/modules/wallet/dap_chain_wallet_cache.c b/modules/wallet/dap_chain_wallet_cache.c
index eb41af386d..027fae5cb4 100644
--- a/modules/wallet/dap_chain_wallet_cache.c
+++ b/modules/wallet/dap_chain_wallet_cache.c
@@ -746,11 +746,11 @@ static int s_save_tx_cache_for_addr(dap_chain_t *a_chain, dap_chain_addr_t *a_ad
                 l_wallet_item = DAP_NEW_Z(dap_wallet_cache_t);
                 l_wallet_item->wallet_addr = l_addr;
                 HASH_ADD(hh, s_wallets_cache, wallet_addr, sizeof(dap_chain_addr_t), l_wallet_item);
-            }
-            
-            HASH_FIND(hh, l_wallet_item->wallet_txs, a_tx_hash, sizeof(dap_hash_fast_t), l_wallet_tx_item);
+            } else
+                HASH_FIND(hh, l_wallet_item->wallet_txs, a_tx_hash, sizeof(dap_hash_fast_t), l_wallet_tx_item);
+
             if (!l_wallet_tx_item) {
-                l_wallet_tx_item = DAP_NEW_Z(dap_wallet_tx_cache_t);
+                l_wallet_tx_item = DAP_NEW(dap_wallet_tx_cache_t);
                 *l_wallet_tx_item = (dap_wallet_tx_cache_t){ .tx_hash = *a_tx_hash, .atom_hash = *a_atom_hash, .tx = a_tx,
                     .multichannel = l_multichannel, .ret_code = a_ret_code, .srv_uid = a_srv_uid, .action = a_action };
                 dap_strncpy(l_wallet_tx_item->token_ticker, a_main_token_ticker ? a_main_token_ticker : "0", DAP_CHAIN_TICKER_SIZE_MAX);
@@ -758,23 +758,25 @@ static int s_save_tx_cache_for_addr(dap_chain_t *a_chain, dap_chain_addr_t *a_ad
             }
             break;
         case 'd': {
-            if (l_wallet_item) {
-                HASH_FIND(hh, l_wallet_item->wallet_txs, a_tx_hash, sizeof(dap_hash_fast_t), l_wallet_tx_item);
-                if (l_wallet_tx_item){
-                    HASH_DEL(l_wallet_item->wallet_txs, l_wallet_tx_item);
-                    dap_list_free_full(l_wallet_tx_item->tx_wallet_inputs, NULL);
-                    dap_list_free_full(l_wallet_tx_item->tx_wallet_outputs, NULL);
-                    DAP_DELETE(l_wallet_tx_item);
-                }
+            if (!l_wallet_item)
+                continue;
+            HASH_FIND(hh, l_wallet_item->wallet_txs, a_tx_hash, sizeof(dap_hash_fast_t), l_wallet_tx_item);
+            if (l_wallet_tx_item){
+                HASH_DEL(l_wallet_item->wallet_txs, l_wallet_tx_item);
+                dap_list_free_full(l_wallet_tx_item->tx_wallet_inputs, NULL);
+                dap_list_free_full(l_wallet_tx_item->tx_wallet_outputs, NULL);
+                DAP_DELETE(l_wallet_tx_item);
             }
         }
-        default: break;
+        default:
+            continue;
         }
+
         switch (*l_tx_item) {
         case TX_ITEM_TYPE_IN:
             switch (a_cache_op) {
             case 'a': {
-                dap_wallet_tx_cache_input_t *l_tx_in = DAP_NEW_Z(dap_wallet_tx_cache_input_t);
+                dap_wallet_tx_cache_input_t *l_tx_in = DAP_NEW(dap_wallet_tx_cache_input_t);
                 *l_tx_in = (dap_wallet_tx_cache_input_t) { .tx_prev_hash = l_prev_tx_hash, .tx_out_prev_idx = l_prev_idx, .value = l_value };
                 l_wallet_tx_item->tx_wallet_inputs = dap_list_append(l_wallet_tx_item->tx_wallet_inputs, l_tx_in);
                 /* Delete unspent out from cache */
@@ -804,7 +806,8 @@ static int s_save_tx_cache_for_addr(dap_chain_t *a_chain, dap_chain_addr_t *a_ad
                     }
                 }
             } break;
-            default: break;
+            default:
+                break;
             }
             break;
         default:
-- 
GitLab


From 1e1bfb5ff1cc9ceff61bbf537c7b3e4d99d97de9 Mon Sep 17 00:00:00 2001
From: "Constantin P." <papizh.konstantin@demlabs.net>
Date: Tue, 25 Feb 2025 21:48:04 +0700
Subject: [PATCH 06/10] Errors fix

---
 modules/wallet/dap_chain_wallet_cache.c | 59 ++++++++++++++-----------
 1 file changed, 33 insertions(+), 26 deletions(-)

diff --git a/modules/wallet/dap_chain_wallet_cache.c b/modules/wallet/dap_chain_wallet_cache.c
index 027fae5cb4..8cfa5c64fb 100644
--- a/modules/wallet/dap_chain_wallet_cache.c
+++ b/modules/wallet/dap_chain_wallet_cache.c
@@ -400,8 +400,7 @@ int dap_chain_wallet_cache_tx_find_outs(dap_chain_net_t *a_net, const char *a_to
     }
 
     dap_wallet_cache_unspent_outs_t *l_item_cur = NULL, *l_tmp = NULL;
-    HASH_ITER(hh, l_wallet_item->unspent_outputs, l_item_cur, l_tmp){
-
+    HASH_ITER(hh, l_wallet_item->unspent_outputs, l_item_cur, l_tmp) {
         if (dap_strcmp(l_item_cur->token_ticker, a_token_ticker))
             continue;
         else {
@@ -491,8 +490,7 @@ int dap_chain_wallet_cache_tx_find_outs_with_val(dap_chain_net_t *a_net, const c
     }
 
     dap_wallet_cache_unspent_outs_t *l_item_cur = NULL, *l_tmp = NULL;
-    HASH_ITER(hh, l_wallet_item->unspent_outputs, l_item_cur, l_tmp){
-
+    HASH_ITER(hh, l_wallet_item->unspent_outputs, l_item_cur, l_tmp) {
         if (dap_strcmp(l_item_cur->token_ticker, a_token_ticker))
             continue;
         else {
@@ -781,8 +779,8 @@ static int s_save_tx_cache_for_addr(dap_chain_t *a_chain, dap_chain_addr_t *a_ad
                 l_wallet_tx_item->tx_wallet_inputs = dap_list_append(l_wallet_tx_item->tx_wallet_inputs, l_tx_in);
                 /* Delete unspent out from cache */
                 if (!a_ret_code) {
-                    unspent_cache_hh_key key = { .tx_hash = l_prev_tx_hash, .out_idx = l_prev_idx };
                     dap_wallet_cache_unspent_outs_t *l_item = NULL;
+                    unspent_cache_hh_key key = { .tx_hash = l_prev_tx_hash, .out_idx = l_prev_idx };
                     HASH_FIND(hh, l_wallet_item->unspent_outputs, &key, sizeof(unspent_cache_hh_key), l_item);
                     if (l_item) {
                         HASH_DEL(l_wallet_item->unspent_outputs, l_item);
@@ -795,14 +793,18 @@ static int s_save_tx_cache_for_addr(dap_chain_t *a_chain, dap_chain_addr_t *a_ad
                 HASH_FIND(hh, l_wallet_item->wallet_txs, &l_prev_tx_hash, sizeof(dap_hash_fast_t), l_wallet_prev_tx_item);
                 if ( l_wallet_prev_tx_item && !l_wallet_prev_tx_item->ret_code ) {
                     dap_wallet_tx_cache_output_t l_sought_out = { .tx_out_idx = l_prev_idx };
-                    void *l_out = dap_list_find(l_wallet_prev_tx_item->tx_wallet_outputs, &l_sought_out, s_out_idx_cmp);
-                    if (l_out) {
-                        dap_wallet_cache_unspent_outs_t *l_unspent_out = DAP_NEW_Z(dap_wallet_cache_unspent_outs_t);
-                        *l_unspent_out = (dap_wallet_cache_unspent_outs_t) { .key = { .tx_hash = l_prev_tx_hash, .out_idx = l_prev_idx },
-                            .output = l_out };
-                        dap_strncpy(l_unspent_out->token_ticker, *l_prev_item == TX_ITEM_TYPE_OUT_EXT ? ((dap_chain_tx_out_ext_t*)l_tx_item)->token
-                                    : l_wallet_prev_tx_item->token_ticker, DAP_CHAIN_TICKER_SIZE_MAX);
-                        HASH_ADD(hh, l_wallet_item->unspent_outputs, key, sizeof(unspent_cache_hh_key), l_unspent_out);
+                    dap_list_t *l_out_item = dap_list_find(l_wallet_prev_tx_item->tx_wallet_outputs, &l_sought_out, s_out_idx_cmp);
+                    if (l_out_item) {
+                        dap_wallet_cache_unspent_outs_t *l_item = NULL;
+                        unspent_cache_hh_key l_key = { .tx_hash = l_prev_tx_hash, .out_idx = l_prev_idx };
+                        HASH_FIND(hh, l_wallet_item->unspent_outputs, &l_key, sizeof(unspent_cache_hh_key), l_item);
+                        if ( !l_item ) {
+                            l_item = DAP_NEW(dap_wallet_cache_unspent_outs_t);
+                            *l_item = (dap_wallet_cache_unspent_outs_t) { .key = l_key, .output = l_out_item->data };
+                            dap_strncpy(l_item->token_ticker, *l_prev_item == TX_ITEM_TYPE_OUT_EXT ? ((dap_chain_tx_out_ext_t*)l_tx_item)->token
+                                        : l_wallet_prev_tx_item->token_ticker, DAP_CHAIN_TICKER_SIZE_MAX);
+                            HASH_ADD(hh, l_wallet_item->unspent_outputs, key, sizeof(unspent_cache_hh_key), l_item);
+                        }
                     }
                 }
             } break;
@@ -813,19 +815,24 @@ static int s_save_tx_cache_for_addr(dap_chain_t *a_chain, dap_chain_addr_t *a_ad
         default:
             switch (a_cache_op) {
             case 'a': {
-                dap_wallet_tx_cache_output_t *l_out = DAP_NEW(dap_wallet_tx_cache_output_t);
-                *l_out = (dap_wallet_tx_cache_output_t){ .tx_out = l_tx_item, .tx_out_idx = l_out_idx };
-                l_wallet_tx_item->tx_wallet_outputs = dap_list_append(l_wallet_tx_item->tx_wallet_outputs, l_out);
-                /* Add unspent out to cache */ 
-                if (!a_ret_code) {
-                    dap_wallet_cache_unspent_outs_t *l_unspent_out = DAP_NEW(dap_wallet_cache_unspent_outs_t);
-                    *l_unspent_out = (dap_wallet_cache_unspent_outs_t) {
-                        .key = { .tx_hash = *a_tx_hash, .out_idx = l_out_idx },
-                        .output = l_out
-                    };
-                    dap_strncpy(l_unspent_out->token_ticker, *l_tx_item == TX_ITEM_TYPE_OUT_EXT ? ((dap_chain_tx_out_ext_t*)l_tx_item)->token
-                                : a_main_token_ticker ? a_main_token_ticker : "0", DAP_CHAIN_TICKER_SIZE_MAX);                   
-                    HASH_ADD(hh, l_wallet_item->unspent_outputs, key, sizeof(unspent_cache_hh_key), l_unspent_out);
+                dap_wallet_tx_cache_output_t l_sought_out = { .tx_out_idx = l_out_idx };
+                if ( !dap_list_find(l_wallet_tx_item->tx_wallet_outputs, &l_sought_out, s_out_idx_cmp) ) {
+                    dap_wallet_tx_cache_output_t *l_out = DAP_NEW(dap_wallet_tx_cache_output_t);
+                    *l_out = (dap_wallet_tx_cache_output_t){ .tx_out = l_tx_item, .tx_out_idx = l_out_idx };
+                    l_wallet_tx_item->tx_wallet_outputs = dap_list_append(l_wallet_tx_item->tx_wallet_outputs, l_out);
+                    /* Add unspent out to cache */ 
+                    if (!a_ret_code) {
+                        dap_wallet_cache_unspent_outs_t *l_item = NULL;
+                        unspent_cache_hh_key l_key = { .tx_hash = *a_tx_hash, .out_idx = l_out_idx };
+                        HASH_FIND(hh, l_wallet_item->unspent_outputs, &l_key, sizeof(unspent_cache_hh_key), l_item);
+                        if ( !l_item ) {
+                            l_item = DAP_NEW(dap_wallet_cache_unspent_outs_t);
+                            *l_item = (dap_wallet_cache_unspent_outs_t) { .key = l_key, .output = l_out };
+                            dap_strncpy(l_item->token_ticker, *l_tx_item == TX_ITEM_TYPE_OUT_EXT ? ((dap_chain_tx_out_ext_t*)l_tx_item)->token
+                                    : a_main_token_ticker ? a_main_token_ticker : "0", DAP_CHAIN_TICKER_SIZE_MAX);                   
+                            HASH_ADD(hh, l_wallet_item->unspent_outputs, key, sizeof(unspent_cache_hh_key), l_item);
+                        }
+                    }
                 }
                 ++l_out_idx;
             } break;
-- 
GitLab


From 8ca171d83806e0fd18843b4eb13dce3ba3c2a004 Mon Sep 17 00:00:00 2001
From: "Constantin P." <papizh.konstantin@demlabs.net>
Date: Tue, 25 Feb 2025 21:53:01 +0700
Subject: [PATCH 07/10] ...

---
 modules/wallet/dap_chain_wallet_cache.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/modules/wallet/dap_chain_wallet_cache.c b/modules/wallet/dap_chain_wallet_cache.c
index 8cfa5c64fb..25ba1b4518 100644
--- a/modules/wallet/dap_chain_wallet_cache.c
+++ b/modules/wallet/dap_chain_wallet_cache.c
@@ -728,11 +728,10 @@ static int s_save_tx_cache_for_addr(dap_chain_t *a_chain, dap_chain_addr_t *a_ad
         default:
             continue;
         }
-
-        if ( !m_check_addr(l_addr) ) {
-            l_out_idx += (int)(*l_tx_item != TX_ITEM_TYPE_IN);
+        l_out_idx += (int)(*l_tx_item != TX_ITEM_TYPE_IN);
+        
+        if ( !m_check_addr(l_addr) )
             continue;
-        }
 
         pthread_rwlock_wrlock(&s_wallet_cache_rwlock);
         dap_wallet_cache_t *l_wallet_item = NULL;
@@ -834,7 +833,6 @@ static int s_save_tx_cache_for_addr(dap_chain_t *a_chain, dap_chain_addr_t *a_ad
                         }
                     }
                 }
-                ++l_out_idx;
             } break;
             case 'd': {
                 if ( !l_wallet_item->wallet_txs ) {
-- 
GitLab


From 7f5874d26d2f10d86503745016f1a9641d0b0fdb Mon Sep 17 00:00:00 2001
From: "Constantin P." <papizh.konstantin@demlabs.net>
Date: Tue, 25 Feb 2025 22:11:22 +0700
Subject: [PATCH 08/10] ...

---
 modules/wallet/dap_chain_wallet_cache.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modules/wallet/dap_chain_wallet_cache.c b/modules/wallet/dap_chain_wallet_cache.c
index 25ba1b4518..95b9c8a642 100644
--- a/modules/wallet/dap_chain_wallet_cache.c
+++ b/modules/wallet/dap_chain_wallet_cache.c
@@ -800,7 +800,7 @@ static int s_save_tx_cache_for_addr(dap_chain_t *a_chain, dap_chain_addr_t *a_ad
                         if ( !l_item ) {
                             l_item = DAP_NEW(dap_wallet_cache_unspent_outs_t);
                             *l_item = (dap_wallet_cache_unspent_outs_t) { .key = l_key, .output = l_out_item->data };
-                            dap_strncpy(l_item->token_ticker, *l_prev_item == TX_ITEM_TYPE_OUT_EXT ? ((dap_chain_tx_out_ext_t*)l_tx_item)->token
+                            dap_strncpy(l_item->token_ticker, *l_prev_item == TX_ITEM_TYPE_OUT_EXT ? ((dap_chain_tx_out_ext_t*)l_prev_item)->token
                                         : l_wallet_prev_tx_item->token_ticker, DAP_CHAIN_TICKER_SIZE_MAX);
                             HASH_ADD(hh, l_wallet_item->unspent_outputs, key, sizeof(unspent_cache_hh_key), l_item);
                         }
-- 
GitLab


From 3f18ecd81095a87ac25c81faea3aed6e9cd5d882 Mon Sep 17 00:00:00 2001
From: "Constantin P." <papizh.konstantin@demlabs.net>
Date: Tue, 25 Feb 2025 22:14:36 +0700
Subject: [PATCH 09/10] ...

---
 modules/wallet/dap_chain_wallet_cache.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modules/wallet/dap_chain_wallet_cache.c b/modules/wallet/dap_chain_wallet_cache.c
index 95b9c8a642..9cd4165413 100644
--- a/modules/wallet/dap_chain_wallet_cache.c
+++ b/modules/wallet/dap_chain_wallet_cache.c
@@ -663,7 +663,7 @@ static int s_save_tx_cache_for_addr(dap_chain_t *a_chain, dap_chain_addr_t *a_ad
                                     dap_hash_fast_t *a_tx_hash, dap_hash_fast_t *a_atom_hash, int a_ret_code, char* a_main_token_ticker,
                                     dap_chain_net_srv_uid_t a_srv_uid, dap_chain_tx_tag_action_type_t a_action, char a_cache_op)
 {
-    int l_ret_val = 0, l_items_cnt = 0, l_out_idx = 0, l_prev_idx;
+    int l_ret_val = 0, l_items_cnt = 0, l_out_idx = -1;
     bool l_multichannel = false;
 #define m_check_addr(addr) (                                                                                    \
     !dap_chain_addr_is_blank(&addr) && (                                                                        \
-- 
GitLab


From 088488c382b23399510b0c4a02442fbd7d3207f1 Mon Sep 17 00:00:00 2001
From: "Constantin P." <papizh.konstantin@demlabs.net>
Date: Tue, 25 Feb 2025 22:23:50 +0700
Subject: [PATCH 10/10] Yet more fixes

---
 modules/wallet/dap_chain_wallet_cache.c | 31 ++++++++++++++-----------
 1 file changed, 17 insertions(+), 14 deletions(-)

diff --git a/modules/wallet/dap_chain_wallet_cache.c b/modules/wallet/dap_chain_wallet_cache.c
index 9cd4165413..f4a70a606b 100644
--- a/modules/wallet/dap_chain_wallet_cache.c
+++ b/modules/wallet/dap_chain_wallet_cache.c
@@ -814,23 +814,26 @@ static int s_save_tx_cache_for_addr(dap_chain_t *a_chain, dap_chain_addr_t *a_ad
         default:
             switch (a_cache_op) {
             case 'a': {
+                dap_wallet_tx_cache_output_t *l_out = NULL;
                 dap_wallet_tx_cache_output_t l_sought_out = { .tx_out_idx = l_out_idx };
-                if ( !dap_list_find(l_wallet_tx_item->tx_wallet_outputs, &l_sought_out, s_out_idx_cmp) ) {
-                    dap_wallet_tx_cache_output_t *l_out = DAP_NEW(dap_wallet_tx_cache_output_t);
+                dap_list_t *l_out_item = dap_list_find(l_wallet_tx_item->tx_wallet_outputs, &l_sought_out, s_out_idx_cmp);
+                if ( !l_out_item ) {
+                    l_out = DAP_NEW(dap_wallet_tx_cache_output_t);
                     *l_out = (dap_wallet_tx_cache_output_t){ .tx_out = l_tx_item, .tx_out_idx = l_out_idx };
                     l_wallet_tx_item->tx_wallet_outputs = dap_list_append(l_wallet_tx_item->tx_wallet_outputs, l_out);
-                    /* Add unspent out to cache */ 
-                    if (!a_ret_code) {
-                        dap_wallet_cache_unspent_outs_t *l_item = NULL;
-                        unspent_cache_hh_key l_key = { .tx_hash = *a_tx_hash, .out_idx = l_out_idx };
-                        HASH_FIND(hh, l_wallet_item->unspent_outputs, &l_key, sizeof(unspent_cache_hh_key), l_item);
-                        if ( !l_item ) {
-                            l_item = DAP_NEW(dap_wallet_cache_unspent_outs_t);
-                            *l_item = (dap_wallet_cache_unspent_outs_t) { .key = l_key, .output = l_out };
-                            dap_strncpy(l_item->token_ticker, *l_tx_item == TX_ITEM_TYPE_OUT_EXT ? ((dap_chain_tx_out_ext_t*)l_tx_item)->token
-                                    : a_main_token_ticker ? a_main_token_ticker : "0", DAP_CHAIN_TICKER_SIZE_MAX);                   
-                            HASH_ADD(hh, l_wallet_item->unspent_outputs, key, sizeof(unspent_cache_hh_key), l_item);
-                        }
+                } else 
+                    l_out = l_out_item->data;
+                /* Add unspent out to cache */ 
+                if (!a_ret_code) {
+                    dap_wallet_cache_unspent_outs_t *l_item = NULL;
+                    unspent_cache_hh_key l_key = { .tx_hash = *a_tx_hash, .out_idx = l_out_idx };
+                    HASH_FIND(hh, l_wallet_item->unspent_outputs, &l_key, sizeof(unspent_cache_hh_key), l_item);
+                    if ( !l_item ) {
+                        l_item = DAP_NEW(dap_wallet_cache_unspent_outs_t);
+                        *l_item = (dap_wallet_cache_unspent_outs_t) { .key = l_key, .output = l_out };
+                        dap_strncpy(l_item->token_ticker, *l_tx_item == TX_ITEM_TYPE_OUT_EXT ? ((dap_chain_tx_out_ext_t*)l_tx_item)->token
+                                : a_main_token_ticker ? a_main_token_ticker : "0", DAP_CHAIN_TICKER_SIZE_MAX);                   
+                        HASH_ADD(hh, l_wallet_item->unspent_outputs, key, sizeof(unspent_cache_hh_key), l_item);
                     }
                 }
             } break;
-- 
GitLab