diff --git a/dap-sdk/core/libdap.pri b/dap-sdk/core/libdap.pri index 945c55411cbcb03efe3eb294d31e2eb33872181a..257fa33003db52eea1f59558a8ea25d21c4be02c 100755 --- a/dap-sdk/core/libdap.pri +++ b/dap-sdk/core/libdap.pri @@ -76,7 +76,6 @@ HEADERS += $$PWD/include/dap_common.h \ SOURCES += $$PWD/src/dap_common.c \ $$PWD/src/dap_binary_tree.c \ $$PWD/src/dap_config.c \ - $$PWD/src/dap_math_ops.c \ $$PWD/src/dap_file_utils.c \ $$PWD/src/dap_circular_buffer.c \ $$PWD/src/dap_list.c \ diff --git a/modules/chain/dap_chain_ledger.c b/modules/chain/dap_chain_ledger.c index cebd13bf91905204568363f090ba0e9135c1365e..7213a27bc922cbc057fbd3050da3c1ea467d12b6 100644 --- a/modules/chain/dap_chain_ledger.c +++ b/modules/chain/dap_chain_ledger.c @@ -117,15 +117,21 @@ typedef struct dap_chain_ledger_tx_item { time_t ts_created; int n_outs; int n_outs_used; - char token_tiker[10]; + char token_ticker[DAP_CHAIN_TICKER_SIZE_MAX] // TODO dynamically allocates the memory in order not to limit the number of outputs in transaction dap_chain_hash_fast_t tx_hash_spent_fast[MAX_OUT_ITEMS]; // spent outs list } cache_data; UT_hash_handle hh; } dap_chain_ledger_tx_item_t; +typedef struct dap_chain_ledger_tx_spent_item { + dap_chain_hash_fast_t tx_hash_fast; + char token_ticker[DAP_CHAIN_TICKER_SIZE_MAX]; + UT_hash_handle hh; +} dap_chain_ledger_tx_spent_item_t; + typedef struct dap_chain_ledger_tokenizer { - char token_ticker[10]; + char token_ticker[DAP_CHAIN_TICKER_SIZE_MAX]; uint256_t sum; UT_hash_handle hh; } dap_chain_ledger_tokenizer_t; @@ -173,6 +179,7 @@ typedef struct dap_ledger_private { dap_chain_ledger_token_emission_item_t * treshold_emissions; dap_chain_ledger_tx_item_t *ledger_items; + dap_chain_ledger_tx_spent_item_t *spent_items; dap_chain_ledger_token_item_t *tokens; @@ -281,7 +288,7 @@ void dap_chain_ledger_handle_free(dap_ledger_t *a_ledger) void dap_chain_ledger_load_end(dap_ledger_t *a_ledger) { PVT(a_ledger)->last_tx.found = true; - PVT(a_ledger)->last_thres_tx.found = true; + PVT(a_ledger)->last_spent_tx.found = true; PVT(a_ledger)->last_emit.found = true; PVT(a_ledger)->last_ticker.found = true; } @@ -1101,23 +1108,22 @@ void dap_chain_ledger_load_cache(dap_ledger_t *a_ledger) l_ledger_pvt->last_tx.found = true; } - l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_TXS_THRES_STR); + l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_SPENT_TXS_STR); l_objs_count = 0; l_objs = dap_chain_global_db_gr_load(l_gdb_group, &l_objs_count); for (size_t i = 0; i < l_objs_count; i++) { - dap_chain_ledger_tx_item_t *l_tx_item = DAP_NEW_Z(dap_chain_ledger_tx_item_t); - dap_chain_hash_fast_from_str(l_objs[i].key, &l_tx_item->tx_hash_fast); - l_tx_item->tx = DAP_NEW_SIZE(dap_chain_datum_tx_t, l_objs[i].value_len); - memcpy(l_tx_item->tx, l_objs[i].value, l_objs[i].value_len); - HASH_ADD(hh, l_ledger_pvt->treshold_txs, tx_hash_fast, sizeof(dap_chain_hash_fast_t), l_tx_item); + dap_chain_ledger_tx_spent_item_t *l_tx_spent_item = DAP_NEW_Z(dap_chain_ledger_tx_spent_item_t); + dap_chain_hash_fast_from_str(l_objs[i].key, &l_tx_spent_item->tx_hash_fast); + strncpy(l_tx_spent_item->token_ticker, (char *)l_objs[i].value, DAP_CHAIN_TICKER_SIZE_MAX); + HASH_ADD(hh, l_ledger_pvt->spent_items, tx_hash_fast, sizeof(dap_chain_hash_fast_t), l_tx_spent_item); if (i == l_objs_count - 1) { - l_ledger_pvt->last_thres_tx.hash = &l_tx_item->tx_hash_fast; + l_ledger_pvt->last_spent_tx.hash = &l_tx_spent_item->tx_hash_fast; } } dap_chain_global_db_objs_delete(l_objs, l_objs_count); DAP_DELETE(l_gdb_group); - if (l_objs_count == 0 || l_ledger_pvt->last_thres_tx.hash == NULL) { - l_ledger_pvt->last_thres_tx.found = true; + if (l_objs_count == 0 || l_ledger_pvt->last_spent_tx.hash == NULL) { + l_ledger_pvt->last_spent_tx.found = true; } l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_BALANCES_STR); @@ -1440,11 +1446,18 @@ const char* dap_chain_ledger_tx_get_token_ticker_by_hash(dap_ledger_t *a_ledger, if ( dap_hash_fast_is_blank(a_tx_hash) ) return NULL; - dap_chain_ledger_tx_item_t *l_item= NULL; + dap_chain_ledger_tx_item_t *l_item; pthread_rwlock_rdlock(&l_ledger_priv->ledger_rwlock); - HASH_FIND(hh, l_ledger_priv->ledger_items, a_tx_hash, sizeof ( *a_tx_hash), l_item ); + HASH_FIND(hh, l_ledger_priv->ledger_items, a_tx_hash, sizeof (*a_tx_hash), l_item); + if (l_item) { + pthread_rwlock_unlock(&l_ledger_priv->ledger_rwlock); + return l_item->cache_data.token_ticker; + } + dap_chain_ledger_tx_spent_item_t *l_spent_item; + HASH_FIND(hh, l_ledger_priv->spent_items, a_tx_hash, sizeof (*a_tx_hash), l_spent_item); pthread_rwlock_unlock(&l_ledger_priv->ledger_rwlock); - return l_item ? l_item->cache_data.token_tiker : NULL; + return l_spent_item ? l_spent_item->token_ticker : NULL; + } /** @@ -1470,7 +1483,7 @@ void dap_chain_ledger_addr_get_token_ticker_all(dap_ledger_t *a_ledger, dap_chai for(size_t i = 0; i < l_tickers_size; i++) { if (l_tickers[i]==NULL) break; - if(l_tickers[i] && strcmp(l_tickers[i], l_tx_item->cache_data.token_tiker) == 0) { + if(l_tickers[i] && strcmp(l_tickers[i], l_tx_item->cache_data.token_ticker) == 0) { l_is_not_in_list = false; break; } @@ -1480,7 +1493,7 @@ void dap_chain_ledger_addr_get_token_ticker_all(dap_ledger_t *a_ledger, dap_chai l_tickers_size += (l_tickers_size / 2); l_tickers = DAP_REALLOC(l_tickers, l_tickers_size); } - l_tickers[l_tickers_pos] = dap_strdup(l_tx_item->cache_data.token_tiker); + l_tickers[l_tickers_pos] = dap_strdup(l_tx_item->cache_data.token_ticker); l_tickers_pos++; } dap_chain_hash_fast_t* l_tx_hash = dap_chain_node_datum_tx_calc_hash(l_tx_item->tx); @@ -1909,7 +1922,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t l_token = NULL; } if (!l_token || !*l_token) { - l_token = l_item_out->cache_data.token_tiker; + l_token = l_item_out->cache_data.token_ticker; } if (! l_token || !*l_token ) { log_it(L_WARNING, "No token ticker found in previous transaction"); @@ -2312,8 +2325,8 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_ledger_tx_item_t *l_prev_item_out = bound_item->item_out; dap_chain_tx_item_type_t l_out_type = *(uint8_t *)l_prev_item_out; - if ( *l_prev_item_out->cache_data.token_tiker ) - l_ticker_trl = dap_stpcpy(l_token_ticker, l_prev_item_out->cache_data.token_tiker); + if ( *l_prev_item_out->cache_data.token_ticker ) + l_ticker_trl = dap_stpcpy(l_token_ticker, l_prev_item_out->cache_data.token_ticker); else if ( l_out_type == TX_ITEM_TYPE_OUT_EXT) // 256 l_ticker_trl = dap_stpcpy(l_token_ticker, bound_item->out.tx_prev_out_ext_256->token); @@ -2557,7 +2570,7 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, : NULL; } if (l_ticker_trl && !l_multichannel) - dap_stpcpy(l_item_tmp->cache_data.token_tiker, l_token_ticker); + dap_stpcpy(l_item_tmp->cache_data.token_ticker, l_token_ticker); size_t l_tx_size = dap_chain_datum_tx_get_size(a_tx); memcpy(l_item_tmp->tx, a_tx, l_tx_size); @@ -2576,8 +2589,8 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, DAP_DELETE(l_tx_cache); } DAP_DELETE(l_gdb_group); - if (!a_from_threshold) - s_treshold_txs_proc(a_ledger); + //if (!a_from_threshold) + // s_treshold_txs_proc(a_ledger); // TODO process thresholds only for non consensus chains ret = 1; } FIN: @@ -2587,7 +2600,7 @@ FIN: int dap_chain_ledger_tx_load(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx) { - if (PVT(a_ledger)->last_tx.found && PVT(a_ledger)->last_thres_tx.found) { + if (PVT(a_ledger)->last_tx.found && PVT(a_ledger)->last_spent_tx.found) { return dap_chain_ledger_tx_add(a_ledger, a_tx, false); } else { dap_chain_hash_fast_t l_tx_hash = {}; @@ -2596,10 +2609,9 @@ int dap_chain_ledger_tx_load(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx) !memcmp(PVT(a_ledger)->last_tx.hash, &l_tx_hash, sizeof(dap_chain_hash_fast_t))) { PVT(a_ledger)->last_tx.found = true; } - if (!PVT(a_ledger)->last_thres_tx.found && - !memcmp(PVT(a_ledger)->last_thres_tx.hash, &l_tx_hash, sizeof(dap_chain_hash_fast_t))) { - PVT(a_ledger)->last_thres_tx.found = true; - } + if (!PVT(a_ledger)->last_spent_tx.found && + !memcmp(PVT(a_ledger)->last_spent_tx.hash, &l_tx_hash, sizeof(dap_chain_hash_fast_t))) { + PVT(a_ledger)->last_spent_tx.found = true; } return 1; } @@ -2618,24 +2630,37 @@ int dap_chain_ledger_tx_remove(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_ dap_chain_ledger_tx_item_t *l_item_tmp; pthread_rwlock_rdlock(&l_ledger_priv->ledger_rwlock); HASH_FIND(hh, l_ledger_priv->ledger_items, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_item_tmp); - pthread_rwlock_unlock(&l_ledger_priv->ledger_rwlock); if(l_item_tmp != NULL) { - pthread_rwlock_wrlock(&l_ledger_priv->ledger_rwlock); - HASH_DEL(l_ledger_priv->ledger_items, l_item_tmp); - pthread_rwlock_unlock(&l_ledger_priv->ledger_rwlock); - // delete transaction - DAP_DELETE(l_item_tmp->tx); - // del struct for hash - DAP_DELETE(l_item_tmp); // Remove it from cache char *l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_TXS_STR); dap_chain_global_db_gr_del(dap_chain_hash_fast_to_str_new(a_tx_hash), l_gdb_group); DAP_DELETE(l_gdb_group); l_ret = 1; + dap_chain_ledger_tx_spent_item_t *l_item_used; + HASH_FIND(hh, l_ledger_priv->spent_items, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_item_used); + if (!l_item_used) { // Add it to spent items + l_item_used = DAP_NEW_Z(dap_chain_ledger_tx_spent_item_t); + memcpy(&l_item_used->tx_hash_fast, a_tx_hash, sizeof(dap_chain_hash_fast_t)); + strncpy(l_item_used->token_ticker, l_item_tmp->cache_data.token_ticker, DAP_CHAIN_TICKER_SIZE_MAX); + HASH_ADD(hh, l_ledger_priv->spent_items, tx_hash_fast, sizeof(dap_chain_hash_fast_t), l_item_used); + // Add it to cache + char *l_cache_data = DAP_NEW_Z_SIZE(char, DAP_CHAIN_TICKER_SIZE_MAX); + strncpy(l_cache_data, l_item_used->token_ticker, DAP_CHAIN_TICKER_SIZE_MAX); + l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_SPENT_TXS_STR); + if (!dap_chain_global_db_gr_set(dap_hash_fast_to_str_new(a_tx_hash), l_cache_data, -1, l_gdb_group)) { + if(s_debug_more) + log_it(L_WARNING, "Ledger cache mismatch"); + DAP_DELETE(l_cache_data); + } + DAP_DELETE(l_gdb_group); + } + // del struct for hash + DAP_DELETE(l_item_tmp); } else // hash not found in the cache l_ret = -2; + pthread_rwlock_unlock(&l_ledger_priv->ledger_rwlock); return l_ret; } @@ -2667,15 +2692,15 @@ void dap_chain_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db) } DAP_DELETE(l_gdb_group); - // delete threshold txs - l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_TXS_THRES_STR); - HASH_ITER(hh, l_ledger_priv->treshold_txs, l_item_current, l_item_tmp) { - HASH_DEL(l_ledger_priv->treshold_txs, l_item_current); + // delete spent transactions + dap_chain_ledger_tx_spent_item_t *l_spent_item_current, *l_spent_item_tmp; + l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_SPENT_TXS_STR); + HASH_ITER(hh, l_ledger_priv->spent_items, l_spent_item_current, l_spent_item_tmp) { + HASH_DEL(l_ledger_priv->spent_items, l_spent_item_current); if (!a_preserve_db) { - dap_chain_hash_fast_to_str(&l_item_current->tx_hash_fast, l_hash_str, l_hash_str_size); + dap_chain_hash_fast_to_str(&l_spent_item_current->tx_hash_fast, l_hash_str, l_hash_str_size); 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); } DAP_DELETE(l_gdb_group); @@ -2691,22 +2716,11 @@ void dap_chain_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db) } DAP_DELETE(l_gdb_group); - // delete threshold emissions - dap_chain_ledger_token_emission_item_t *l_emission_current, *l_emission_tmp; - char *l_emissions_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_EMISSIONS_STR); - HASH_ITER(hh, l_ledger_priv->treshold_emissions, l_emission_current, l_emission_tmp) { - HASH_DEL(l_ledger_priv->treshold_emissions, l_emission_current); - if (!a_preserve_db) { - 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(dap_strdup(l_hash_str), l_emissions_gdb_group); - } - DAP_DELETE(l_emission_current->datum_token_emission); - DAP_DELETE(l_emission_current); - } - // delete tokens & its emissions dap_chain_ledger_token_item_t *l_token_current, *l_token_tmp; + dap_chain_ledger_token_emission_item_t *l_emission_current, *l_emission_tmp; l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_TOKENS_STR); + char *l_emissions_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_EMISSIONS_STR); HASH_ITER(hh, l_ledger_priv->tokens, l_token_current, l_token_tmp) { HASH_DEL(l_ledger_priv->tokens, l_token_current); pthread_rwlock_wrlock(&l_token_current->token_emissions_rwlock); @@ -2729,8 +2743,23 @@ void dap_chain_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db) DAP_DELETE(l_gdb_group); DAP_DELETE(l_emissions_gdb_group); + + // delete threshold emissions + 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_DELETE(l_emission_current->datum_token_emission); + DAP_DELETE(l_emission_current); + } + // delete threshold transactions + 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_DELETE(l_item_current->tx); + DAP_DELETE(l_item_current); + } + + l_ledger_priv->last_tx.found = true; - l_ledger_priv->last_thres_tx.found = true; + l_ledger_priv->last_spent_tx.found = true; l_ledger_priv->last_emit.found = true; l_ledger_priv->last_ticker.found = true; @@ -2872,7 +2901,7 @@ uint256_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_c if (l_type == TX_ITEM_TYPE_OUT) { const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t*) l_list_tmp->data; // Check for token name - if (!strcmp(a_token_ticker, l_iter_current->cache_data.token_tiker)) + if (!strcmp(a_token_ticker, l_iter_current->cache_data.token_ticker)) { // if transaction has the out item with requested addr if (!memcmp(a_addr, &l_tx_out->addr, sizeof(dap_chain_addr_t))) { // if 'out' item not used & transaction is valid @@ -2890,7 +2919,7 @@ uint256_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_c const dap_chain_256_tx_out_t *l_tx_out = (const dap_chain_256_tx_out_t*) l_list_tmp->data; // const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t*) l_list_tmp->data; // Check for token name - if (!strcmp(a_token_ticker, l_iter_current->cache_data.token_tiker)) + if (!strcmp(a_token_ticker, l_iter_current->cache_data.token_ticker)) { // if transaction has the out item with requested addr if (!memcmp(a_addr, &l_tx_out->addr, sizeof(dap_chain_addr_t))) { // if 'out' item not used & transaction is valid @@ -2945,8 +2974,8 @@ static dap_chain_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger, HASH_ITER(hh, l_ledger_priv->ledger_items , l_iter_current, l_item_tmp) { // If a_token is setup we check if its not our token - miss it - if (a_token && *l_iter_current->cache_data.token_tiker && - dap_strcmp(l_iter_current->cache_data.token_tiker, a_token)) + if (a_token && *l_iter_current->cache_data.token_ticker && + dap_strcmp(l_iter_current->cache_data.token_ticker, a_token)) continue; // Now work with it dap_chain_datum_tx_t *l_tx = l_iter_current->tx; @@ -3102,7 +3131,7 @@ dap_chain_datum_tx_t* dap_chain_ledger_tx_cache_find_out_cond(dap_ledger_t *a_le l_cur_tx = l_tx_tmp; memcpy(a_tx_first_hash, l_tx_hash_tmp, sizeof(dap_chain_hash_fast_t)); if (a_token_ticker) { - strcpy(a_token_ticker, l_iter_current->cache_data.token_tiker); + strcpy(a_token_ticker, l_iter_current->cache_data.token_ticker); } break; } diff --git a/modules/chain/include/dap_chain_ledger.h b/modules/chain/include/dap_chain_ledger.h index d88df0abbbc2b6498b39d7e2f80e8a40ff5f9daa..cce692b50d1f4f8679ad51373e1236c2195ea6f6 100644 --- a/modules/chain/include/dap_chain_ledger.h +++ b/modules/chain/include/dap_chain_ledger.h @@ -63,7 +63,8 @@ typedef bool (* dap_chain_ledger_verificator_callback_t)(dap_chain_tx_out_cond_t #define DAP_CHAIN_LEDGER_TOKENS_STR "tokens" #define DAP_CHAIN_LEDGER_EMISSIONS_STR "emissions" #define DAP_CHAIN_LEDGER_TXS_STR "txs" -#define DAP_CHAIN_LEDGER_TXS_THRES_STR "thres_txs" +#define DAP_CHAIN_LEDGER_TXS_THRES_STR "thres_txs" // obsolete +#define DAP_CHAIN_LEDGER_SPENT_TXS_STR "spent_txs" #define DAP_CHAIN_LEDGER_BALANCES_STR "balances" int dap_chain_ledger_init(); diff --git a/modules/global-db/dap_chain_global_db_driver_sqlite.c b/modules/global-db/dap_chain_global_db_driver_sqlite.c index a234a7061507af93dd8b075129ba094ea340db37..b9060cd5cafd12f93c5ff78426e8b66001076855 100644 --- a/modules/global-db/dap_chain_global_db_driver_sqlite.c +++ b/modules/global-db/dap_chain_global_db_driver_sqlite.c @@ -839,12 +839,13 @@ dap_store_obj_t* dap_db_driver_sqlite_read_cond_store_obj(const char *a_group, u if(a_count_out) l_count_out = (int)*a_count_out; char *l_str_query = NULL; - if(l_count_out) + if (l_count_out) { l_str_query = sqlite3_mprintf("SELECT id,ts,key,value FROM '%s' WHERE id>='%lld' ORDER BY id ASC LIMIT %d", l_table_name, a_id, l_count_out); - else + } else { l_str_query = sqlite3_mprintf("SELECT id,ts,key,value FROM '%s' WHERE id>='%lld' ORDER BY id ASC", l_table_name, a_id); + } sqlite3 *s_db = s_sqlite_get_connection(); if(!s_db){ if (l_str_query) sqlite3_free(l_str_query); @@ -917,20 +918,21 @@ dap_store_obj_t* dap_db_driver_sqlite_read_store_obj(const char *a_group, const if(a_count_out) l_count_out = *a_count_out; char *l_str_query; - if(a_key) { - if(l_count_out) + if (a_key) { + if (l_count_out) { l_str_query = sqlite3_mprintf("SELECT id,ts,key,value FROM '%s' WHERE key='%s' ORDER BY id ASC LIMIT %d", l_table_name, a_key, l_count_out); - else + } else { l_str_query = sqlite3_mprintf("SELECT id,ts,key,value FROM '%s' WHERE key='%s' ORDER BY id ASC", l_table_name, a_key); - } - else { - if(l_count_out) + } + } else { + if (l_count_out) { l_str_query = sqlite3_mprintf("SELECT id,ts,key,value FROM '%s' ORDER BY id ASC LIMIT %d", l_table_name, l_count_out); - else + } else { l_str_query = sqlite3_mprintf("SELECT id,ts,key,value FROM '%s' ORDER BY id ASC", l_table_name); + } } int l_ret = dap_db_driver_sqlite_query(s_db, l_str_query, &l_res, NULL); diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c index c9c0c18513d591ec3d67ec46039f375511b57b49..240c103e35314dd5c0609acab83c8c1190bf36f0 100644 --- a/modules/net/dap_chain_net.c +++ b/modules/net/dap_chain_net.c @@ -123,6 +123,11 @@ struct link_dns_request { uint_fast16_t tries; }; +struct net_link { + dap_chain_node_info_t *link_info; + dap_chain_node_client_t *link; +}; + /** * @struct dap_chain_net_pvt * @details Private part of chain_net dap object @@ -146,12 +151,9 @@ typedef struct dap_chain_net_pvt{ //Active synchronizing link dap_chain_node_client_t *active_link; - // Established links - dap_list_t *links; // Links list - size_t links_connected_count; - // Prepared links - dap_list_t *links_info; // Links info list + dap_list_t *net_links; // Links list + size_t links_connected_count; atomic_uint links_dns_requests; @@ -241,6 +243,11 @@ static void s_net_state_link_prepare_success(dap_worker_t * a_worker,dap_chain_n static void s_net_state_link_prepare_error(dap_worker_t * a_worker,dap_chain_node_info_t * a_node_info, void * a_arg, int a_errno); +// Replace link success/error callbacks +static void s_net_state_link_replace_success(dap_worker_t *a_worker,dap_chain_node_info_t *a_node_info, void *a_arg); +static void s_net_state_link_replace_error(dap_worker_t *a_worker,dap_chain_node_info_t *a_node_info, void *a_arg, int a_errno); + + //static void s_net_proc_kill( dap_chain_net_t * a_net ); int s_net_load(const char * a_net_name, uint16_t a_acl_idx); @@ -422,9 +429,11 @@ void dap_chain_net_sync_gdb_broadcast(void *a_arg, const char a_op_code, const c dap_chain_t *l_chain = dap_chain_net_get_chain_by_name(l_net, "gdb"); dap_chain_id_t l_chain_id = l_chain ? l_chain->id : (dap_chain_id_t) {}; dap_chain_cell_id_t l_cell_id = l_chain ? l_chain->cells->id : (dap_chain_cell_id_t){}; - pthread_rwlock_rdlock(&PVT(l_net)->rwlock); - for (dap_list_t *l_tmp = PVT(l_net)->links; l_tmp; l_tmp = dap_list_next(l_tmp)) { - dap_chain_node_client_t *l_node_client = (dap_chain_node_client_t *)l_tmp->data; + pthread_rwlock_rdlock(&PVT(l_net)->rwlock); + for (dap_list_t *l_tmp = PVT(l_net)->net_links; l_tmp; l_tmp = dap_list_next(l_tmp)) { + dap_chain_node_client_t *l_node_client = ((struct net_link *)l_tmp->data)->link; + if (!l_node_client) + continue; dap_stream_worker_t *l_stream_worker = dap_client_get_stream_worker(l_node_client->client); if (!l_stream_worker) continue; @@ -473,17 +482,57 @@ static void s_chain_callback_notify(void * a_arg, dap_chain_t *a_chain, dap_chai dap_chain_net_t *l_net = (dap_chain_net_t *)a_arg; if (PVT(l_net)->state == NET_STATE_ONLINE) { pthread_rwlock_rdlock(&PVT(l_net)->rwlock); - for (dap_list_t *l_tmp = PVT(l_net)->links; l_tmp; l_tmp = dap_list_next(l_tmp)) { - dap_chain_node_client_t *l_node_client = (dap_chain_node_client_t *)l_tmp->data; - dap_stream_worker_t * l_worker = dap_client_get_stream_worker( l_node_client->client); - if(l_worker) - dap_stream_ch_chain_pkt_write_mt(l_worker, l_node_client->ch_chain_uuid, DAP_STREAM_CH_CHAIN_PKT_TYPE_CHAIN, - l_net->pub.id.uint64, a_chain->id.uint64, a_id.uint64, a_atom, a_atom_size); + for (dap_list_t *l_tmp = PVT(l_net)->net_links; l_tmp; l_tmp = dap_list_next(l_tmp)) { + dap_chain_node_client_t *l_node_client = ((struct net_link *)l_tmp->data)->link; + if (l_node_client) { + dap_stream_worker_t * l_worker = dap_client_get_stream_worker( l_node_client->client); + if(l_worker) + dap_stream_ch_chain_pkt_write_mt(l_worker, l_node_client->ch_chain_uuid, DAP_STREAM_CH_CHAIN_PKT_TYPE_CHAIN, + l_net->pub.id.uint64, a_chain->id.uint64, a_id.uint64, a_atom, a_atom_size); + } } pthread_rwlock_unlock(&PVT(l_net)->rwlock); } } +static dap_chain_node_info_t *s_get_dns_link_from_cfg(dap_chain_net_t *a_net) +{ + dap_chain_net_pvt_t *l_net_pvt = PVT(a_net); + struct in_addr l_addr = {}; + uint16_t i, l_port; + if (l_net_pvt->seed_aliases_count) { + i = rand() % l_net_pvt->seed_aliases_count; + dap_chain_node_addr_t *l_remote_addr = dap_chain_node_alias_find(a_net, l_net_pvt->seed_aliases[i]); + if (l_remote_addr){ + dap_chain_node_info_t *l_remote_node_info = dap_chain_node_info_read(a_net, l_remote_addr); + if(l_remote_node_info){ + l_addr.s_addr = l_remote_node_info ? l_remote_node_info->hdr.ext_addr_v4.s_addr : 0; + DAP_DELETE(l_remote_node_info); + l_port = DNS_LISTEN_PORT; + }else{ + log_it(L_WARNING,"Can't find node info for node addr "NODE_ADDR_FP_STR, + NODE_ADDR_FP_ARGS(l_remote_addr)); + } + }else{ + log_it(L_WARNING,"Can't find alias info for seed alias %s",l_net_pvt->seed_aliases[i]); + } + } else if (l_net_pvt->bootstrap_nodes_count) { + i = rand() % l_net_pvt->bootstrap_nodes_count; + l_addr = l_net_pvt->bootstrap_nodes_addrs[i]; + l_port = l_net_pvt->bootstrap_nodes_ports[i]; + } + if (!l_addr.s_addr) + return NULL; + dap_chain_node_info_t *l_link_node_info = DAP_NEW_Z(dap_chain_node_info_t); + if(! l_link_node_info){ + log_it(L_CRITICAL,"Can't allocate memory for node link info"); + return NULL; + } + l_link_node_info->hdr.ext_addr_v4 = l_addr; + l_link_node_info->hdr.ext_port = l_port; + return l_link_node_info; +} + /** * @brief s_fill_links_from_root_aliases * @param a_net @@ -494,10 +543,10 @@ static void s_fill_links_from_root_aliases(dap_chain_net_t * a_net) uint64_t l_own_addr = dap_chain_net_get_cur_addr_int(a_net); for (size_t i = 0; i < MIN(s_max_links_count, l_pvt_net->seed_aliases_count); i++) { pthread_rwlock_rdlock(&l_pvt_net->rwlock); - if (dap_list_length(l_pvt_net->links_info) >= s_max_links_count) { + if (dap_list_length(l_pvt_net->net_links) >= s_max_links_count) { pthread_rwlock_unlock(&l_pvt_net->rwlock); break; - }else + } else pthread_rwlock_unlock(&l_pvt_net->rwlock); dap_chain_node_addr_t *l_link_addr = dap_chain_node_alias_find(a_net, l_pvt_net->seed_aliases[i]); @@ -509,8 +558,10 @@ static void s_fill_links_from_root_aliases(dap_chain_net_t * a_net) } dap_chain_node_info_t *l_link_node_info = dap_chain_node_info_read(a_net, l_link_addr); if(l_link_node_info) { + struct net_link *l_new_link = DAP_NEW_Z(struct net_link); + l_new_link->link_info = l_link_node_info; pthread_rwlock_wrlock(&l_pvt_net->rwlock); - l_pvt_net->links_info = dap_list_append(l_pvt_net->links_info, l_link_node_info); + l_pvt_net->net_links = dap_list_append(l_pvt_net->net_links, l_new_link); pthread_rwlock_unlock(&l_pvt_net->rwlock); } else { log_it(L_WARNING, "Not found link %s."NODE_ADDR_FP_STR" in the node list", a_net->pub.name, @@ -519,6 +570,95 @@ static void s_fill_links_from_root_aliases(dap_chain_net_t * a_net) } } +/** + * @brief s_net_state_link_replace_error + * @param a_worker + * @param a_node_info + * @param a_arg + * @param a_errno + */ +static void s_net_state_link_replace_error(dap_worker_t *a_worker, dap_chain_node_info_t *a_node_info, void *a_arg, int a_errno) +{ + UNUSED(a_worker); + struct link_dns_request *l_dns_request = (struct link_dns_request *)a_arg; + dap_chain_net_t *l_net = l_dns_request->net; + char l_node_addr_str[INET_ADDRSTRLEN] = {}; + inet_ntop(AF_INET, &a_node_info->hdr.ext_addr_v4, l_node_addr_str, sizeof (a_node_info->hdr.ext_addr_v4)); + log_it(L_WARNING,"Link " NODE_ADDR_FP_STR " (%s) replace error with code %d", NODE_ADDR_FP_ARGS_S(a_node_info->hdr.address), + l_node_addr_str,a_errno ); + dap_notify_server_send_f_mt("{" + "class:\"NetLinkReplaceError\"," + "net_id:0x%016" DAP_UINT64_FORMAT_X "," + "cell_id:0x%016"DAP_UINT64_FORMAT_X"," + "address:\""NODE_ADDR_FP_STR"\"," + "error: %d" + "}\n", l_net->pub.id.uint64, a_node_info->hdr.cell_id.uint64, + NODE_ADDR_FP_ARGS_S(a_node_info->hdr.address), a_errno); + DAP_DELETE(a_node_info); + dap_chain_node_info_t *l_link_node_info = NULL; + for (int i = 0; i < 1000; i++) { + l_link_node_info = s_get_dns_link_from_cfg(l_net); + if (l_link_node_info) + break; + } + if (!l_link_node_info) { // We have lost this link forever + DAP_DELETE(l_dns_request); + return; + } + if (dap_chain_node_info_dns_request(l_link_node_info->hdr.ext_addr_v4, + l_link_node_info->hdr.ext_port, + l_net->pub.name, + l_link_node_info, // use it twice + s_net_state_link_replace_success, + s_net_state_link_replace_error, + l_dns_request)) { + log_it(L_ERROR, "Can't process node info dns request"); + DAP_DELETE(l_link_node_info); + DAP_DELETE(l_dns_request); + } +} + +/** + * @brief s_net_state_link_repace_success + * @param a_worker + * @param a_node_info + * @param a_arg + */ + +static void s_net_state_link_replace_success(dap_worker_t *a_worker, dap_chain_node_info_t *a_node_info, void *a_arg) +{ + if (s_debug_more) { + char l_node_addr_str[INET_ADDRSTRLEN] = {}; + inet_ntop(AF_INET, &a_node_info->hdr.ext_addr_v4, l_node_addr_str, INET_ADDRSTRLEN); + log_it(L_DEBUG,"Link " NODE_ADDR_FP_STR " (%s) replace success", NODE_ADDR_FP_ARGS_S(a_node_info->hdr.address), + l_node_addr_str); + } + + struct link_dns_request *l_dns_request = (struct link_dns_request *)a_arg; + dap_chain_net_t *l_net = l_dns_request->net; + dap_chain_net_pvt_t *l_net_pvt = PVT(l_net); + uint64_t l_own_addr = dap_chain_net_get_cur_addr_int(l_net); + if (a_node_info->hdr.address.uint64 == l_own_addr) { + s_net_state_link_replace_error(a_worker, a_node_info, a_arg, EWOULDBLOCK); + return; + } + struct net_link *l_new_link = DAP_NEW_Z(struct net_link); + l_new_link->link_info = a_node_info; + l_new_link->link = dap_chain_net_client_create_n_connect(l_net, a_node_info); + pthread_rwlock_wrlock(&l_net_pvt->rwlock); + l_net_pvt->net_links = dap_list_append(l_net_pvt->net_links, l_new_link); + pthread_rwlock_unlock(&l_net_pvt->rwlock); + + dap_notify_server_send_f_mt("{" + "class:\"NetLinkReplaceSuccess\"," + "net_id:0x%016" DAP_UINT64_FORMAT_X "," + "cell_id:0x%016"DAP_UINT64_FORMAT_X"," + "address:\""NODE_ADDR_FP_STR"\"" + "}\n", l_net->pub.id.uint64, a_node_info->hdr.cell_id.uint64, + NODE_ADDR_FP_ARGS_S(a_node_info->hdr.address)); + DAP_DELETE(l_dns_request); +} + /** * @brief s_node_link_callback_connected * @param a_node_client @@ -552,28 +692,70 @@ static void s_node_link_callback_connected(dap_chain_node_client_t * a_node_clie } +static void s_node_link_remove(dap_chain_net_pvt_t *a_net_pvt, dap_chain_node_client_t *a_node_client) +{ + for (dap_list_t *it = a_net_pvt->net_links; it; it = it->next) { + if (((struct net_link *)it->data)->link == a_node_client) { + DAP_DELETE(((struct net_link *)it->data)->link_info); + a_net_pvt->net_links = dap_list_delete_link(a_net_pvt->net_links, it); + break; + } + } +} + /** * @brief s_node_link_callback_disconnected * @param a_node_client * @param a_arg */ -static void s_node_link_callback_disconnected(dap_chain_node_client_t * a_node_client, void * a_arg) -{ - dap_chain_net_t * l_net = (dap_chain_net_t *) a_arg; - dap_chain_net_pvt_t * l_net_pvt = PVT(l_net); + +static void s_node_link_callback_disconnected(dap_chain_node_client_t *a_node_client, void *a_arg) +{ + dap_chain_net_t *l_net = (dap_chain_net_t *)a_arg; + dap_chain_net_pvt_t *l_net_pvt = PVT(l_net); pthread_rwlock_wrlock(&l_net_pvt->rwlock); if (a_node_client->is_connected) { a_node_client->is_connected = false; log_it(L_INFO, "%s."NODE_ADDR_FP_STR" disconnected.%s",l_net->pub.name, NODE_ADDR_FP_ARGS_S(a_node_client->info->hdr.address), - l_net_pvt->state_target == NET_STATE_OFFLINE ? "" : " Reconnecting back..."); + l_net_pvt->state_target == NET_STATE_OFFLINE ? "" : " Replace it..."); if (l_net_pvt->links_connected_count) l_net_pvt->links_connected_count--; else log_it(L_ERROR, "Links count is zero in disconnected callback, looks smbd decreased it twice or forget to increase on connect/reconnect"); } if (l_net_pvt->state_target != NET_STATE_OFFLINE) { - a_node_client->keep_connection = true; + for (dap_list_t *it = l_net_pvt->net_links; it; it = it->next) { + if (((struct net_link *)it->data)->link == NULL) { // We have a free prepared link + s_node_link_remove(l_net_pvt, a_node_client); + ((struct net_link *)it->data)->link = dap_chain_net_client_create_n_connect(l_net, + ((struct net_link *)it->data)->link_info); + pthread_rwlock_unlock(&l_net_pvt->rwlock); + return; + } + } + dap_chain_node_info_t *l_link_node_info = s_get_dns_link_from_cfg(l_net); + if (!l_link_node_info) { // Try to keep this connection + a_node_client->keep_connection = true; + } else { + struct link_dns_request *l_dns_request = DAP_NEW_Z(struct link_dns_request); + l_dns_request->net = l_net; + if (dap_chain_node_info_dns_request(l_link_node_info->hdr.ext_addr_v4, + l_link_node_info->hdr.ext_port, + l_net->pub.name, + l_link_node_info, // use it twice + s_net_state_link_replace_success, + s_net_state_link_replace_error, + l_dns_request)) { + log_it(L_ERROR, "Can't process node info dns request"); + DAP_DELETE(l_link_node_info); + DAP_DELETE(l_dns_request); + a_node_client->keep_connection = true; + } else { + s_node_link_remove(l_net_pvt, a_node_client); + a_node_client->keep_connection = false; + } + } } pthread_rwlock_unlock(&l_net_pvt->rwlock); } @@ -643,10 +825,10 @@ static void s_node_link_callback_delete(dap_chain_node_client_t * a_node_client, return; } pthread_rwlock_wrlock(&l_net_pvt->rwlock); - for ( dap_list_t * it = l_net_pvt->links; it; it=it->next ){ - if (it->data == a_node_client) { + for ( dap_list_t * it = l_net_pvt->net_links; it; it=it->next ){ + if (((struct net_link *)it->data)->link == a_node_client) { log_it(L_DEBUG,"Replace node client with new one"); - it->data = dap_chain_net_client_create_n_connect(l_net, a_node_client->info); + ((struct net_link *)it->data)->link = dap_chain_net_client_create_n_connect(l_net, a_node_client->info); } } pthread_rwlock_unlock(&l_net_pvt->rwlock); @@ -678,10 +860,12 @@ static void s_net_state_link_prepare_success(dap_worker_t * a_worker,dap_chain_n struct link_dns_request * l_dns_request = (struct link_dns_request *) a_arg; dap_chain_net_t * l_net = l_dns_request->net; dap_chain_net_pvt_t * l_net_pvt = PVT(l_net); - uint64_t l_own_addr =0; + uint64_t l_own_addr = dap_chain_net_get_cur_addr_int(l_net); if (a_node_info->hdr.address.uint64 != l_own_addr) { + struct net_link *l_new_link = DAP_NEW_Z(struct net_link); + l_new_link->link_info = a_node_info; pthread_rwlock_wrlock(&l_net_pvt->rwlock); - l_net_pvt->links_info = dap_list_append(l_net_pvt->links_info, a_node_info); + l_net_pvt->net_links = dap_list_append(l_net_pvt->net_links, l_new_link); pthread_rwlock_unlock(&l_net_pvt->rwlock); l_dns_request->tries = 0; } @@ -778,9 +962,8 @@ static void s_net_links_notify(dap_chain_net_t * a_net ) dap_string_t * l_str_reply = dap_string_new("["); size_t i =0; - for (dap_list_t * l_item = l_net_pvt->links; l_item; l_item = l_item->next ) { - dap_chain_node_client_t * l_node_client = l_item->data; - + for (dap_list_t * l_item = l_net_pvt->net_links; l_item; l_item = l_item->next ) { + dap_chain_node_client_t * l_node_client = ((struct net_link *)l_item->data)->link; if(l_node_client){ dap_chain_node_info_t * l_info = l_node_client->info; char l_ext_addr_v4[INET_ADDRSTRLEN]={}; @@ -837,19 +1020,19 @@ static bool s_net_states_proc(dap_proc_thread_t *a_thread, void *a_arg) // State OFFLINE where we don't do anything case NET_STATE_OFFLINE: { // delete all links - dap_list_t *l_tmp = l_net_pvt->links; + dap_list_t *l_tmp = l_net_pvt->net_links; while (l_tmp) { dap_list_t *l_next =l_tmp->next; - ((dap_chain_node_client_t *)l_tmp->data)->keep_connection = false; - dap_chain_node_client_close(l_tmp->data); + dap_chain_node_client_t *l_link = ((struct net_link *)l_tmp->data)->link; + if (l_link) { + l_link->keep_connection = false; + dap_chain_node_client_close(l_link); + } + DAP_DELETE(((struct net_link *)l_tmp->data)->link_info); DAP_DELETE(l_tmp); l_tmp = l_next; } - l_net_pvt->links = NULL; - if(l_net_pvt->links_info){ - dap_list_free_full(l_net_pvt->links_info, free); - l_net_pvt->links_info = NULL; - } + l_net_pvt->net_links = NULL; if ( l_net_pvt->state_target != NET_STATE_OFFLINE ){ l_net_pvt->state = NET_STATE_LINKS_PREPARE; l_repeat_after_exit = true; @@ -871,8 +1054,11 @@ static bool s_net_states_proc(dap_proc_thread_t *a_thread, void *a_arg) dap_chain_node_info_t *l_link_node_info = DAP_NEW_Z(dap_chain_node_info_t); l_link_node_info->hdr.address.uint64 = l_net_pvt->gdb_sync_nodes_addrs[i].uint64; l_link_node_info->hdr.ext_addr_v4.s_addr = l_net_pvt->gdb_sync_nodes_links_ips[i]; - l_link_node_info->hdr.ext_port = l_net_pvt->gdb_sync_nodes_links_ports[i]; - l_net_pvt->links_info = dap_list_append(l_net_pvt->links_info, l_link_node_info); + l_link_node_info->hdr.ext_port = l_net_pvt->gdb_sync_nodes_links_ports[i]; + struct net_link *l_new_link = DAP_NEW_Z(struct net_link); + l_new_link->link_info = l_link_node_info; + l_net_pvt->net_links = dap_list_append(l_net_pvt->net_links, l_new_link); + } uint64_t l_own_addr = dap_chain_net_get_cur_addr_int(l_net); if (l_net_pvt->node_info) { @@ -880,9 +1066,12 @@ static bool s_net_states_proc(dap_proc_thread_t *a_thread, void *a_arg) dap_chain_node_info_t *l_link_node_info = dap_chain_node_info_read(l_net, &l_net_pvt->node_info->links[i]); if (!l_link_node_info || l_link_node_info->hdr.address.uint64 == l_own_addr) { continue; // Do not link with self - } - l_net_pvt->links_info = dap_list_append(l_net_pvt->links_info, l_link_node_info); - if (dap_list_length(l_net_pvt->links_info) >= s_max_links_count) { + } + struct net_link *l_new_link = DAP_NEW_Z(struct net_link); + l_new_link->link_info = l_link_node_info; + l_net_pvt->net_links = dap_list_append(l_net_pvt->net_links, l_new_link); + if (dap_list_length(l_net_pvt->net_links) >= s_max_links_count) { + break; } } @@ -907,74 +1096,44 @@ static bool s_net_states_proc(dap_proc_thread_t *a_thread, void *a_arg) case NODE_ROLE_FULL: case NODE_ROLE_MASTER: case NODE_ROLE_LIGHT: - default: { + default: { + if (!l_net_pvt->seed_aliases_count && ! l_net_pvt->bootstrap_nodes_count) { + log_it(L_ERROR, "No root servers present in configuration file. Can't establish DNS requests"); + if (l_net_pvt->net_links) { // We have other links + l_net_pvt->state = NET_STATE_LINKS_CONNECTING; + l_repeat_after_exit = true; + } + break; + } // Get DNS request result from root nodes as synchronization links bool l_sync_fill_root_nodes = false; - uint32_t l_link_id=0; - if (!l_sync_fill_root_nodes){ - for (size_t n=0; n< s_required_links_count;n++ ) { - struct in_addr l_addr = {}; - uint16_t i, l_port; - if (l_net_pvt->seed_aliases_count) { - i = rand() % l_net_pvt->seed_aliases_count; - dap_chain_node_addr_t *l_remote_addr = dap_chain_node_alias_find(l_net, l_net_pvt->seed_aliases[i]); - if (l_remote_addr){ - dap_chain_node_info_t *l_remote_node_info = dap_chain_node_info_read(l_net, l_remote_addr); - if(l_remote_node_info){ - l_addr.s_addr = l_remote_node_info ? l_remote_node_info->hdr.ext_addr_v4.s_addr : 0; - DAP_DELETE(l_remote_node_info); - l_port = DNS_LISTEN_PORT; - }else{ - log_it(L_WARNING,"Can't find node info for node addr "NODE_ADDR_FP_STR, - NODE_ADDR_FP_ARGS(l_remote_addr)); - } - }else{ - log_it(L_WARNING,"Can't find alias info for seed alias %s",l_net_pvt->seed_aliases[i]); - } - } else if (l_net_pvt->bootstrap_nodes_count) { - i = rand() % l_net_pvt->bootstrap_nodes_count; - l_addr = l_net_pvt->bootstrap_nodes_addrs[i]; - l_port = l_net_pvt->bootstrap_nodes_ports[i]; - } else { - log_it(L_ERROR, "No root servers present in configuration file. Can't establish DNS requests"); - if (!dap_list_length(l_net_pvt->links_info)) { // No links can be prepared, go offline - l_net_pvt->state_target = NET_STATE_OFFLINE; - } - } - if (l_addr.s_addr) { - dap_chain_node_info_t *l_link_node_info = DAP_NEW_Z(dap_chain_node_info_t); - if(! l_link_node_info){ - log_it(L_CRITICAL,"Can't allocate memory for node link info"); - break; - } -/* #ifdef DAP_OS_UNIX - struct in_addr _in_addr = { .s_addr = l_addr.s_addr }; - #else - struct in_addr _in_addr = { { .S_addr = l_addr.S_un.S_addr } }; - #endif -*/ - l_sync_fill_root_nodes = false; - if (l_net_pvt->state_target != NET_STATE_OFFLINE) { - l_net_pvt->links_dns_requests++; - struct link_dns_request * l_dns_request = DAP_NEW_Z(struct link_dns_request); - l_dns_request->net = l_net; - l_dns_request->link_id = l_link_id; - if(dap_chain_node_info_dns_request(l_addr, l_port, l_net->pub.name, l_link_node_info, - s_net_state_link_prepare_success, - s_net_state_link_prepare_error,l_dns_request) != 0 ){ - log_it(L_ERROR, "Can't process node info dns request"); - DAP_DEL_Z(l_link_node_info); - - } - }else{ - DAP_DEL_Z(l_link_node_info); - } + uint32_t l_link_id = 0; + if (!l_sync_fill_root_nodes) { + for (size_t n = 0; l_net_pvt->links_dns_requests < s_max_links_count; n++) { + dap_chain_node_info_t *l_link_node_info = s_get_dns_link_from_cfg(l_net); + if (!l_link_node_info) + continue; + l_net_pvt->links_dns_requests++; + struct link_dns_request *l_dns_request = DAP_NEW_Z(struct link_dns_request); + l_dns_request->net = l_net; + l_dns_request->link_id = l_link_id++; + if (dap_chain_node_info_dns_request(l_link_node_info->hdr.ext_addr_v4, + l_link_node_info->hdr.ext_port, + l_net->pub.name, + l_link_node_info, // use it twice + s_net_state_link_prepare_success, + s_net_state_link_prepare_error, + l_dns_request)) { + log_it(L_ERROR, "Can't process node info dns request"); + DAP_DEL_Z(l_dns_request); + DAP_DEL_Z(l_link_node_info); } - l_link_id++; + if (n > 1000) // It's a problem with link prepare + break; } } - if (l_sync_fill_root_nodes){ - log_it(L_ATT,"Not found bootstrap addresses, fill seed nodelist from root aliases"); + if (l_sync_fill_root_nodes) { + log_it(L_ATT, "Not use bootstrap addresses, fill seed nodelist from root aliases"); pthread_rwlock_unlock(&l_net_pvt->rwlock); s_fill_links_from_root_aliases(l_net); pthread_rwlock_wrlock(&l_net_pvt->rwlock); @@ -985,12 +1144,13 @@ static bool s_net_states_proc(dap_proc_thread_t *a_thread, void *a_arg) case NET_STATE_LINKS_CONNECTING: { log_it(L_INFO, "%s.state: NET_STATE_LINKS_CONNECTING",l_net->pub.name); - for (dap_list_t *l_tmp = l_net_pvt->links_info; l_tmp; l_tmp = dap_list_next(l_tmp)) { - dap_chain_node_info_t *l_link_info = (dap_chain_node_info_t *)l_tmp->data; + int l_used_links = 0; + for (dap_list_t *l_tmp = l_net_pvt->net_links; l_tmp; l_tmp = dap_list_next(l_tmp)) { + dap_chain_node_info_t *l_link_info = ((struct net_link *)l_tmp->data)->link_info; dap_chain_node_client_t *l_client = dap_chain_net_client_create_n_connect(l_net, l_link_info); l_client->keep_connection = true; - l_net_pvt->links = dap_list_append(l_net_pvt->links, l_client); - if (dap_list_length(l_net_pvt->links) == s_required_links_count) + ((struct net_link *)l_tmp->data)->link = l_client; + if (++l_used_links == s_required_links_count) break; } } break; @@ -1026,15 +1186,14 @@ bool dap_chain_net_sync_trylock(dap_chain_net_t *a_net, dap_chain_node_client_t pthread_rwlock_rdlock(&l_net_pvt->rwlock); bool l_found = false; if (l_net_pvt->active_link) { - for (dap_list_t *l_links = l_net_pvt->links; l_links; l_links = dap_list_next(l_links)) { - if (l_links->data == l_net_pvt->active_link) { - dap_chain_node_client_t *l_client = (dap_chain_node_client_t *)l_links->data; - if (l_client->state >= NODE_CLIENT_STATE_ESTABLISHED && + for (dap_list_t *l_links = l_net_pvt->net_links; l_links; l_links = dap_list_next(l_links)) { + dap_chain_node_client_t *l_client = ((struct net_link *)l_links->data)->link; + if (l_client == l_net_pvt->active_link && + l_client->state >= NODE_CLIENT_STATE_ESTABLISHED && l_client->state < NODE_CLIENT_STATE_SYNCED && a_client != l_client) { - l_found = true; - break; - } + l_found = true; + break; } } } @@ -1232,7 +1391,7 @@ void s_set_reply_text_node_status(char **a_str_reply, dap_chain_net_t * a_net){ if (PVT(a_net)->state != NET_STATE_OFFLINE) l_sync_current_link_text_block = dap_strdup_printf(", active links %u from %u", PVT(a_net)->links_connected_count, - dap_list_length(PVT(a_net)->links)); + dap_list_length(PVT(a_net)->net_links)); dap_chain_node_cli_set_reply_text(a_str_reply, "Network \"%s\" has state %s (target state %s)%s%s", a_net->pub.name, c_net_states[PVT(a_net)->state], @@ -1436,12 +1595,11 @@ static int s_cli_net(int argc, char **argv, char **a_str_reply) size_t i =0; dap_chain_net_pvt_t * l_net_pvt = PVT(l_net); pthread_rwlock_rdlock(&l_net_pvt->rwlock ); - size_t l_links_count = dap_list_length(l_net_pvt->links); + size_t l_links_count = dap_list_length(l_net_pvt->net_links); dap_string_t *l_reply = dap_string_new(""); dap_string_append_printf(l_reply,"Links %zu:\n", l_links_count); - for (dap_list_t * l_item = l_net_pvt->links; l_item; l_item = l_item->next ) { - dap_chain_node_client_t * l_node_client = l_item->data; - + for (dap_list_t * l_item = l_net_pvt->net_links; l_item; l_item = l_item->next ) { + dap_chain_node_client_t *l_node_client = ((struct net_link *)l_item->data)->link; if(l_node_client){ dap_chain_node_info_t * l_info = l_node_client->info; char l_ext_addr_v4[INET_ADDRSTRLEN]={}; @@ -2544,7 +2702,7 @@ void dap_chain_net_proc_mempool (dap_chain_net_t * a_net) dap_chain_datum_tx_t * dap_chain_net_get_tx_by_hash(dap_chain_net_t * a_net, dap_chain_hash_fast_t * a_tx_hash, dap_chain_net_tx_search_type_t a_search_type) { - dap_ledger_t * l_ledger = dap_chain_ledger_by_net_name( a_net->pub.name ); + dap_ledger_t * l_ledger = a_net->pub.ledger; dap_chain_datum_tx_t * l_tx = NULL; switch (a_search_type) { @@ -2556,7 +2714,7 @@ dap_chain_datum_tx_t * dap_chain_net_get_tx_by_hash(dap_chain_net_t * a_net, dap for ( dap_chain_t * l_chain = a_net->pub.chains; l_chain; l_chain = l_chain->next){ if ( l_chain->callback_tx_find_by_hash ){ // try to find transaction in chain ( inside shard ) - l_tx = l_chain->callback_tx_find_by_hash( l_chain, a_tx_hash ); + l_tx = l_chain->callback_tx_find_by_hash(l_chain, a_tx_hash); if (l_tx) break; } @@ -2566,7 +2724,7 @@ dap_chain_datum_tx_t * dap_chain_net_get_tx_by_hash(dap_chain_net_t * a_net, dap case TX_SEARCH_TYPE_NET_UNSPENT: case TX_SEARCH_TYPE_CELL_UNSPENT:{ - l_tx = dap_chain_ledger_tx_find_by_hash( l_ledger, a_tx_hash ); + l_tx = dap_chain_ledger_tx_find_by_hash(l_ledger, a_tx_hash); }break; } return l_tx; diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c index 44fdd7abaff7475bb748358fc11b3d81bee9c76e..f462cdbec41de51aaf5679d7618e831a6c6a80dc 100644 --- a/modules/net/dap_chain_node_cli_cmd_tx.c +++ b/modules/net/dap_chain_node_cli_cmd_tx.c @@ -91,38 +91,21 @@ static void s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, dap_ledger_t *a_ledger, dap_string_t *a_str_out, const char *a_hash_out_type, - bool save_processed_tx, - dap_chain_tx_hash_processed_ht_t **a_tx_hash_processed, - size_t *l_tx_num) + dap_chain_hash_fast_t *a_tx_hash) { - dap_chain_hash_fast_t l_tx_hash; - dap_hash_fast(a_datum, dap_chain_datum_tx_get_size(a_datum), &l_tx_hash); - if (save_processed_tx){ - dap_chain_tx_hash_processed_ht_t *l_sht = NULL; - HASH_FIND(hh, *a_tx_hash_processed, &l_tx_hash, sizeof(dap_chain_hash_fast_t), l_sht); - if (l_sht != NULL) - return; - l_sht = DAP_NEW_Z(dap_chain_tx_hash_processed_ht_t); - memcpy(&l_sht->hash, &l_tx_hash, sizeof(dap_chain_hash_fast_t)); - HASH_ADD(hh, *a_tx_hash_processed, hash, sizeof(dap_chain_hash_fast_t), l_sht); - (*l_tx_num)++; - } - char *l_tx_hash_user_str; - char l_tx_hash_str[70]; - dap_chain_hash_fast_to_str(&l_tx_hash, l_tx_hash_str, 70); time_t l_ts_create = (time_t)a_datum->header.ts_created; if(!dap_strcmp(a_hash_out_type, "hex")) - l_tx_hash_user_str = dap_strdup(l_tx_hash_str); + l_hash_str = dap_chain_hash_fast_to_str_new(a_tx_hash); else - l_tx_hash_user_str = dap_enc_base58_from_hex_str_to_str(l_tx_hash_str); + l_hash_str = dap_enc_base58_encode_hash_to_str(a_tx_hash); dap_list_t *l_list_tx_any = dap_chain_datum_tx_items_get(a_datum, TX_ITEM_TYPE_TOKEN, NULL); if(a_ledger == NULL){ - dap_string_append_printf(a_str_out, "transaction: %s hash: %s\n Items:\n", l_list_tx_any ? "(emit)" : "", l_tx_hash_user_str); + dap_string_append_printf(a_str_out, "transaction:%s hash: %s\n Items:\n", l_list_tx_any ? "(emit)" : "", l_tx_hash_user_str); } else { char buf[50]; dap_string_append_printf(a_str_out, "transaction:%s hash: %s\n TS Created: %s Token ticker: %s\n Items:\n", l_list_tx_any ? " (emit)" : "", l_tx_hash_user_str, dap_ctime_r(&l_ts_create, buf), - dap_chain_ledger_tx_get_token_ticker_by_hash(a_ledger, &l_tx_hash)); + dap_chain_ledger_tx_get_token_ticker_by_hash(a_ledger, a_tx_hash)); } DAP_DELETE(l_tx_hash_user_str); dap_list_free(l_list_tx_any); @@ -973,36 +956,19 @@ static char* dap_db_history_filter(dap_chain_t * a_chain, dap_ledger_t *a_ledger size_t l_datum_num = 0, l_token_num = 0, l_emission_num = 0, l_tx_num = 0; size_t l_datum_num_global = a_total_datums ? *a_total_datums : 0; while(l_atom && l_atom_size) { - size_t l_datums_count = 0; - dap_chain_datum_t **l_datums = - (a_chain->callback_atom_get_datums && l_atom && l_atom_size) ? - a_chain->callback_atom_get_datums(l_atom, l_atom_size, &l_datums_count) : NULL; - if(!l_datums) { - log_it(L_WARNING, "Not defined callback_atom_get_datums for chain \"%s\"", a_chain->name); - return NULL ; - } - for(size_t l_datum_n = 0; l_datum_n < l_datums_count; l_datum_n++) { - dap_chain_datum_t *l_datum = l_datums[l_datum_n]; - if(!l_datum) { // || l_datum->header.type_id != DAP_CHAIN_DATUM_TX) { - // go to next atom - //l_atom = a_chain->callback_atom_iter_get_next(l_atom_iter, &l_atom_size); - continue; + size_t l_datums_count = 0; + dap_chain_datum_t **l_datums = + (a_chain->callback_atom_get_datums && l_atom && l_atom_size) ? + a_chain->callback_atom_get_datums(l_atom, l_atom_size, &l_datums_count) : NULL; + if(!l_datums) { + log_it(L_WARNING, "Not defined callback_atom_get_datums for chain \"%s\"", a_chain->name); + return NULL ; + } + for(size_t l_datum_n = 0; l_datum_n < l_datums_count; l_datum_n++) { + dap_chain_datum_t *l_datum = l_datums[l_datum_n]; + if(!l_datum) { // || l_datum->header.type_id != DAP_CHAIN_DATUM_TX) { + continue; } - /*dap_chain_atom_iter_t *l_atom_iter = a_chain->callback_atom_iter_create(a_chain); - dap_chain_atom_ptr_t l_atom = a_chain->callback_atom_iter_get_first(l_atom_iter); - size_t l_atom_size = a_chain->callback_atom_get_size(l_atom); - size_t l_datum_num = 0, l_token_num = 0, l_emission_num = 0, l_tx_num = 0; - while(l_atom && l_atom_size) { - dap_chain_datum_t *l_datum = - a_chain->callback_atom_get_datum ? - a_chain->callback_atom_get_datum(l_atom) : (dap_chain_datum_t*) l_atom; - if(!l_datum) { - // go to next transaction - l_atom = a_chain->callback_atom_iter_get_next(l_atom_iter); - l_atom_size = a_chain->callback_atom_get_size(l_atom); - log_it(L_ERROR, "datum=NULL for atom=0x%x", l_atom); - continue; - }*/ char l_time_str[70]; // get time of create datum if(dap_time_to_str_rfc822(l_time_str, 71, l_datum->header.ts_create) < 1) @@ -1171,10 +1137,19 @@ static char* dap_db_history_filter(dap_chain_t * a_chain, dap_ledger_t *a_ledger l_tx_num++; break; } - dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*)l_datum->data; //calc tx hash - s_dap_chain_datum_tx_out_data(l_tx, a_ledger, l_str_out, a_hash_out_type, true, &a_tx_hash_processed, &l_tx_num); + dap_chain_hash_fast_t l_tx_hash; + dap_hash_fast(l_tx, dap_chain_datum_tx_get_size(l_tx), &l_tx_hash); + dap_chain_tx_hash_processed_ht_t *l_sht = NULL; + HASH_FIND(hh, a_tx_hash_processed, &l_tx_hash, sizeof(dap_chain_hash_fast_t), l_sht); + if (l_sht != NULL) + break; + l_sht = DAP_NEW_Z(dap_chain_tx_hash_processed_ht_t); + memcpy(&l_sht->hash, &l_tx_hash, sizeof(dap_chain_hash_fast_t)); + HASH_ADD(hh, a_tx_hash_processed, hash, sizeof(dap_chain_hash_fast_t), l_sht); + l_tx_num++; + s_dap_chain_datum_tx_out_data(l_tx, a_ledger, l_str_out, a_hash_out_type, &l_tx_hash); } break; default: @@ -1392,9 +1367,13 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) int l_sub_cmd = SUBCMD_NONE; if (dap_chain_node_cli_find_option_val(a_argv, 2, 3, "coins", NULL )) l_sub_cmd = SUBCMD_LIST_COIN; + if (l_sub_cmd == SUBCMD_NONE) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Command 'list' requires subcommand 'coins'"); + return -5; + } dap_chain_node_cli_find_option_val(a_argv, 3, a_argc, "-net", &l_net_str); if (l_net_str == NULL){ - dap_chain_node_cli_set_reply_text(a_str_reply, "Command requires key -net"); + dap_chain_node_cli_set_reply_text(a_str_reply, "Command 'list' requires key -net"); return -1; } dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(l_net_str); @@ -1417,38 +1396,42 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-hash", &l_tx_hash_str); //get net dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-net", &l_net_str); + //get search type + const char *l_unspent_str = NULL; + dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-unspent", &l_unspent_str); //check input if (l_tx_hash_str == NULL){ - dap_chain_node_cli_set_reply_text(a_str_reply, "command requires key -hash"); + dap_chain_node_cli_set_reply_text(a_str_reply, "Subcommand 'info' requires key -hash"); return -1; } if (l_net_str == NULL){ - dap_chain_node_cli_set_reply_text(a_str_reply, "command requires key -net"); - return -1; - } - dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(l_net_str); - if (l_ledger == NULL){ - dap_chain_node_cli_set_reply_text(a_str_reply, "Can't get ledger for net %s", l_net_str); + dap_chain_node_cli_set_reply_text(a_str_reply, "Subcommand 'info' requires key -net"); + return -2; + } + dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_str); + if (!l_net) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Can't find net %s", l_net_str); return -2; } dap_chain_hash_fast_t *l_tx_hash = DAP_NEW(dap_chain_hash_fast_t); if(dap_chain_hash_fast_from_str(l_tx_hash_str, l_tx_hash)){ dap_chain_node_cli_set_reply_text(a_str_reply, "Can't get hash_fast from %s", l_tx_hash_str); - return -2; + return -4; } - dap_chain_datum_tx_t *l_datum_tx = dap_chain_ledger_tx_find_by_hash(l_ledger, l_tx_hash); + dap_chain_datum_tx_t *l_datum_tx = dap_chain_net_get_tx_by_hash(l_net, l_tx_hash, + l_unspent_str ? TX_SEARCH_TYPE_NET_UNSPENT : TX_SEARCH_TYPE_NET); if (l_datum_tx == NULL){ dap_chain_node_cli_set_reply_text(a_str_reply, "Can't get datum from transaction hash %s", l_tx_hash_str); - return -2; + return -5; } dap_string_t *l_str = dap_string_new(""); - s_dap_chain_datum_tx_out_data(l_datum_tx, l_ledger, l_str, l_hash_out_type, false, NULL, NULL); + s_dap_chain_datum_tx_out_data(l_datum_tx, l_net->pub.ledger, l_str, l_hash_out_type, l_tx_hash); dap_chain_node_cli_set_reply_text(a_str_reply, l_str->str); dap_string_free(l_str, true); } else{ - dap_chain_node_cli_set_reply_text(a_str_reply, "command requires parameter 'list' or 'tx' or 'info'"); - return -1; + dap_chain_node_cli_set_reply_text(a_str_reply, "Command 'ledger' requires parameter 'list' or 'tx' or 'info'"); + return -6; } return 0; } diff --git a/modules/net/dap_chain_node_dns_client.c b/modules/net/dap_chain_node_dns_client.c index af3c5a5684acea9c28e4fb477d6447249d503f57..419841a1c9e00d0c5f51f1f13b19828c64c2aa1f 100644 --- a/modules/net/dap_chain_node_dns_client.c +++ b/modules/net/dap_chain_node_dns_client.c @@ -219,6 +219,7 @@ int dap_chain_node_info_dns_request(struct in_addr a_addr, uint16_t a_port, char } l_dns_client->dns_request = DAP_NEW_Z(dap_dns_buf_t); if( ! l_dns_client->dns_request){ + DAP_DELETE(l_dns_client->buf); DAP_DELETE(l_dns_client); return -3; } diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c index 8d81a7e50ad12638cb31c4215a9f356d47ac6548..3f4e854118bc6e7eaea764467bf7ec4f8f283edb 100644 --- a/modules/type/dag/dap_chain_cs_dag.c +++ b/modules/type/dag/dap_chain_cs_dag.c @@ -55,7 +55,6 @@ typedef struct dap_chain_cs_dag_event_item { dap_chain_hash_fast_t hash; - dap_chain_hash_fast_t hash_event_content; time_t ts_added; dap_chain_cs_dag_event_t *event; size_t event_size; @@ -96,9 +95,8 @@ static dap_chain_atom_iter_t* s_chain_callback_atom_iter_create_from(dap_chain_t static dap_chain_atom_ptr_t s_chain_callback_atom_iter_find_by_hash(dap_chain_atom_iter_t * a_atom_iter , dap_chain_hash_fast_t * a_atom_hash, size_t * a_atom_size); -static dap_chain_datum_tx_t* s_chain_callback_atom_iter_find_by_tx_hash(dap_chain_t * a_chain , - dap_chain_hash_fast_t * a_atom_hash); - +static dap_chain_datum_tx_t* s_chain_callback_atom_find_by_tx_hash(dap_chain_t *a_chain, + dap_chain_hash_fast_t *a_tx_hash); static dap_chain_datum_t** s_chain_callback_atom_get_datum(dap_chain_atom_ptr_t a_event, size_t a_atom_size, size_t *a_datums_count); // Get event(s) from dag static dap_chain_atom_ptr_t s_chain_callback_atom_iter_get_first( dap_chain_atom_iter_t * a_atom_iter, size_t *a_atom_size ); // Get the fisrt event from dag @@ -147,7 +145,7 @@ int dap_chain_cs_dag_init(void) "\tdoesn't changes after sign add to event. \n\n" "dag -net <chain net name> -chain <chain name> event dump -event <event hash> -from < events | events_lasts | round.new | round.<Round id in hex> > [-H hex|base58(default)]\n" "\tDump event info\n\n" - "dag -net <chain net name> -chain <chain name> event list -from < events | events_lasts | round.new | round.<Round id in hex> \n\n" + "dag -net <chain net name> -chain <chain name> event list -from < events | events_lasts | round.new | round.<Round id in hex> \n\n" "\tShow event list \n\n" "dag -net <chain net name> -chain <chain name> round complete\n\n" "\tComplete the current new round, verify it and if everything is ok - publish new events in chain\n\n" @@ -212,8 +210,7 @@ int dap_chain_cs_dag_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg) a_chain->callback_atom_iter_get_lasts = s_chain_callback_atom_iter_get_lasts; a_chain->callback_atom_find_by_hash = s_chain_callback_atom_iter_find_by_hash; - a_chain->callback_tx_find_by_hash = s_chain_callback_atom_iter_find_by_tx_hash; - + a_chain->callback_tx_find_by_hash = s_chain_callback_atom_find_by_tx_hash; a_chain->callback_add_datums = s_chain_callback_datums_pool_proc; @@ -355,9 +352,9 @@ static int s_dap_chain_add_atom_to_ledger(dap_chain_cs_dag_t * a_dag, dap_ledger l_tx_event->ts_added = a_event_item->ts_added; l_tx_event->event = a_event_item->event; l_tx_event->event_size = a_event_item->event_size; - memcpy(&l_tx_event->hash, &a_event_item->hash, sizeof (l_tx_event->hash) ); + dap_hash_fast(l_tx, dap_chain_datum_tx_get_size(l_tx), &l_tx_event->hash); int l_err = pthread_rwlock_wrlock(l_events_rwlock); - HASH_ADD(hh,PVT(a_dag)->tx_events, hash, sizeof (l_tx_event->hash), l_tx_event); + HASH_ADD(hh,PVT(a_dag)->tx_events, hash, sizeof(l_tx_event->hash), l_tx_event); if (l_err != EDEADLK) { pthread_rwlock_unlock(l_events_rwlock); } @@ -1233,16 +1230,16 @@ static dap_chain_atom_ptr_t s_chain_callback_atom_iter_find_by_hash(dap_chain_at } -static dap_chain_datum_tx_t* s_chain_callback_atom_iter_find_by_tx_hash(dap_chain_t * a_chain , - dap_chain_hash_fast_t * a_atom_hash) +static dap_chain_datum_tx_t* s_chain_callback_atom_find_by_tx_hash(dap_chain_t *a_chain, + dap_chain_hash_fast_t *a_tx_hash) { dap_chain_cs_dag_t * l_dag = DAP_CHAIN_CS_DAG( a_chain ); dap_chain_cs_dag_event_item_t * l_event_item = NULL; pthread_rwlock_rdlock(&PVT(l_dag)->events_rwlock); - HASH_FIND(hh, PVT(l_dag)->tx_events,a_atom_hash,sizeof(*a_atom_hash),l_event_item); + HASH_FIND(hh, PVT(l_dag)->tx_events, a_tx_hash, sizeof(*a_tx_hash), l_event_item); pthread_rwlock_unlock(&PVT(l_dag)->events_rwlock); if ( l_event_item ){ - dap_chain_datum_t * l_datum = dap_chain_cs_dag_event_get_datum(l_event_item->event, l_event_item->event_size) ; + dap_chain_datum_t *l_datum = dap_chain_cs_dag_event_get_datum(l_event_item->event, l_event_item->event_size); return l_datum ? l_datum->header.data_size ? (dap_chain_datum_tx_t*) l_datum->data : NULL :NULL; }else return NULL;