diff --git a/modules/chain/dap_chain_ledger.c b/modules/chain/dap_chain_ledger.c index 6cf3cee7eaba257292a8b087e7f0737a7ed2f5a5..984441e3bb77402f6925be4f394fb86c0310df55 100644 --- a/modules/chain/dap_chain_ledger.c +++ b/modules/chain/dap_chain_ledger.c @@ -4428,21 +4428,25 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d // Mark 'out' items in cache if they were used & delete previous transactions from cache if it need // find all bound pairs 'in' and 'out' - dap_list_t *l_list_tmp = l_list_bound_items; size_t l_outs_used = dap_list_length(l_list_bound_items); - size_t l_cache_size = sizeof(dap_store_obj_t) * (l_outs_used + 1); - dap_store_obj_t *l_cache_used_outs = DAP_NEW_Z_SIZE(dap_store_obj_t, l_cache_size); - if ( !l_cache_used_outs ) { - if (l_item_tmp) - if (l_item_tmp->tx) - DAP_DELETE(l_item_tmp->tx); - DAP_DELETE(l_item_tmp); - log_it(L_CRITICAL, "Memory allocation error"); - return -1; + + dap_store_obj_t *l_cache_used_outs = NULL; + char *l_ledger_cache_group = NULL; + if (PVT(a_ledger)->cached) { + dap_store_obj_t *l_cache_used_outs = DAP_NEW_Z_SIZE(dap_store_obj_t, sizeof(dap_store_obj_t) * (l_outs_used + 1)); + if ( !l_cache_used_outs ) { + if (l_item_tmp) { + DAP_DEL_Z(l_item_tmp->tx); + DAP_DELETE(l_item_tmp); + } + dap_list_free(l_list_bound_items); + log_it(L_CRITICAL, "Memory allocation error"); + return -1; + } + l_ledger_cache_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_TXS_STR); } - char *l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_TXS_STR); const char *l_cur_token_ticker = NULL; - + dap_list_t *l_list_tmp = l_list_bound_items; // Update balance: deducts for (int i = 1; l_list_tmp; i++) { dap_chain_ledger_tx_bound_t *bound_item = l_list_tmp->data; @@ -4491,6 +4495,14 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d continue; } dap_chain_ledger_tx_item_t *l_prev_item_out = bound_item->item_out; + if (l_prev_item_out->cache_data.n_outs <= l_prev_item_out->cache_data.n_outs_used) { + log_it(L_ERROR, "[!] Irrelevant prev tx: out items mismatch %d <= %d", + l_prev_item_out->cache_data.n_outs, l_prev_item_out->cache_data.n_outs_used); + l_list_tmp = dap_list_next(l_list_tmp); + i--; + l_outs_used--; + continue; + } l_cur_token_ticker = l_prev_item_out->cache_data.token_ticker; int l_tx_prev_out_used_idx = 0; if (l_type == TX_ITEM_TYPE_IN) { @@ -4562,42 +4574,41 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d l_prev_item_out->cache_data.tx_hash_spent_fast[l_tx_prev_out_used_idx] = *a_tx_hash; l_prev_item_out->cache_data.n_outs_used++; // mirror it in the cache - size_t l_tx_size = dap_chain_datum_tx_get_size(l_prev_item_out->tx); - size_t l_tx_cache_sz = l_tx_size + sizeof(l_prev_item_out->cache_data); - byte_t *l_tx_cache = DAP_NEW_Z_SIZE(byte_t, l_tx_cache_sz); - memcpy(l_tx_cache, &l_prev_item_out->cache_data, sizeof(l_prev_item_out->cache_data)); - memcpy(l_tx_cache + sizeof(l_prev_item_out->cache_data), l_prev_item_out->tx, l_tx_size); - char *l_tx_i_hash = dap_chain_hash_fast_to_str_new(&l_prev_item_out->tx_hash_fast); - l_cache_used_outs[i] = (dap_store_obj_t) { - .key = l_tx_i_hash, - .value = l_tx_cache, - .value_len = l_tx_cache_sz, - .group = l_gdb_group, - .type = DAP_DB$K_OPTYPE_ADD - }; - l_cache_used_outs[i].timestamp = dap_nanotime_now(); + if (PVT(a_ledger)->cached) { + size_t l_tx_size = dap_chain_datum_tx_get_size(l_prev_item_out->tx); + size_t l_tx_cache_sz = l_tx_size + sizeof(l_prev_item_out->cache_data); + byte_t *l_tx_cache = DAP_NEW_Z_SIZE(byte_t, l_tx_cache_sz); + memcpy(l_tx_cache, &l_prev_item_out->cache_data, sizeof(l_prev_item_out->cache_data)); + memcpy(l_tx_cache + sizeof(l_prev_item_out->cache_data), l_prev_item_out->tx, l_tx_size); + char *l_tx_i_hash = dap_chain_hash_fast_to_str_new(&l_prev_item_out->tx_hash_fast); + l_cache_used_outs[i] = (dap_store_obj_t) { + .key = l_tx_i_hash, + .value = l_tx_cache, + .value_len = l_tx_cache_sz, + .group = l_ledger_cache_group, + .type = DAP_DB$K_OPTYPE_ADD + }; + l_cache_used_outs[i].timestamp = dap_nanotime_now(); + } // delete previous transactions from cache because all out is used if(l_prev_item_out->cache_data.n_outs_used == l_prev_item_out->cache_data.n_outs) { - dap_chain_hash_fast_t l_tx_prev_hash_to_del = bound_item->tx_prev_hash; + dap_chain_hash_fast_t *l_tx_prev_hash_to_del = &l_prev_item_out->tx_hash_fast; //&bound_item->tx_prev_hash; + char l_tx_prev_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; + dap_chain_hash_fast_to_str(l_tx_prev_hash_to_del, l_tx_prev_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE); // remove from memory ledger - int res = dap_chain_ledger_tx_remove(a_ledger, &l_tx_prev_hash_to_del, a_tx->header.ts_created); - if(res == -2) { - if(s_debug_more) { - char l_tx_prev_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; - dap_chain_hash_fast_to_str(&l_tx_prev_hash_to_del, l_tx_prev_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE); - log_it(L_ERROR, "Can't delete previous transactions because hash=%s not found", l_tx_prev_hash_str); - } + int res = dap_chain_ledger_tx_remove(a_ledger, l_tx_prev_hash_to_del, a_tx->header.ts_created); + switch (res) { + case 1: + debug_if(s_debug_more, L_INFO, "Deleted prev tx %s from ledger", l_tx_prev_hash_str); + break; + case -2: + debug_if(s_debug_more, L_ERROR, "Can't delete previous transactions %s: hash not found", l_tx_prev_hash_str); l_ret = -100; l_outs_used = i; goto FIN; - } - else if(res != 1) { - if(s_debug_more) { - char l_tx_prev_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; - dap_chain_hash_fast_to_str(&l_tx_prev_hash_to_del, l_tx_prev_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE); - log_it(L_ERROR, "Can't delete previous transactions with hash=%s", l_tx_prev_hash_str); - } + default: + debug_if(s_debug_more, L_ERROR, "Can't delete previous transaction %s, res code %d", l_tx_prev_hash_str, res); l_ret = -101; l_outs_used = i; goto FIN; @@ -4751,7 +4762,7 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d .key = l_tx_hash_str, .value = l_tx_cache, .value_len = l_tx_cache_sz, - .group = l_gdb_group, + .group = l_ledger_cache_group, .type = DAP_DB$K_OPTYPE_ADD }; l_cache_used_outs[0].timestamp = dap_nanotime_now(); @@ -4767,12 +4778,14 @@ FIN: if (l_list_tx_out) dap_list_free(l_list_tx_out); DAP_DEL_Z(l_main_token_ticker); - for (size_t i = 1; i <= l_outs_used; i++) { - DAP_DELETE(l_cache_used_outs[i].key); - DAP_DELETE(l_cache_used_outs[i].value); + if (PVT(a_ledger)->cached) { + for (size_t i = 1; i <= l_outs_used; i++) { + DAP_DEL_Z(l_cache_used_outs[i].key); + DAP_DEL_Z(l_cache_used_outs[i].value); + } + DAP_DELETE(l_cache_used_outs); + DAP_DELETE(l_ledger_cache_group); } - DAP_DELETE(l_gdb_group); - DAP_DELETE(l_cache_used_outs); return l_ret; } @@ -4876,7 +4889,7 @@ int dap_chain_ledger_tx_remove(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_ } } // delete tx & its item - DAP_DELETE(l_item_tmp->tx); + DAP_DEL_Z(l_item_tmp->tx); DAP_DELETE(l_item_tmp); } else