From 25cba02f0c8011115aaccbcdef15302610dbb491 Mon Sep 17 00:00:00 2001 From: "Constantin P." <papizh.konstantin@demlabs.net> Date: Wed, 26 Feb 2025 08:06:09 +0000 Subject: [PATCH] Hotfix wcache imp --- modules/wallet/dap_chain_wallet_cache.c | 158 ++++++++++++------------ 1 file changed, 81 insertions(+), 77 deletions(-) diff --git a/modules/wallet/dap_chain_wallet_cache.c b/modules/wallet/dap_chain_wallet_cache.c index 7dbc8737d1..f4a70a606b 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 { @@ -665,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) && ( \ @@ -681,12 +679,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 +691,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 +710,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 */ @@ -735,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_item_type == TX_ITEM_TYPE_OUT_ALL); + 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; @@ -751,9 +743,9 @@ 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(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, @@ -763,57 +755,22 @@ 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_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); @@ -821,8 +778,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); @@ -835,21 +792,68 @@ 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_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); + } } } } break; - default: break; + default: + break; } - } break; - default: break; + break; + 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 }; + 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); + } 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; + 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