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/dap-sdk/crypto/include/dap_sign.h b/dap-sdk/crypto/include/dap_sign.h index 23d13c366641c28d3f6f0bae351bdc3f2c1a92b2..98def4e69a3de1e7cf1711498b511dd7ce3a946b 100755 --- a/dap-sdk/crypto/include/dap_sign.h +++ b/dap-sdk/crypto/include/dap_sign.h @@ -141,7 +141,7 @@ dap_multi_sign_t *dap_multi_sign_create(dap_multi_sign_params_t *a_params, const int dap_multi_sign_verify(dap_multi_sign_t *a_sign, const void *a_data, const size_t a_data_size); void dap_multi_sign_delete(dap_multi_sign_t *a_sign); -void dap_sign_get_information(dap_sign_t* a_sign, dap_string_t *a_str_out); +void dap_sign_get_information(dap_sign_t *a_sign, dap_string_t *a_str_out, const char *a_hash_out_type); #ifdef __cplusplus } diff --git a/dap-sdk/crypto/src/dap_sign.c b/dap-sdk/crypto/src/dap_sign.c index 7c64420b0b4202cb9cbf8d8a7a5a3e0332b0667b..7ef32815968bae394a8413e7286a74a11f30b96d 100755 --- a/dap-sdk/crypto/src/dap_sign.c +++ b/dap-sdk/crypto/src/dap_sign.c @@ -28,6 +28,7 @@ #include "dap_strfuncs.h" #include "dap_hash.h" #include "dap_sign.h" +#include "dap_enc_base58.h" #include "dap_enc_bliss.h" #include "dap_enc_tesla.h" #include "dap_enc_picnic.h" @@ -410,7 +411,7 @@ int dap_sign_verify(dap_sign_t * a_chain_sign, const void * a_data, const size_t case DAP_ENC_KEY_TYPE_SIG_TESLA: case DAP_ENC_KEY_TYPE_SIG_PICNIC: case DAP_ENC_KEY_TYPE_SIG_DILITHIUM: - if(l_key->dec_na(l_key, a_data, a_data_size, l_sign_data, l_sign_data_size) < 0) + if((ssize_t)l_key->dec_na(l_key, a_data, a_data_size, l_sign_data, l_sign_data_size) < 0) l_ret = 0; else l_ret = 1; @@ -861,14 +862,22 @@ void dap_multi_sign_delete(dap_multi_sign_t *a_sign) * @param a_sign Signature can be NULL * @param a_str_out The output string pointer */ -void dap_sign_get_information(dap_sign_t* a_sign, dap_string_t *a_str_out){ +void dap_sign_get_information(dap_sign_t* a_sign, dap_string_t *a_str_out, const char *a_hash_out_type) +{ dap_string_append_printf(a_str_out, "Signature: \n"); if (a_sign != NULL){ dap_chain_hash_fast_t l_hash_pkey; dap_string_append_printf(a_str_out, "\tType: %s\n", dap_sign_type_to_str(a_sign->header.type)); if(dap_sign_get_pkey_hash(a_sign, &l_hash_pkey)){ - dap_string_append_printf(a_str_out, "\tPublic key hash: %s\n", dap_chain_hash_fast_to_str_new(&l_hash_pkey)); + char *l_hash_str = NULL; + if (!dap_strcmp(a_hash_out_type, "hex")) + l_hash_str = dap_chain_hash_fast_to_str_new(&l_hash_pkey); + else + l_hash_str = dap_enc_base58_encode_hash_to_str(&l_hash_pkey); + dap_string_append_printf(a_str_out, "\tPublic key hash: %s\n", l_hash_str); + DAP_DELETE(l_hash_str); + } dap_string_append_printf(a_str_out, "\tPublic key size: %u\n" "\tSignature size: %u\n", diff --git a/modules/chain/dap_chain_ledger.c b/modules/chain/dap_chain_ledger.c index cebd13bf91905204568363f090ba0e9135c1365e..5f64beb19e574f60e437627b29b114959d9128b7 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; @@ -194,7 +201,7 @@ typedef struct dap_ledger_private { dap_chain_cell_id_t local_cell_id; /* Cache section */ dap_ledger_cache_item_t last_tx; - dap_ledger_cache_item_t last_thres_tx; + dap_ledger_cache_item_t last_spent_tx; dap_ledger_cache_item_t last_emit; dap_ledger_cache_str_item_t last_ticker; } dap_ledger_private_t; @@ -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,9 +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 +2631,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 +2693,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 +2717,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 +2744,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 +2902,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 +2920,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 @@ -2931,8 +2961,8 @@ uint256_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_c * a_public_key_size[in] public key size * a_tx_first_hash [in/out] hash of the initial transaction/ found transaction, if 0 start from the beginning */ -static dap_chain_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger, - const dap_chain_addr_t *a_addr,const char * a_token, dap_chain_hash_fast_t *a_tx_first_hash) +static dap_chain_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr, + const char * a_token, dap_chain_hash_fast_t *a_tx_first_hash) { if(!a_addr || !a_tx_first_hash) return NULL; @@ -2945,8 +2975,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 +3132,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..b643ccfb082eee0092abd0931a925ecf275f3756 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]={}; @@ -836,20 +1019,21 @@ static bool s_net_states_proc(dap_proc_thread_t *a_thread, void *a_arg) switch (l_net_pvt->state) { // State OFFLINE where we don't do anything case NET_STATE_OFFLINE: { + l_net_pvt->links_connected_count = 0; // 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 +1055,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 +1067,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 +1097,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 +1145,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 +1187,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 +1392,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 +1596,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 +2703,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 +2715,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 +2725,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..6c7ff2164fcad12ca13949f3085175dbca11d947 100644 --- a/modules/net/dap_chain_node_cli_cmd_tx.c +++ b/modules/net/dap_chain_node_cli_cmd_tx.c @@ -91,40 +91,29 @@ 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; + char *l_hash_str = NULL; 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_hash_str); } else { char buf[50]; + const char *l_ticker; + if (l_list_tx_any) { + l_ticker = ((dap_chain_tx_token_t*)l_list_tx_any->data)->header.ticker; + } else { + l_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(a_ledger, a_tx_hash); + } 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)); + l_list_tx_any ? " (emit)" : "", l_hash_str, dap_ctime_r(&l_ts_create, buf), l_ticker); } - DAP_DELETE(l_tx_hash_user_str); + DAP_DELETE(l_hash_str); dap_list_free(l_list_tx_any); uint32_t l_tx_items_count = 0; uint32_t l_tx_items_size =a_datum->header.tx_items_size; @@ -132,18 +121,27 @@ static void s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, char l_tmp_buf[70]; dap_sign_t *l_sign_tmp; dap_chain_hash_fast_t l_pkey_hash_tmp; + dap_hash_fast_t *l_hash_tmp = NULL; dap_pkey_t *l_pkey_tmp; while(l_tx_items_count < l_tx_items_size){ uint8_t *item = a_datum->tx_items + l_tx_items_count; size_t l_item_tx_size = dap_chain_datum_item_tx_get_size(item); switch(dap_chain_datum_tx_item_get_type(item)){ case TX_ITEM_TYPE_IN: - l_hash_str_tmp = dap_chain_hash_fast_to_str_new(&((dap_chain_tx_in_t*)item)->header.tx_prev_hash); + l_hash_tmp = &((dap_chain_tx_in_t*)item)->header.tx_prev_hash; + if (dap_hash_fast_is_blank(l_hash_tmp)) { + l_hash_str = dap_strdup("BLANK"); + } else { + if (!dap_strcmp(a_hash_out_type, "hex")) + l_hash_str = dap_chain_hash_fast_to_str_new(l_hash_tmp); + else + l_hash_str = dap_enc_base58_encode_hash_to_str(l_hash_tmp); + } dap_string_append_printf(a_str_out, "\t IN:\nTx_prev_hash: %s\n" "\t\t Tx_out_prev_idx: %u\n", - l_tx_hash_str, + l_hash_str, ((dap_chain_tx_in_t*)item)->header.tx_out_prev_idx); - DAP_DELETE(l_hash_str_tmp); + DAP_DELETE(l_hash_str); break; case TX_ITEM_TYPE_OUT: dap_string_append_printf(a_str_out, "\t OUT:\n" @@ -164,16 +162,26 @@ static void s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, break; } case TX_ITEM_TYPE_TOKEN: - l_hash_str_tmp = dap_chain_hash_fast_to_str_new(&((dap_chain_tx_token_t*)item)->header.token_emission_hash); + l_hash_tmp = &((dap_chain_tx_token_t*)item)->header.token_emission_hash; + if (!dap_strcmp(a_hash_out_type, "hex")) + l_hash_str = dap_chain_hash_fast_to_str_new(l_hash_tmp); + else + l_hash_str = dap_enc_base58_encode_hash_to_str(l_hash_tmp); dap_string_append_printf(a_str_out, "\t TOKEN:\n" "\t\t ticker: %s \n" "\t\t token_emission_hash: %s\n" - "\t\t token_emission_chain_id: 0x%016"DAP_UINT64_FORMAT_x"\n", ((dap_chain_tx_token_t*)item)->header.ticker, l_hash_str_tmp, + "\t\t token_emission_chain_id: 0x%016"DAP_UINT64_FORMAT_x"\n", + ((dap_chain_tx_token_t*)item)->header.ticker, + l_hash_str, ((dap_chain_tx_token_t*)item)->header.token_emission_chain_id.uint64); - DAP_DELETE(l_hash_str_tmp); + DAP_DELETE(l_hash_str); break; case TX_ITEM_TYPE_TOKEN_EXT: - l_hash_str_tmp = dap_chain_hash_fast_to_str_new(&((dap_chain_tx_token_ext_t*)item)->header.ext_tx_hash); + l_hash_tmp = &((dap_chain_tx_token_ext_t*)item)->header.ext_tx_hash; + if (!dap_strcmp(a_hash_out_type, "hex")) + l_hash_str = dap_chain_hash_fast_to_str_new(l_hash_tmp); + else + l_hash_str = dap_enc_base58_encode_hash_to_str(l_hash_tmp); dap_string_append_printf(a_str_out, "\t TOKEN EXT:\n" "\t\t Version: %u\n" "\t\t Ticker: %s\n" @@ -185,15 +193,15 @@ static void s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, ((dap_chain_tx_token_ext_t*)item)->header.ticker, ((dap_chain_tx_token_ext_t*)item)->header.ext_chain_id.uint64, ((dap_chain_tx_token_ext_t*)item)->header.ext_net_id.uint64, - l_hash_str_tmp, + l_hash_str, ((dap_chain_tx_token_ext_t*)item)->header.ext_tx_out_idx); - DAP_FREE(l_hash_str_tmp); + DAP_DELETE(l_hash_str); break; case TX_ITEM_TYPE_SIG: l_sign_tmp = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t*)item); dap_string_append_printf(a_str_out, "\t SIG:\n" "\t sig_size: %u\n", ((dap_chain_tx_sig_t*)item)->header.sig_size); - dap_sign_get_information(l_sign_tmp, a_str_out); + dap_sign_get_information(l_sign_tmp, a_str_out, a_hash_out_type); break; case TX_ITEM_TYPE_RECEIPT: dap_string_append_printf(a_str_out, "\t Receipt:\n" @@ -224,21 +232,24 @@ static void s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, sizeof(dap_sign_t)); dap_string_append_printf(a_str_out, "Exts:\n" " Provider:\n"); - dap_sign_get_information(l_provider, a_str_out); + dap_sign_get_information(l_provider, a_str_out, a_hash_out_type); dap_string_append_printf(a_str_out, " Client:\n"); - dap_sign_get_information(l_client, a_str_out); + dap_sign_get_information(l_client, a_str_out, a_hash_out_type); } else if (((dap_chain_datum_tx_receipt_t*)item)->exts_size == sizeof(dap_sign_t)) { dap_sign_t *l_provider = DAP_NEW_Z(dap_sign_t); memcpy(l_provider, ((dap_chain_datum_tx_receipt_t*)item)->exts_n_signs, sizeof(dap_sign_t)); dap_string_append_printf(a_str_out, "Exts:\n" " Provider:\n"); - dap_sign_get_information(l_provider, a_str_out); + dap_sign_get_information(l_provider, a_str_out, a_hash_out_type); } break; case TX_ITEM_TYPE_PKEY: l_pkey_tmp = (dap_pkey_t*)((dap_chain_tx_pkey_t*)item)->pkey; dap_hash_fast(l_pkey_tmp->pkey, l_pkey_tmp->header.size, &l_pkey_hash_tmp); - l_hash_str_tmp = dap_chain_hash_fast_to_str_new(&l_pkey_hash_tmp); + if (!dap_strcmp(a_hash_out_type, "hex")) + l_hash_str = dap_chain_hash_fast_to_str_new(&l_pkey_hash_tmp); + else + l_hash_str = dap_enc_base58_encode_hash_to_str(&l_pkey_hash_tmp); dap_string_append_printf(a_str_out, "\t PKey: \n" "\t\t SIG type: %s\n" "\t\t SIG size: %u\n" @@ -252,18 +263,22 @@ static void s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, ((dap_chain_tx_pkey_t*)item)->seq_no, dap_pkey_type_to_str(l_pkey_tmp->header.type), l_pkey_tmp->header.size, - l_hash_str_tmp); - DAP_FREE(l_hash_str_tmp); + l_hash_str); + DAP_DELETE(l_hash_str); break; case TX_ITEM_TYPE_IN_COND: - l_hash_str_tmp = dap_chain_hash_fast_to_str_new(&((dap_chain_tx_in_t*)item)->header.tx_prev_hash); + l_hash_tmp = &((dap_chain_tx_in_cond_t*)item)->header.tx_prev_hash; + if (!dap_strcmp(a_hash_out_type, "hex")) + l_hash_str = dap_chain_hash_fast_to_str_new(l_hash_tmp); + else + l_hash_str = dap_enc_base58_encode_hash_to_str(l_hash_tmp); dap_string_append_printf(a_str_out, "\t IN COND:\n\t\tReceipt_idx: %u\n" "\t\t Tx_prev_hash: %s\n" "\t\t Tx_out_prev_idx: %u\n", ((dap_chain_tx_in_cond_t*)item)->header.receipt_idx, - l_hash_str_tmp, + l_hash_str, ((dap_chain_tx_in_cond_t*)item)->header.tx_out_prev_idx); - DAP_FREE(l_hash_str_tmp); + DAP_DELETE(l_hash_str); break; case TX_ITEM_TYPE_OUT_COND: dap_string_append_printf(a_str_out, "\t OUT COND:\n" @@ -279,18 +294,22 @@ static void s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, dap_chain_tx_out_cond_subtype_to_str(((dap_chain_tx_out_cond_old_t*)item)->header.subtype)); switch (((dap_chain_tx_out_cond_t*)item)->header.subtype) { case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY: - l_hash_str_tmp = dap_chain_hash_fast_to_str_new(&((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.pkey_hash); + l_hash_tmp = &((dap_chain_tx_out_cond_old_t*)item)->subtype.srv_pay.pkey_hash; + if (!dap_strcmp(a_hash_out_type, "hex")) + l_hash_str = dap_chain_hash_fast_to_str_new(l_hash_tmp); + else + l_hash_str = dap_enc_base58_encode_hash_to_str(l_hash_tmp); dap_string_append_printf(a_str_out, "\t\t\t unit: 0x%08x\n" "\t\t\t uid: 0x%016"DAP_UINT64_FORMAT_x"\n" "\t\t\t pkey: %s\n" "\t\t\t max price: %s (%"DAP_UINT64_FORMAT_U") \n", ((dap_chain_tx_out_cond_old_t*)item)->subtype.srv_pay.unit.uint32, ((dap_chain_tx_out_cond_old_t*)item)->subtype.srv_pay.srv_uid.uint64, - l_hash_str_tmp, + l_hash_str, dap_chain_balance_to_coins(dap_chain_uint256_from( ((dap_chain_tx_out_cond_old_t*)item)->subtype.srv_pay.unit_price_max_datoshi)), ((dap_chain_tx_out_cond_old_t*)item)->subtype.srv_pay.unit_price_max_datoshi); - DAP_FREE(l_hash_str_tmp); + DAP_DELETE(l_hash_str); break; case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE: dap_string_append_printf(a_str_out, "\t\t\t uid: 0x%016"DAP_UINT64_FORMAT_x"\n" @@ -331,18 +350,22 @@ static void s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, ); switch (((dap_chain_tx_out_cond_t*)item)->header.subtype) { case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY: - l_hash_str_tmp = dap_chain_hash_fast_to_str_new(&((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.pkey_hash); + l_hash_tmp = &((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.pkey_hash; + if (!dap_strcmp(a_hash_out_type, "hex")) + l_hash_str = dap_chain_hash_fast_to_str_new(l_hash_tmp); + else + l_hash_str = dap_enc_base58_encode_hash_to_str(l_hash_tmp); dap_string_append_printf(a_str_out, "\t\t\t unit: 0x%08x\n" "\t\t\t uid: 0x%016"DAP_UINT64_FORMAT_x"\n" "\t\t\t pkey: %s\n" "\t\t\t max price: %s (%s) \n", ((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.unit.uint32, ((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.srv_uid.uint64, - l_hash_str_tmp, + l_hash_str, dap_chain_balance_to_coins(((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.unit_price_max_datoshi), dap_chain_balance_print(((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.unit_price_max_datoshi) ); - DAP_FREE(l_hash_str_tmp); + DAP_DELETE(l_hash_str); break; case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE: dap_string_append_printf(a_str_out, "\t\t\t uid: 0x%016"DAP_UINT64_FORMAT_x"\n" @@ -973,36 +996,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) @@ -1107,7 +1113,7 @@ static char* dap_db_history_filter(dap_chain_t * a_chain, dap_ledger_t *a_ledger if(!a_filter_token_name || !dap_strcmp(l_token_em->hdr.ticker, a_filter_token_name)) { char * l_token_emission_address_str = dap_chain_addr_to_str(&(l_token_em->hdr.address)); // filter for addr - if(dap_strcmp(a_filtr_addr_base58,l_token_emission_address_str)) { + if (a_filtr_addr_base58 && dap_strcmp(a_filtr_addr_base58, l_token_emission_address_str)) { break; } if ( l_token_em->hdr.version == 1 ) { // && l_token_em->hdr.type_256 ) { // 256 @@ -1171,10 +1177,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: @@ -1243,7 +1258,7 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) const char * l_hash_out_type = NULL; dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-H", &l_hash_out_type); if(!l_hash_out_type) - l_hash_out_type = "base58"; + l_hash_out_type = "hex"; if(dap_strcmp(l_hash_out_type,"hex") && dap_strcmp(l_hash_out_type,"base58")) { dap_chain_node_cli_set_reply_text(a_str_reply, "invalid parameter -H, valid values: -H <hex | base58>"); return -1; @@ -1298,7 +1313,8 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) //const char *l_chain_group = dap_chain_gdb_get_group(l_chain); dap_chain_hash_fast_t l_tx_hash; if(l_tx_hash_str) { - if(dap_chain_hash_fast_from_str(l_tx_hash_str, &l_tx_hash) < 0) { + if (dap_chain_hash_fast_from_str(l_tx_hash_str, &l_tx_hash) && + dap_enc_base58_hex_to_hash(l_tx_hash_str, &l_tx_hash)) { l_tx_hash_str = NULL; dap_chain_node_cli_set_reply_text(a_str_reply, "tx hash not recognized"); return -1; @@ -1392,9 +1408,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 +1437,43 @@ 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)){ + if (dap_chain_hash_fast_from_str(l_tx_hash_str, l_tx_hash) && + dap_enc_base58_hex_to_hash(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; diff --git a/modules/type/dag/dap_chain_cs_dag_event.c b/modules/type/dag/dap_chain_cs_dag_event.c index bcdb5ce1e101de818a5964e4f35298b1e32fe55e..8ec8716bf12c8e858c95699163eccac9fa824f32 100644 --- a/modules/type/dag/dap_chain_cs_dag_event.c +++ b/modules/type/dag/dap_chain_cs_dag_event.c @@ -198,7 +198,7 @@ bool dap_chain_cs_dag_event_gdb_set(char *a_event_hash_str, dap_chain_cs_dag_eve return ret; } -dap_chain_cs_dag_event_t* dap_chain_cs_dag_event_gdb_get(char *a_event_hash_str, uint32_t * a_event_size, const char *a_group, +dap_chain_cs_dag_event_t* dap_chain_cs_dag_event_gdb_get(const char *a_event_hash_str, size_t *a_event_size, const char *a_group, dap_chain_cs_dag_event_round_cfg_t * a_event_round_cfg) { size_t l_event_round_item_size = 0; dap_chain_cs_dag_event_round_item_t* l_event_round_item = diff --git a/modules/type/dag/include/dap_chain_cs_dag.h b/modules/type/dag/include/dap_chain_cs_dag.h index ac2ac6074724c973673dd968cab86f8c58677e5e..48d9cd9d153f0bd66395ad4c15517bc87180fe51 100644 --- a/modules/type/dag/include/dap_chain_cs_dag.h +++ b/modules/type/dag/include/dap_chain_cs_dag.h @@ -36,7 +36,7 @@ typedef dap_chain_cs_dag_event_t * (*dap_chain_cs_dag_callback_event_create_t)(d dap_chain_hash_fast_t *, size_t, size_t*); -typedef int (*dap_chain_cs_dag_callback_get_round_cfg_t)(dap_chain_cs_dag_t *, dap_chain_cs_dag_event_round_cfg_t *); +typedef void (*dap_chain_cs_dag_callback_get_round_cfg_t)(dap_chain_cs_dag_t *, dap_chain_cs_dag_event_round_cfg_t *); typedef void (*dap_chain_cs_dag_callback_set_event_round_cfg_t)(dap_chain_cs_dag_t *, dap_chain_cs_dag_event_round_cfg_t *); typedef struct dap_chain_cs_dag_hal_item { diff --git a/modules/type/dag/include/dap_chain_cs_dag_event.h b/modules/type/dag/include/dap_chain_cs_dag_event.h index 244c2fbd965cb7b60d94a0e7adc9ae7341c88576..7b188243ab36a9d110804607aff41dcd1ab67366 100644 --- a/modules/type/dag/include/dap_chain_cs_dag_event.h +++ b/modules/type/dag/include/dap_chain_cs_dag_event.h @@ -145,6 +145,6 @@ static inline uint32_t dap_chain_cs_dag_event_round_item_get_size(dap_chain_cs_d bool dap_chain_cs_dag_event_gdb_set(char *a_event_hash_str, dap_chain_cs_dag_event_t * a_event, uint32_t a_event_size, const char *a_group, dap_chain_cs_dag_event_round_cfg_t * a_event_round_cfg); -dap_chain_cs_dag_event_t* dap_chain_cs_dag_event_gdb_get(char *a_event_hash_str, uint32_t * a_event_size, +dap_chain_cs_dag_event_t* dap_chain_cs_dag_event_gdb_get(const char *a_event_hash_str, size_t *a_event_size, const char *a_group, dap_chain_cs_dag_event_round_cfg_t * a_event_round_cfg);