From a4a4cb0b7e8bf1762f9446854685e9f4d5012626 Mon Sep 17 00:00:00 2001 From: Roman Khlopkov <roman.khlopkov@demlabs.net> Date: Wed, 16 Mar 2022 06:33:39 +0000 Subject: [PATCH] support-5341 --- dap-sdk/core/src/dap_common.c | 3 +- modules/chain/dap_chain_ledger.c | 504 ++++++++++------------- modules/chain/include/dap_chain_ledger.h | 5 +- modules/common/dap_chain_datum_token.c | 22 +- modules/global-db/dap_chain_global_db.c | 2 +- modules/mempool/dap_chain_mempool.c | 8 +- modules/net/dap_chain_net.c | 18 +- modules/net/include/dap_chain_net.h | 6 +- 8 files changed, 265 insertions(+), 303 deletions(-) diff --git a/dap-sdk/core/src/dap_common.c b/dap-sdk/core/src/dap_common.c index c48ba80359..c581a5fed7 100755 --- a/dap-sdk/core/src/dap_common.c +++ b/dap-sdk/core/src/dap_common.c @@ -378,7 +378,8 @@ static int s_check_and_fill_buffer_log(char **m, struct tm *a_tm_st, char *a_tmp a_tm_st->tm_min >= l_tm.tm_min && a_tm_st->tm_sec >= l_tm.tm_sec) { size_t l_len = strlen(a_tmp); - strncpy(s, a_tmp, l_len); + memcpy(s, a_tmp, l_len); + s[l_len] = '\0'; s += l_len; //*s++ = '\n'; *m = s; diff --git a/modules/chain/dap_chain_ledger.c b/modules/chain/dap_chain_ledger.c index cb0696b901..ae129db15a 100644 --- a/modules/chain/dap_chain_ledger.c +++ b/modules/chain/dap_chain_ledger.c @@ -82,14 +82,8 @@ typedef struct dap_chain_ledger_token_item { uint16_t type; dap_chain_datum_token_t * datum_token; - //union { - // uint64_t total_supply; - uint256_t total_supply; // 256 - //}; - // union { - // uint64_t current_supply; - uint256_t current_supply; - //}; + uint256_t total_supply; + uint256_t current_supply; pthread_rwlock_t token_emissions_rwlock; dap_chain_ledger_token_emission_item_t * token_emissions; @@ -177,8 +171,8 @@ typedef struct dap_ledger_cache_str_item { typedef struct dap_ledger_private { dap_chain_net_t * net; // List of ledger - unspent transactions cache - dap_chain_ledger_tx_item_t *treshold_txs; - dap_chain_ledger_token_emission_item_t * treshold_emissions; + dap_chain_ledger_tx_item_t *threshold_txs; + dap_chain_ledger_token_emission_item_t * threshold_emissions; dap_chain_ledger_tx_item_t *ledger_items; dap_chain_ledger_tx_spent_item_t *spent_items; @@ -192,8 +186,8 @@ typedef struct dap_ledger_private { // for separate access to tokens pthread_rwlock_t tokens_rwlock; - pthread_rwlock_t treshold_txs_rwlock; - pthread_rwlock_t treshold_emissions_rwlock; + pthread_rwlock_t threshold_txs_rwlock; + pthread_rwlock_t threshold_emissions_rwlock; pthread_rwlock_t balance_accounts_rwlock; uint16_t check_flags; @@ -215,14 +209,14 @@ typedef struct dap_ledger_private { 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 void s_treshold_emissions_proc( dap_ledger_t * a_ledger); -static void s_treshold_txs_proc( dap_ledger_t * a_ledger); +static void s_threshold_emissions_proc( dap_ledger_t * a_ledger); +static void s_threshold_txs_proc( dap_ledger_t * a_ledger); static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_item_t *a_token_item , dap_chain_datum_token_t * a_token, size_t a_token_size); static int s_ledger_permissions_check(dap_chain_ledger_token_item_t * a_token_item, uint16_t a_permission_id, const void * a_data,size_t a_data_size ); static bool s_ledger_tps_callback(void *a_arg); -static size_t s_treshold_emissions_max = 1000; -static size_t s_treshold_txs_max = 10000; +static size_t s_threshold_emissions_max = 1000; +static size_t s_threshold_txs_max = 10000; static bool s_debug_more = false; static bool s_token_supply_limit_disable = false; @@ -264,10 +258,10 @@ static dap_ledger_t * dap_chain_ledger_handle_new(void) l_ledger->_internal = l_ledger_pvt = DAP_NEW_Z(dap_ledger_private_t); // Initialize Read/Write Lock Attribute - pthread_rwlock_init(&l_ledger_pvt->ledger_rwlock, NULL); // PTHREAD_RWLOCK_INITIALIZER; + pthread_rwlock_init(&l_ledger_pvt->ledger_rwlock, NULL); pthread_rwlock_init(&l_ledger_pvt->tokens_rwlock, NULL); - pthread_rwlock_init(&l_ledger_pvt->treshold_txs_rwlock , NULL); - pthread_rwlock_init(&l_ledger_pvt->treshold_emissions_rwlock , NULL); + pthread_rwlock_init(&l_ledger_pvt->threshold_txs_rwlock , NULL); + pthread_rwlock_init(&l_ledger_pvt->threshold_emissions_rwlock , NULL); pthread_rwlock_init(&l_ledger_pvt->balance_accounts_rwlock , NULL); return l_ledger; } @@ -285,8 +279,8 @@ void dap_chain_ledger_handle_free(dap_ledger_t *a_ledger) // Destroy Read/Write Lock pthread_rwlock_destroy(&PVT(a_ledger)->ledger_rwlock); pthread_rwlock_destroy(&PVT(a_ledger)->tokens_rwlock); - pthread_rwlock_destroy(&PVT(a_ledger)->treshold_txs_rwlock ); - pthread_rwlock_destroy(&PVT(a_ledger)->treshold_emissions_rwlock ); + pthread_rwlock_destroy(&PVT(a_ledger)->threshold_txs_rwlock ); + pthread_rwlock_destroy(&PVT(a_ledger)->threshold_emissions_rwlock ); pthread_rwlock_destroy(&PVT(a_ledger)->balance_accounts_rwlock ); DAP_DELETE(PVT(a_ledger)); DAP_DELETE(a_ledger); @@ -464,8 +458,8 @@ int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t * if(s_debug_more) log_it(L_WARNING,"Unknown token declaration type 0x%04X", a_token->type ); } - // Proc emissions tresholds - s_treshold_emissions_proc( a_ledger); //TODO process thresholds only for no-consensus chains + // Proc emissions thresholds + s_threshold_emissions_proc( a_ledger); //TODO process thresholds only for no-consensus chains return 0; } @@ -983,105 +977,87 @@ dap_list_t *dap_chain_ledger_token_info(dap_ledger_t *a_ledger) */ bool s_update_token_cache(dap_ledger_t *a_ledger, dap_chain_ledger_token_item_t * l_token_item, uint256_t l_emission_value) { - dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); - - char *l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_TOKENS_STR); - size_t l_obj_length = 0; - - // - // Get dap_chain_datum_token_t token object from GDB, key is token name - // - - dap_chain_datum_token_t *l_token_for_update = (dap_chain_datum_token_t *) dap_chain_global_db_gr_get(l_token_item->ticker, &l_obj_length, l_gdb_group); - dap_chain_datum_token_t *l_token_cache = DAP_NEW_Z_SIZE(dap_chain_datum_token_t, l_obj_length); - - memcpy(l_token_cache, l_token_for_update, l_obj_length); - - if (compare256(l_token_cache->header_private.current_supply_256, l_emission_value) >= 0) - { - SUBTRACT_256_256(l_token_cache->header_private.current_supply_256, l_emission_value, &l_token_cache->header_private.current_supply_256); - log_it(L_DEBUG,"New current supply %s for token %s", dap_chain_balance_print(l_token_cache->header_private.current_supply_256), l_token_item->ticker); - - //Update value in ledger memory object - - l_token_item->current_supply = l_token_cache->header_private.current_supply_256; - } - else - { - log_it(L_WARNING,"Token current supply %s lower, than emission value = %s", dap_chain_balance_print(l_token_cache->header_private.current_supply_256), + //Update value in ledger memory object + if (compare256(l_token_item->current_supply, l_emission_value) >= 0) { + SUBTRACT_256_256(l_token_item->current_supply, l_emission_value, &l_token_item->current_supply); + log_it(L_DEBUG,"New current supply %s for token %s", + dap_chain_balance_print(l_token_item->current_supply), l_token_item->ticker); + } else { + log_it(L_WARNING,"Token current supply %s lower, than emission value = %s", + dap_chain_balance_print(l_token_item->current_supply), dap_chain_balance_print(l_emission_value)); - - DAP_DELETE(l_gdb_group); - DAP_DELETE(l_token_cache); return false; } - - if (!dap_chain_global_db_gr_set(dap_strdup(l_token_item->ticker), l_token_cache, l_obj_length, l_gdb_group)) - { + // Get dap_chain_datum_token_t token object from GDB, key is token name + char *l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_TOKENS_STR); + size_t l_obj_length = 0; + dap_chain_datum_token_t *l_token_cache = (dap_chain_datum_token_t *) + dap_chain_global_db_gr_get(l_token_item->ticker, &l_obj_length, l_gdb_group); + l_token_cache->header_private.current_supply_256 = l_token_item->current_supply; + if (!dap_chain_global_db_gr_set(l_token_item->ticker, l_token_cache, l_obj_length, l_gdb_group)) { if(s_debug_more) log_it(L_WARNING, "Ledger cache mismatch"); - DAP_DELETE(l_token_cache); } - + DAP_DELETE(l_token_cache); DAP_DELETE(l_gdb_group); - return true; } /** - * @brief s_treshold_emissions_proc + * @brief s_threshold_emissions_proc * @param a_ledger */ -static void s_treshold_emissions_proc(dap_ledger_t * a_ledger) +static void s_threshold_emissions_proc(dap_ledger_t * a_ledger) { bool l_success; do { l_success = false; dap_chain_ledger_token_emission_item_t *l_emission_item, *l_emission_tmp; - pthread_rwlock_rdlock(&PVT(a_ledger)->treshold_emissions_rwlock); - HASH_ITER(hh, PVT(a_ledger)->treshold_emissions, l_emission_item, l_emission_tmp) { - pthread_rwlock_unlock(&PVT(a_ledger)->treshold_emissions_rwlock); + pthread_rwlock_rdlock(&PVT(a_ledger)->threshold_emissions_rwlock); + HASH_ITER(hh, PVT(a_ledger)->threshold_emissions, l_emission_item, l_emission_tmp) { + pthread_rwlock_unlock(&PVT(a_ledger)->threshold_emissions_rwlock); int l_res = dap_chain_ledger_token_emission_add(a_ledger, (byte_t *)l_emission_item->datum_token_emission, - l_emission_item->datum_token_emission_size); + l_emission_item->datum_token_emission_size, + &l_emission_item->datum_token_emission_hash, true); if (l_res != DAP_CHAIN_CS_VERIFY_CODE_TX_NO_TOKEN) { - pthread_rwlock_wrlock(&PVT(a_ledger)->treshold_emissions_rwlock); - HASH_DEL(PVT(a_ledger)->treshold_emissions, l_emission_item); - pthread_rwlock_unlock(&PVT(a_ledger)->treshold_emissions_rwlock); + pthread_rwlock_wrlock(&PVT(a_ledger)->threshold_emissions_rwlock); + HASH_DEL(PVT(a_ledger)->threshold_emissions, l_emission_item); + pthread_rwlock_unlock(&PVT(a_ledger)->threshold_emissions_rwlock); DAP_DELETE(l_emission_item); l_success = true; } - pthread_rwlock_rdlock(&PVT(a_ledger)->treshold_emissions_rwlock); + pthread_rwlock_rdlock(&PVT(a_ledger)->threshold_emissions_rwlock); } - pthread_rwlock_unlock(&PVT(a_ledger)->treshold_emissions_rwlock); + pthread_rwlock_unlock(&PVT(a_ledger)->threshold_emissions_rwlock); } while (l_success); } /** - * @brief s_treshold_txs_proc + * @brief s_threshold_txs_proc * @param a_ledger */ -static void s_treshold_txs_proc( dap_ledger_t *a_ledger) +static void s_threshold_txs_proc( dap_ledger_t *a_ledger) { bool l_success; dap_ledger_private_t * l_ledger_pvt = PVT(a_ledger); - pthread_rwlock_rdlock(&l_ledger_pvt->treshold_txs_rwlock); + pthread_rwlock_rdlock(&l_ledger_pvt->threshold_txs_rwlock); do { l_success = false; dap_chain_ledger_tx_item_t *l_tx_item, *l_tx_tmp; - HASH_ITER(hh, l_ledger_pvt->treshold_txs, l_tx_item, l_tx_tmp) { - pthread_rwlock_unlock(&l_ledger_pvt->treshold_txs_rwlock ); + HASH_ITER(hh, l_ledger_pvt->threshold_txs, l_tx_item, l_tx_tmp) { + pthread_rwlock_unlock(&l_ledger_pvt->threshold_txs_rwlock ); int l_res = dap_chain_ledger_tx_add(a_ledger, l_tx_item->tx, &l_tx_item->tx_hash_fast, true); - pthread_rwlock_wrlock(&l_ledger_pvt->treshold_txs_rwlock); + pthread_rwlock_wrlock(&l_ledger_pvt->threshold_txs_rwlock); if (l_res != DAP_CHAIN_CS_VERIFY_CODE_TX_NO_EMISSION && l_res != DAP_CHAIN_CS_VERIFY_CODE_TX_NO_PREVIOUS) { - HASH_DEL(l_ledger_pvt->treshold_txs, l_tx_item); + HASH_DEL(l_ledger_pvt->threshold_txs, l_tx_item); DAP_DELETE(l_tx_item); l_success = true; } } } while (l_success); - pthread_rwlock_unlock(&l_ledger_pvt->treshold_txs_rwlock); + pthread_rwlock_unlock(&l_ledger_pvt->threshold_txs_rwlock); } void dap_chain_ledger_load_cache(dap_ledger_t *a_ledger) @@ -1095,8 +1071,6 @@ void dap_chain_ledger_load_cache(dap_ledger_t *a_ledger) dap_chain_ledger_token_item_t *l_token_item = DAP_NEW_Z(dap_chain_ledger_token_item_t); strncpy(l_token_item->ticker, l_objs[i].key, sizeof(l_token_item->ticker) - 1); l_token_item->ticker[sizeof(l_token_item->ticker) - 1] = '\0'; - // l_token_item->datum_token = DAP_NEW_Z_SIZE(dap_chain_datum_token_t, l_objs[i].value_len); - // memcpy(l_token_item->datum_token, l_objs[i].value, l_objs[i].value_len); size_t l_token_size = l_objs[i].value_len; l_token_item->datum_token = dap_chain_datum_token_read(l_objs[i].value, &l_token_size); pthread_rwlock_init(&l_token_item->token_emissions_rwlock, NULL); @@ -1132,27 +1106,14 @@ void dap_chain_ledger_load_cache(dap_ledger_t *a_ledger) continue; dap_chain_ledger_token_emission_item_t *l_emission_item = DAP_NEW_Z(dap_chain_ledger_token_emission_item_t); dap_chain_hash_fast_from_str(l_objs[i].key, &l_emission_item->datum_token_emission_hash); - size_t l_emission_size = l_objs[i].value_len; const char *c_token_ticker = ((dap_chain_datum_token_emission_t *)l_objs[i].value)->hdr.ticker; dap_chain_ledger_token_item_t *l_token_item = NULL; HASH_FIND_STR(l_ledger_pvt->tokens, c_token_ticker, l_token_item); - // l_emission_item->datum_token_emission = l_token_item - // ? dap_chain_datum_emission_read(l_objs[i].value, &l_emission_size) - // : DAP_DUP_SIZE(l_objs[i].value, l_objs[i].value_len); - - l_emission_item->datum_token_emission = dap_chain_datum_emission_read(l_objs[i].value, &l_emission_size); - l_emission_item->datum_token_emission_size = l_emission_size; - - // need to check after token emission will be working in develop build - //log_it(L_WARNING,"Ledger cache datum_token_emission %lld, ticker: %s", l_emission_item->datum_token_emission->hdr.value, c_token_ticker); - - if (l_token_item) { + l_emission_item->datum_token_emission = DAP_DUP_SIZE(l_objs[i].value, l_objs[i].value_len); + l_emission_item->datum_token_emission_size = l_objs[i].value_len; + if (l_token_item) HASH_ADD(hh, l_token_item->token_emissions, datum_token_emission_hash, sizeof(dap_chain_hash_fast_t), l_emission_item); - } else { - HASH_ADD(hh, l_ledger_pvt->treshold_emissions, datum_token_emission_hash, - sizeof(dap_chain_hash_fast_t), l_emission_item); - } } dap_chain_global_db_objs_delete(l_objs, l_objs_count); DAP_DELETE(l_gdb_group); @@ -1188,19 +1149,13 @@ void dap_chain_ledger_load_cache(dap_ledger_t *a_ledger) 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_ledger_wallet_balance_t *l_balance_item = DAP_NEW_Z(dap_ledger_wallet_balance_t); - size_t l_v0_size = sizeof(uint128_t); // for old data - l_balance_item->key = DAP_NEW_Z_SIZE(char, strlen(l_objs[i].key) + 1); strcpy(l_balance_item->key, l_objs[i].key); char *l_ptr = strchr(l_balance_item->key, ' '); if (l_ptr++) { strcpy(l_balance_item->token_ticker, l_ptr); } - if ( l_v0_size == l_objs[i].value_len ) { // old data - l_balance_item->balance.lo = *(uint128_t *)l_objs[i].value; - } else { - l_balance_item->balance = *(uint256_t *)l_objs[i].value; - } + l_balance_item->balance = *(uint256_t *)l_objs[i].value; HASH_ADD_KEYPTR(hh, l_ledger_pvt->balance_accounts, l_balance_item->key, strlen(l_balance_item->key), l_balance_item); } @@ -1262,12 +1217,12 @@ int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_ dap_hash_fast(a_token_emission, a_token_emission_size, &l_token_emission_hash); char * l_hash_str = dap_chain_hash_fast_to_str_new(&l_token_emission_hash); pthread_rwlock_rdlock(l_token_item ? &l_token_item->token_emissions_rwlock - : &l_ledger_priv->treshold_emissions_rwlock); - HASH_FIND(hh,l_token_item ? l_token_item->token_emissions : l_ledger_priv->treshold_emissions, + : &l_ledger_priv->threshold_emissions_rwlock); + HASH_FIND(hh,l_token_item ? l_token_item->token_emissions : l_ledger_priv->threshold_emissions, &l_token_emission_hash, sizeof(l_token_emission_hash), l_token_emission_item); - unsigned long long l_threshold_emissions_count = HASH_COUNT( l_ledger_priv->treshold_emissions); + unsigned long long l_threshold_emissions_count = HASH_COUNT( l_ledger_priv->threshold_emissions); pthread_rwlock_unlock(l_token_item ? &l_token_item->token_emissions_rwlock - : &l_ledger_priv->treshold_emissions_rwlock); + : &l_ledger_priv->threshold_emissions_rwlock); if(l_token_emission_item ) { if(s_debug_more) { if ( l_token_emission_item->datum_token_emission->hdr.version == 1 ) //&& l_token_emission_item->datum_token_emission->hdr.type_256 ) @@ -1278,10 +1233,10 @@ int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_ l_token_emission_item->datum_token_emission->hdr.value, c_token_ticker, l_hash_str); } l_ret = -1; - }else if ( (! l_token_item) && ( l_threshold_emissions_count >= s_treshold_emissions_max)) { + }else if ( (! l_token_item) && ( l_threshold_emissions_count >= s_threshold_emissions_max)) { if(s_debug_more) - log_it(L_WARNING,"Treshold for emissions is overfulled (%zu max)", - s_treshold_emissions_max); + log_it(L_WARNING,"threshold for emissions is overfulled (%zu max)", + s_threshold_emissions_max); l_ret = -2; } DAP_DELETE(l_hash_str); @@ -1290,6 +1245,8 @@ int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_ // Check emission correctness size_t l_emission_size = a_token_emission_size; dap_chain_datum_token_emission_t *l_emission = dap_chain_datum_emission_read(a_token_emission, &l_emission_size); + if (compare256(l_token_item->current_supply, l_emission->hdr.value_256) < 0) + return -4; switch (l_emission->hdr.type){ case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH:{ dap_chain_ledger_token_item_t *l_token_item=NULL; @@ -1323,12 +1280,8 @@ int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_ } if (l_aproves < l_aproves_valid ){ if(s_debug_more) { - if ( l_emission->hdr.version == 2 ) // 256 - log_it(L_WARNING, "Emission of %s datoshi of %s:%s is wrong: only %u valid aproves when %u need", - dap_chain_balance_print(l_emission->hdr.value_256), a_ledger->net_name, l_emission->hdr.ticker, l_aproves, l_aproves_valid ); - else - log_it(L_WARNING, "Emission of %"DAP_UINT64_FORMAT_U" datoshi of %s:%s is wrong: only %u valid aproves when %u need", - l_emission->hdr.value, a_ledger->net_name, l_emission->hdr.ticker, l_aproves, l_aproves_valid ); + log_it(L_WARNING, "Emission of %s datoshi of %s:%s is wrong: only %u valid aproves when %u need", + dap_chain_balance_print(l_emission->hdr.value_256), a_ledger->net_name, l_emission->hdr.ticker, l_aproves, l_aproves_valid ); } l_ret = -3; } @@ -1350,96 +1303,79 @@ int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_ * @param a_token_emision_size * @return */ -int dap_chain_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size) +int dap_chain_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size, + dap_hash_fast_t *a_emission_hash, bool a_from_threshold) { int l_ret = 0; dap_ledger_private_t *l_ledger_priv = PVT(a_ledger); - const char * c_token_ticker = ((dap_chain_datum_token_emission_t *)a_token_emission)->hdr.ticker; dap_chain_ledger_token_item_t * l_token_item = NULL; pthread_rwlock_rdlock(&l_ledger_priv->tokens_rwlock); HASH_FIND_STR(l_ledger_priv->tokens, c_token_ticker, l_token_item); pthread_rwlock_unlock(&l_ledger_priv->tokens_rwlock); dap_chain_ledger_token_emission_item_t * l_token_emission_item = NULL; + if (!l_token_item && a_from_threshold) + return DAP_CHAIN_CS_VERIFY_CODE_TX_NO_TOKEN; // check if such emission is already present in table - dap_chain_hash_fast_t l_token_emission_hash = {}; - dap_hash_fast(a_token_emission, a_token_emission_size, &l_token_emission_hash); - char * l_hash_str = dap_chain_hash_fast_to_str_new(&l_token_emission_hash); pthread_rwlock_rdlock( l_token_item ? &l_token_item->token_emissions_rwlock - : &l_ledger_priv->treshold_emissions_rwlock); - HASH_FIND(hh,l_token_item ? l_token_item->token_emissions : l_ledger_priv->treshold_emissions, - &l_token_emission_hash, sizeof(l_token_emission_hash), l_token_emission_item); - unsigned long long l_threshold_emissions_count = HASH_COUNT( l_ledger_priv->treshold_emissions); + : &l_ledger_priv->threshold_emissions_rwlock); + HASH_FIND(hh,l_token_item ? l_token_item->token_emissions : l_ledger_priv->threshold_emissions, + a_emission_hash, sizeof(*a_emission_hash), l_token_emission_item); pthread_rwlock_unlock(l_token_item ? &l_token_item->token_emissions_rwlock - : &l_ledger_priv->treshold_emissions_rwlock); - - if(l_token_emission_item == NULL ) { - if ( l_token_item || l_threshold_emissions_count < s_treshold_emissions_max ) { - l_token_emission_item = DAP_NEW_Z(dap_chain_ledger_token_emission_item_t); - size_t l_emission_size = a_token_emission_size; - l_token_emission_item->datum_token_emission = l_token_item - ? dap_chain_datum_emission_read(a_token_emission, &l_emission_size) - : DAP_DUP_SIZE(a_token_emission, a_token_emission_size); - memcpy(&l_token_emission_item->datum_token_emission_hash, &l_token_emission_hash, sizeof(l_token_emission_hash)); - l_token_emission_item->datum_token_emission_size = l_emission_size; - - // + : &l_ledger_priv->threshold_emissions_rwlock); + char *l_hash_str = dap_chain_hash_fast_to_str_new(a_emission_hash); + if (!l_token_emission_item) { + l_token_emission_item = DAP_NEW_Z(dap_chain_ledger_token_emission_item_t); + l_token_emission_item->datum_token_emission_size = a_token_emission_size; + memcpy(&l_token_emission_item->datum_token_emission_hash, a_emission_hash, sizeof(*a_emission_hash)); + if (l_token_item) { + l_token_emission_item->datum_token_emission = dap_chain_datum_emission_read(a_token_emission, + &l_token_emission_item->datum_token_emission_size); // update current_supply in ledger cache and ledger memory object - // - if (!PVT(a_ledger)->load_mode && l_token_item && !s_token_supply_limit_disable) - { if (!s_update_token_cache(a_ledger, l_token_item, l_token_emission_item->datum_token_emission->hdr.value_256)) - return DAP_CHAIN_CS_VERIFY_CODE_TX_NO_EMISSION; - } - + return -4; if (s_token_supply_limit_disable) - { log_it(L_WARNING,"s_token_supply_limit_disable is enabled in config, please fix it and disable"); - } - if (l_token_item) { - pthread_rwlock_wrlock(&l_token_item->token_emissions_rwlock); - HASH_ADD(hh, l_token_item->token_emissions, datum_token_emission_hash, - sizeof(l_token_emission_hash), l_token_emission_item); - pthread_rwlock_unlock(&l_token_item->token_emissions_rwlock); - // Add it to cache - dap_chain_datum_token_emission_t *l_emission_cache = DAP_DUP_SIZE(a_token_emission, a_token_emission_size); - char *l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_EMISSIONS_STR); - if (!dap_chain_global_db_gr_set(dap_strdup(l_hash_str), l_emission_cache, a_token_emission_size, l_gdb_group)) { - log_it(L_WARNING, "Ledger cache mismatch"); - DAP_DELETE(l_emission_cache); - } - DAP_DELETE(l_gdb_group); - } else { - pthread_rwlock_wrlock(&l_ledger_priv->treshold_emissions_rwlock); - HASH_ADD(hh, l_ledger_priv->treshold_emissions, datum_token_emission_hash, - sizeof(l_token_emission_hash), l_token_emission_item); - pthread_rwlock_unlock(&l_ledger_priv->treshold_emissions_rwlock); - l_ret = DAP_CHAIN_CS_VERIFY_CODE_TX_NO_TOKEN; + pthread_rwlock_wrlock(&l_token_item->token_emissions_rwlock); + HASH_ADD(hh, l_token_item->token_emissions, datum_token_emission_hash, + sizeof(*a_emission_hash), l_token_emission_item); + pthread_rwlock_unlock(&l_token_item->token_emissions_rwlock); + // Add it to cache + char *l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_EMISSIONS_STR); + if (!dap_chain_global_db_gr_set(l_hash_str, a_token_emission, a_token_emission_size,l_gdb_group)) { + log_it(L_WARNING, "Ledger cache mismatch"); } - char * l_token_emission_address_str = dap_chain_addr_to_str(&(l_token_emission_item->datum_token_emission->hdr.address) ); + DAP_DELETE(l_gdb_group); if(s_debug_more) { - if ( l_token_emission_item->datum_token_emission->hdr.version == 1 ) // && l_token_emission_item->datum_token_emission->hdr.type_256 ) - log_it(L_NOTICE, "Added token emission datum to %s: type=%s value=%s token=%s to_addr=%s ", - l_token_item?"emissions cache":"emissions treshold", - c_dap_chain_datum_token_emission_type_str[ l_token_emission_item->datum_token_emission->hdr.type ] , - dap_chain_balance_to_coins( - l_token_emission_item->datum_token_emission->hdr.value_256 - ), c_token_ticker, - l_token_emission_address_str); - else - log_it(L_NOTICE, "Added token emission datum to %s: type=%s value=%.1Lf token=%s to_addr=%s ", - l_token_item?"emissions cache":"emissions treshold", - c_dap_chain_datum_token_emission_type_str[ l_token_emission_item->datum_token_emission->hdr.type ] , - dap_chain_datoshi_to_coins(l_token_emission_item->datum_token_emission->hdr.value), c_token_ticker, - l_token_emission_address_str); + char * l_token_emission_address_str = dap_chain_addr_to_str(&(l_token_emission_item->datum_token_emission->hdr.address)); + log_it(L_NOTICE, "Added token emission datum to emissions cache: type=%s value=%s token=%s to_addr=%s ", + c_dap_chain_datum_token_emission_type_str[l_token_emission_item->datum_token_emission->hdr.type], + dap_chain_balance_to_coins(l_token_emission_item->datum_token_emission->hdr.value_256), + c_token_ticker, l_token_emission_address_str); + DAP_DELETE(l_token_emission_address_str); + } + } else if (HASH_COUNT(l_ledger_priv->threshold_emissions) < s_threshold_emissions_max) { + l_token_emission_item->datum_token_emission = DAP_DUP_SIZE(a_token_emission, a_token_emission_size); + pthread_rwlock_wrlock(&l_ledger_priv->threshold_emissions_rwlock); + HASH_ADD(hh, l_ledger_priv->threshold_emissions, datum_token_emission_hash, + sizeof(*a_emission_hash), l_token_emission_item); + pthread_rwlock_unlock(&l_ledger_priv->threshold_emissions_rwlock); + l_ret = DAP_CHAIN_CS_VERIFY_CODE_TX_NO_TOKEN; + if(s_debug_more) { + char * l_token_emission_address_str = dap_chain_addr_to_str(&(l_token_emission_item->datum_token_emission->hdr.address)); + log_it(L_NOTICE, "Added token emission datum to emissions threshold: type=%s value=%.1Lf token=%s to_addr=%s ", + c_dap_chain_datum_token_emission_type_str[l_token_emission_item->datum_token_emission->hdr.type], + dap_chain_datoshi_to_coins(l_token_emission_item->datum_token_emission->hdr.value), + c_token_ticker, l_token_emission_address_str); + DAP_DELETE(l_token_emission_address_str); } - DAP_DELETE(l_token_emission_address_str); - }else{ + } else { + DAP_DELETE(l_token_emission_item); if(s_debug_more) - log_it(L_WARNING,"Treshold for emissions is overfulled (%zu max), dropping down new data, added nothing", - s_treshold_emissions_max); + log_it(L_WARNING,"threshold for emissions is overfulled (%zu max), dropping down new data, added nothing", + s_threshold_emissions_max); l_ret = -2; } } else { @@ -1456,20 +1392,17 @@ int dap_chain_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_ l_ret = -1; } DAP_DELETE(l_hash_str); - if (!l_ret) - s_treshold_txs_proc(a_ledger); return l_ret; } int dap_chain_ledger_token_emission_load(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size) { + dap_chain_hash_fast_t l_token_emission_hash = {}; + dap_hash_fast(a_token_emission, a_token_emission_size, &l_token_emission_hash); if (PVT(a_ledger)->load_mode) { - dap_chain_hash_fast_t l_token_emission_hash = {}; - dap_hash_fast(a_token_emission, a_token_emission_size, &l_token_emission_hash); dap_chain_ledger_token_emission_item_t *l_token_emission_item; dap_chain_ledger_token_item_t *l_token_item, *l_item_tmp; - pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock); - + pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock); HASH_ITER(hh, PVT(a_ledger)->tokens, l_token_item, l_item_tmp) { pthread_rwlock_rdlock(&l_token_item->token_emissions_rwlock); HASH_FIND(hh, l_token_item->token_emissions, &l_token_emission_hash, sizeof(l_token_emission_hash), @@ -1480,18 +1413,16 @@ int dap_chain_ledger_token_emission_load(dap_ledger_t *a_ledger, byte_t *a_token return 0; } } - pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock); - pthread_rwlock_rdlock(&PVT(a_ledger)->treshold_emissions_rwlock); - HASH_FIND(hh, PVT(a_ledger)->treshold_emissions, &l_token_emission_hash, sizeof(l_token_emission_hash), + pthread_rwlock_rdlock(&PVT(a_ledger)->threshold_emissions_rwlock); + HASH_FIND(hh, PVT(a_ledger)->threshold_emissions, &l_token_emission_hash, sizeof(l_token_emission_hash), l_token_emission_item); - pthread_rwlock_unlock(&PVT(a_ledger)->treshold_emissions_rwlock); + pthread_rwlock_unlock(&PVT(a_ledger)->threshold_emissions_rwlock); if (l_token_emission_item) { return DAP_CHAIN_CS_VERIFY_CODE_TX_NO_TOKEN; } } - - return dap_chain_ledger_token_emission_add(a_ledger, a_token_emission, a_token_emission_size); + return dap_chain_ledger_token_emission_add(a_ledger, a_token_emission, a_token_emission_size, &l_token_emission_hash, false); } /** @@ -1548,14 +1479,16 @@ const char* dap_chain_ledger_tx_get_token_ticker_by_hash(dap_ledger_t *a_ledger, return NULL; dap_chain_ledger_tx_item_t *l_item; + unsigned l_hash_value; + HASH_VALUE(a_tx_hash, sizeof(*a_tx_hash), l_hash_value); 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_BYHASHVALUE(hh, l_ledger_priv->ledger_items, a_tx_hash, sizeof(*a_tx_hash), l_hash_value, 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); + HASH_FIND_BYHASHVALUE(hh, l_ledger_priv->spent_items, a_tx_hash, sizeof(*a_tx_hash), l_hash_value, l_spent_item); pthread_rwlock_unlock(&l_ledger_priv->ledger_rwlock); return l_spent_item ? l_spent_item->token_ticker : NULL; @@ -1650,7 +1583,7 @@ static dap_chain_datum_tx_t* s_find_datum_tx_by_hash(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *l_tx_ret = NULL; dap_chain_ledger_tx_item_t *l_tx_item; 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_tx_item); // tx_hash already in the hash? + HASH_FIND(hh, l_ledger_priv->ledger_items, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_tx_item); pthread_rwlock_unlock(&l_ledger_priv->ledger_rwlock); if(l_tx_item) { l_tx_ret = l_tx_item->tx; @@ -1671,6 +1604,15 @@ dap_chain_datum_tx_t* dap_chain_ledger_tx_find_by_hash(dap_ledger_t *a_ledger, d return s_find_datum_tx_by_hash(a_ledger, a_tx_hash, NULL); } +bool dap_chain_ledger_tx_spent_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash) +{ + dap_chain_ledger_tx_spent_item_t *l_tx_item; + pthread_rwlock_rdlock(&PVT(a_ledger)->ledger_rwlock); + HASH_FIND(hh, PVT(a_ledger)->spent_items, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_tx_item); + pthread_rwlock_unlock(&PVT(a_ledger)->ledger_rwlock); + return l_tx_item; +} + /** * Check whether used 'out' items (local function) */ @@ -1918,37 +1860,33 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t // calculate hash of public key in current transaction dap_chain_hash_fast_t l_hash_pkey; - { - // Get sign item - dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t*) dap_chain_datum_tx_item_get(a_tx, NULL, - TX_ITEM_TYPE_SIG, NULL); - // Get sign from sign item - dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t*) l_tx_sig); - // Get public key from sign - size_t l_pkey_ser_size = 0; - const uint8_t *l_pkey_ser = dap_sign_get_pkey(l_sign, &l_pkey_ser_size); - // calculate hash from public key - dap_hash_fast(l_pkey_ser, l_pkey_ser_size, &l_hash_pkey); - // hash of public key in 'out' item of previous transaction - - uint8_t *l_prev_out_addr_key = NULL; - switch (l_type) { - case TX_ITEM_TYPE_OUT_256: - l_prev_out_addr_key = bound_item->out.tx_prev_out_256->addr.data.key; break; - case TX_ITEM_TYPE_OUT: - l_prev_out_addr_key = bound_item->out.tx_prev_out->addr.data.key; break; - case TX_ITEM_TYPE_OUT_EXT: - l_prev_out_addr_key = bound_item->out.tx_prev_out_ext_256->addr.data.key; break; - default: - log_it(L_DEBUG, "Unknown item type %d", l_type); - break; - } + // Get sign item + dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t*) dap_chain_datum_tx_item_get(a_tx, NULL, + TX_ITEM_TYPE_SIG, NULL); + // Get sign from sign item + dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t*) l_tx_sig); + // Get public key from sign + size_t l_pkey_ser_size = 0; + const uint8_t *l_pkey_ser = dap_sign_get_pkey(l_sign, &l_pkey_ser_size); + // calculate hash from public key + dap_hash_fast(l_pkey_ser, l_pkey_ser_size, &l_hash_pkey); + // hash of public key in 'out' item of previous transaction - // 4. compare public key hashes in the signature of the current transaction and in the 'out' item of the previous transaction - if(memcmp(&l_hash_pkey, l_prev_out_addr_key, sizeof(dap_chain_hash_fast_t))) { - l_err_num = -9; - break; - } + uint8_t *l_prev_out_addr_key = NULL; + switch (l_type) { + case TX_ITEM_TYPE_OUT_256: + l_prev_out_addr_key = bound_item->out.tx_prev_out_256->addr.data.key; break; + case TX_ITEM_TYPE_OUT: + l_prev_out_addr_key = bound_item->out.tx_prev_out->addr.data.key; break; + case TX_ITEM_TYPE_OUT_EXT: + l_prev_out_addr_key = bound_item->out.tx_prev_out_ext_256->addr.data.key; break; + default: break; + } + + // 4. compare public key hashes in the signature of the current transaction and in the 'out' item of the previous transaction + if(memcmp(&l_hash_pkey, l_prev_out_addr_key, sizeof(dap_chain_hash_fast_t))) { + l_err_num = -9; + break; } switch (l_type) { @@ -1960,9 +1898,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t l_value = bound_item->out.tx_prev_out_ext_256->header.value; l_token = bound_item->out.tx_prev_out_ext_256->token; break; - default: - log_it(L_DEBUG, "Unknown item type %d", l_type); - break; + default: break; } } else { // TX_ITEM_TYPE_IN_COND if(*(uint8_t *)l_tx_prev_out != TX_ITEM_TYPE_OUT_256_COND) { @@ -2212,8 +2148,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t if (l_ledger_priv->check_token_emission) { // Check the token emission dap_chain_datum_token_emission_t * l_token_emission = dap_chain_ledger_token_emission_find(a_ledger, l_token, l_emission_hash); if (l_token_emission) { - //if (!EQUAL_256(l_token_emission->hdr.value_256, l_value_cur->sum)) { - if (false){ + if (!EQUAL_256(l_token_emission->hdr.value_256, l_value_cur->sum)) { l_err_num = -10; } l_value_cur = NULL; @@ -2342,6 +2277,7 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_list_t *l_list_bound_items = NULL; dap_list_t *l_list_tx_out = NULL; dap_chain_ledger_tx_item_t *l_item_tmp = NULL; + unsigned l_hash_value = 0; if (!l_ledger_priv->tps_timer) { clock_gettime(CLOCK_REALTIME, &l_ledger_priv->tps_start_time); @@ -2351,9 +2287,12 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, l_ledger_priv->tps_timer = dap_timerfd_start(500, s_ledger_tps_callback, l_ledger_priv); } bool l_from_threshold = a_from_threshold; - 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_ledger_priv->load_mode && !l_from_threshold) { + HASH_VALUE(a_tx_hash, sizeof(*a_tx_hash), l_hash_value); + pthread_rwlock_rdlock(&l_ledger_priv->ledger_rwlock); + HASH_FIND_BYHASHVALUE(hh, l_ledger_priv->ledger_items, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_hash_value, l_item_tmp); + pthread_rwlock_unlock(&l_ledger_priv->ledger_rwlock); + } char l_tx_hash_str[70]; dap_chain_hash_fast_to_str(a_tx_hash, l_tx_hash_str, sizeof(l_tx_hash_str)); if (l_item_tmp) { // transaction already present in the cache list @@ -2368,24 +2307,26 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, a_ledger, a_tx, &l_list_bound_items, &l_list_tx_out)) < 0) { if (l_ret_check == DAP_CHAIN_CS_VERIFY_CODE_TX_NO_PREVIOUS) { if (!l_from_threshold) { - pthread_rwlock_rdlock(&l_ledger_priv->treshold_txs_rwlock); - HASH_FIND(hh, l_ledger_priv->treshold_txs, a_tx_hash, sizeof(*a_tx_hash), l_item_tmp); - unsigned long long l_threshold_txs_count = HASH_COUNT(l_ledger_priv->treshold_txs); + if (!l_hash_value) + HASH_VALUE(a_tx_hash, sizeof(*a_tx_hash), l_hash_value); + pthread_rwlock_rdlock(&l_ledger_priv->threshold_txs_rwlock); + HASH_FIND_BYHASHVALUE(hh, l_ledger_priv->threshold_txs, a_tx_hash, sizeof(*a_tx_hash), l_hash_value, l_item_tmp); + unsigned long long l_threshold_txs_count = HASH_COUNT(l_ledger_priv->threshold_txs); if (!l_item_tmp) { - if (l_threshold_txs_count >= s_treshold_txs_max) { + if (l_threshold_txs_count >= s_threshold_txs_max) { if(s_debug_more) - log_it(L_WARNING,"Treshold for tranactions is overfulled (%zu max), dropping down new data, added nothing", - s_treshold_txs_max); + log_it(L_WARNING,"threshold for tranactions is overfulled (%zu max), dropping down new data, added nothing", + s_threshold_txs_max); } else { l_item_tmp = DAP_NEW_Z(dap_chain_ledger_tx_item_t); memcpy(&l_item_tmp->tx_hash_fast, a_tx_hash, sizeof(dap_chain_hash_fast_t)); l_item_tmp->tx = a_tx; - HASH_ADD(hh, l_ledger_priv->treshold_txs, tx_hash_fast, sizeof(dap_chain_hash_fast_t), l_item_tmp); + HASH_ADD_BYHASHVALUE(hh, l_ledger_priv->threshold_txs, tx_hash_fast, sizeof(dap_chain_hash_fast_t), l_hash_value, l_item_tmp); if(s_debug_more) log_it (L_DEBUG, "Tx %s added to threshold", l_tx_hash_str); } } - pthread_rwlock_unlock(&l_ledger_priv->treshold_txs_rwlock); + pthread_rwlock_unlock(&l_ledger_priv->threshold_txs_rwlock); } } else { if(s_debug_more) @@ -2412,11 +2353,10 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, void *l_item_in = *(void **)&bound_item->in; dap_chain_tx_item_type_t l_type = *(uint8_t *)l_item_in; 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_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 + else l_ticker_trl = dap_stpcpy(l_token_ticker, bound_item->out.tx_prev_out_ext_256->token); if (!l_multichannel && l_ticker_old_trl && strcmp(l_token_ticker, l_token_ticker_old)) { @@ -2429,12 +2369,14 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_ledger_wallet_balance_t *wallet_balance = NULL; uint256_t l_value = {}; dap_chain_addr_t *l_addr = NULL; + void *l_item_out = *(void **)&bound_item->out; + dap_chain_tx_item_type_t l_out_type = *(uint8_t *)l_item_out; switch (l_out_type) { case TX_ITEM_TYPE_OUT_256: l_addr = &bound_item->out.tx_prev_out_256->addr; break; case TX_ITEM_TYPE_OUT: l_addr = &bound_item->out.tx_prev_out->addr; break; case TX_ITEM_TYPE_OUT_EXT: l_addr = &bound_item->out.tx_prev_out_ext_256->addr; break; default: - log_it(L_DEBUG, "Unknown item type %d", l_type); + log_it(L_DEBUG, "Unknown item type %d", l_out_type); break; } char *l_addr_str = dap_chain_addr_to_str(l_addr); @@ -2448,7 +2390,7 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, case TX_ITEM_TYPE_OUT: l_value = GET_256_FROM_64(bound_item->out.tx_prev_out->header.value); break; case TX_ITEM_TYPE_OUT_EXT: l_value = bound_item->out.tx_prev_out_ext_256->header.value; break; default: - log_it(L_DEBUG, "Unknown item type %d", l_type); + log_it(L_DEBUG, "Unknown item type %d", l_out_type); break; } @@ -2575,10 +2517,6 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, break; } char *l_addr_str = dap_chain_addr_to_str(l_addr); - - //log_it (L_DEBUG, "Check unspent %.03Lf %s for addr %s", - // (long double) l_out_item->header.value/ 1000000000000.0L, - // l_token_ticker, l_addr_str); dap_ledger_wallet_balance_t *wallet_balance = NULL; if (l_multichannel) { l_ticker_trl = dap_stpcpy(l_token_ticker, l_out_item_ext_256->token); @@ -2600,8 +2538,8 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, HASH_FIND_STR(PVT(a_ledger)->balance_accounts, l_wallet_balance_key, wallet_balance); pthread_rwlock_unlock(&l_ledger_priv->balance_accounts_rwlock); if (wallet_balance) { - if(s_debug_more) - log_it(L_DEBUG, "Balance item is present in cache"); + //if(s_debug_more) + // log_it(L_DEBUG, "Balance item is present in cache"); SUM_256_256(wallet_balance->balance, l_value_256, &wallet_balance->balance); DAP_DELETE (l_wallet_balance_key); // Update the cache @@ -2612,7 +2550,7 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, strcpy(wallet_balance->token_ticker, l_token_ticker); SUM_256_256(wallet_balance->balance, l_value_256, &wallet_balance->balance); if(s_debug_more) - log_it(L_DEBUG,"!!! Create new balance item: %s %s", l_addr_str, l_token_ticker); + log_it(L_DEBUG, "Create new balance item: %s %s", l_addr_str, l_token_ticker); pthread_rwlock_wrlock(&l_ledger_priv->balance_accounts_rwlock); HASH_ADD_KEYPTR(hh, PVT(a_ledger)->balance_accounts, wallet_balance->key, strlen(l_wallet_balance_key), wallet_balance); @@ -2639,13 +2577,15 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_list_t *l_tist_tmp = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_OUT_ALL, &l_item_tmp->cache_data.n_outs); // If debug mode dump the UTXO if (dap_log_level_get() == L_DEBUG && s_debug_more) { - for (size_t i =0; i < (size_t) l_item_tmp->cache_data.n_outs; i++){ - dap_chain_tx_out_t *l_tx_out = l_tist_tmp->data; + dap_list_t *it = l_tist_tmp; + for (int i = 0; i < l_item_tmp->cache_data.n_outs; i++) { + dap_chain_tx_out_t *l_tx_out = it->data; if (l_tx_out->header.type != TX_ITEM_TYPE_OUT) continue; char * l_tx_out_addr_str = dap_chain_addr_to_str( &l_tx_out->addr ); log_it(L_DEBUG, "Added tx out to %s", l_tx_out_addr_str); DAP_DELETE (l_tx_out_addr_str); + it = it->next; } } if(l_tist_tmp) @@ -2663,8 +2603,10 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, size_t l_tx_size = dap_chain_datum_tx_get_size(a_tx); memcpy(l_item_tmp->tx, a_tx, l_tx_size); - pthread_rwlock_rdlock(&l_ledger_priv->ledger_rwlock); - HASH_ADD(hh, l_ledger_priv->ledger_items, tx_hash_fast, sizeof(dap_chain_hash_fast_t), l_item_tmp); // tx_hash_fast: name of key field + if (!l_hash_value) + HASH_VALUE(a_tx_hash, sizeof(*a_tx_hash), l_hash_value); + pthread_rwlock_wrlock(&l_ledger_priv->ledger_rwlock); + HASH_ADD_BYHASHVALUE(hh, l_ledger_priv->ledger_items, tx_hash_fast, sizeof(dap_chain_hash_fast_t), l_hash_value, l_item_tmp); // tx_hash_fast: name of key field pthread_rwlock_unlock(&l_ledger_priv->ledger_rwlock); // Count TPS clock_gettime(CLOCK_REALTIME, &l_ledger_priv->tps_end_time); @@ -2682,7 +2624,7 @@ 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); // TODO process thresholds only for non consensus chains + s_threshold_txs_proc(a_ledger); // TODO process thresholds only for non consensus chains ret = 1; } return ret; @@ -2709,19 +2651,21 @@ int dap_chain_ledger_tx_load(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, memcpy(a_tx_hash, &l_tx_hash, sizeof(l_tx_hash)); if (PVT(a_ledger)->load_mode) { dap_chain_ledger_tx_item_t *l_tx_item; + unsigned l_hash_value; + HASH_VALUE(&l_tx_hash, sizeof(dap_chain_hash_fast_t), l_hash_value); pthread_rwlock_rdlock(&PVT(a_ledger)->ledger_rwlock); - HASH_FIND(hh, PVT(a_ledger)->ledger_items, &l_tx_hash, sizeof(dap_chain_hash_fast_t), l_tx_item); + HASH_FIND_BYHASHVALUE(hh, PVT(a_ledger)->ledger_items, &l_tx_hash, sizeof(dap_chain_hash_fast_t), l_hash_value, l_tx_item); if (l_tx_item) { pthread_rwlock_unlock(&PVT(a_ledger)->ledger_rwlock); return 1; } - HASH_FIND(hh, PVT(a_ledger)->treshold_txs, &l_tx_hash, sizeof(dap_chain_hash_fast_t), l_tx_item); + HASH_FIND_BYHASHVALUE(hh, PVT(a_ledger)->threshold_txs, &l_tx_hash, sizeof(dap_chain_hash_fast_t), l_hash_value, l_tx_item); if (l_tx_item) { pthread_rwlock_unlock(&PVT(a_ledger)->ledger_rwlock); return DAP_CHAIN_CS_VERIFY_CODE_TX_NO_PREVIOUS; } dap_chain_ledger_tx_spent_item_t *l_tx_spent_item; - HASH_FIND(hh, PVT(a_ledger)->spent_items, &l_tx_hash, sizeof(dap_chain_hash_fast_t), l_tx_spent_item); + HASH_FIND_BYHASHVALUE(hh, PVT(a_ledger)->spent_items, &l_tx_hash, sizeof(dap_chain_hash_fast_t), l_hash_value, l_tx_spent_item); pthread_rwlock_unlock(&PVT(a_ledger)->ledger_rwlock); if (l_tx_spent_item) return 1; @@ -2741,9 +2685,12 @@ int dap_chain_ledger_tx_remove(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_ int l_ret = -1; dap_ledger_private_t *l_ledger_priv = PVT(a_ledger); 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); + unsigned l_hash_value; + HASH_VALUE(a_tx_hash, sizeof(*a_tx_hash), l_hash_value); + pthread_rwlock_wrlock(&l_ledger_priv->ledger_rwlock); + HASH_FIND_BYHASHVALUE(hh, l_ledger_priv->ledger_items, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_hash_value, l_item_tmp); if(l_item_tmp != NULL) { + HASH_DEL(l_ledger_priv->ledger_items, l_item_tmp); // Remove it from cache char *l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_TXS_STR); char *l_tx_hash_str = dap_chain_hash_fast_to_str_new(a_tx_hash); @@ -2752,12 +2699,12 @@ int dap_chain_ledger_tx_remove(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_ 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); + HASH_FIND_BYHASHVALUE(hh, l_ledger_priv->spent_items, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_hash_value, 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); + HASH_ADD_BYHASHVALUE(hh, l_ledger_priv->spent_items, tx_hash_fast, sizeof(dap_chain_hash_fast_t), l_hash_value, l_item_used); // Add it to cache l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_SPENT_TXS_STR); @@ -2788,8 +2735,8 @@ void dap_chain_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db) dap_ledger_private_t *l_ledger_priv = PVT(a_ledger); pthread_rwlock_wrlock(&l_ledger_priv->ledger_rwlock); pthread_rwlock_wrlock(&l_ledger_priv->tokens_rwlock); - pthread_rwlock_wrlock(&l_ledger_priv->treshold_emissions_rwlock); - pthread_rwlock_wrlock(&l_ledger_priv->treshold_txs_rwlock); + pthread_rwlock_wrlock(&l_ledger_priv->threshold_emissions_rwlock); + pthread_rwlock_wrlock(&l_ledger_priv->threshold_txs_rwlock); pthread_rwlock_wrlock(&l_ledger_priv->balance_accounts_rwlock); // delete transactions @@ -2858,22 +2805,29 @@ void dap_chain_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db) // 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); + HASH_ITER(hh, l_ledger_priv->threshold_emissions, l_emission_current, l_emission_tmp) { + HASH_DEL(l_ledger_priv->threshold_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); + HASH_ITER(hh, l_ledger_priv->threshold_txs, l_item_current, l_item_tmp) { + HASH_DEL(l_ledger_priv->threshold_txs, l_item_current); DAP_DELETE(l_item_current->tx); DAP_DELETE(l_item_current); } + l_ledger_priv->ledger_items = NULL; + l_ledger_priv->spent_items = NULL; + l_ledger_priv->balance_accounts = NULL; + l_ledger_priv->tokens = NULL; + l_ledger_priv->threshold_emissions = NULL; + l_ledger_priv->threshold_txs = NULL; + pthread_rwlock_unlock(&l_ledger_priv->ledger_rwlock); pthread_rwlock_unlock(&l_ledger_priv->tokens_rwlock); - pthread_rwlock_unlock(&l_ledger_priv->treshold_emissions_rwlock); - pthread_rwlock_unlock(&l_ledger_priv->treshold_txs_rwlock); + pthread_rwlock_unlock(&l_ledger_priv->threshold_emissions_rwlock); + pthread_rwlock_unlock(&l_ledger_priv->threshold_txs_rwlock); pthread_rwlock_unlock(&l_ledger_priv->balance_accounts_rwlock); } diff --git a/modules/chain/include/dap_chain_ledger.h b/modules/chain/include/dap_chain_ledger.h index aedd68b4fc..5a02d2c3a4 100644 --- a/modules/chain/include/dap_chain_ledger.h +++ b/modules/chain/include/dap_chain_ledger.h @@ -129,7 +129,8 @@ dap_list_t *dap_chain_ledger_token_info(dap_ledger_t *a_ledger); /** * Add token emission datum */ -int dap_chain_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size); +int dap_chain_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size, + dap_hash_fast_t *a_emission_hash, bool a_from_threshold); int dap_chain_ledger_token_emission_load(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size); // Check if it addable @@ -197,7 +198,7 @@ uint256_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_c * return transaction, or NULL if transaction not found in the cache */ dap_chain_datum_tx_t* dap_chain_ledger_tx_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash); - +bool dap_chain_ledger_tx_spent_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash); // Get the transaction in the cache by the addr in out item dap_chain_datum_tx_t* dap_chain_ledger_tx_find_by_addr(dap_ledger_t *a_ledger, const char * a_token, diff --git a/modules/common/dap_chain_datum_token.c b/modules/common/dap_chain_datum_token.c index 1263cd4bac..349f1c6cd6 100644 --- a/modules/common/dap_chain_datum_token.c +++ b/modules/common/dap_chain_datum_token.c @@ -114,8 +114,7 @@ dap_chain_datum_token_t *dap_chain_datum_token_read(byte_t *a_token_serial, size uint16_t l_token_type = ((dap_chain_datum_token_t *)a_token_serial)->type; if ( dap_chain_datum_token_is_old(l_token_type) ) { - dap_chain_datum_token_old_t * l_token_old = DAP_NEW_Z_SIZE(dap_chain_datum_token_old_t, (*a_token_size)); - memcpy(l_token_old, a_token_serial, (*a_token_size)); + dap_chain_datum_token_old_t *l_token_old = (dap_chain_datum_token_old_t *)a_token_serial; size_t l_token_size = (*a_token_size) - sizeof(*l_token_old) + sizeof(dap_chain_datum_token_t); dap_chain_datum_token_t * l_token = DAP_NEW_Z_SIZE(dap_chain_datum_token_t, l_token_size); memcpy(l_token->ticker, l_token_old->ticker, sizeof(l_token_old->ticker)); @@ -148,15 +147,11 @@ dap_chain_datum_token_t *dap_chain_datum_token_read(byte_t *a_token_serial, size memcpy(&l_token->header_public.premine_address, &l_token_old->header_public.premine_address, sizeof(l_token_old->header_public.premine_address)); break; default: - DAP_DELETE(l_token_old); return NULL; } - DAP_DELETE(l_token_old); return l_token; } else { - dap_chain_datum_token_t * l_token = DAP_NEW_Z_SIZE(dap_chain_datum_token_t, (*a_token_size)); - memcpy(l_token, a_token_serial, (*a_token_size)); - return l_token; + return DAP_DUP_SIZE(a_token_serial, *a_token_size); } return NULL; } @@ -276,7 +271,6 @@ size_t dap_chain_datum_emission_get_size(uint8_t *a_emission_serial) l_ret = sizeof(l_emission->hdr); } switch (l_emission->hdr.type) { - // case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_256_AUTH: case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH: { uint16_t l_sign_count = *(uint16_t *)(a_emission_serial + l_ret); l_ret += sizeof(l_emission->data.type_auth); @@ -285,19 +279,15 @@ size_t dap_chain_datum_emission_get_size(uint8_t *a_emission_serial) l_ret += dap_sign_get_size(l_sign); } } break; - // case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_256_ALGO: case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_ALGO: l_ret += sizeof(l_emission->data.type_algo); break; - // case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_256_ATOM_OWNER: case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_ATOM_OWNER: l_ret += sizeof(l_emission->data.type_atom_owner); break; - // case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_256_SMART_CONTRACT: case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_SMART_CONTRACT: l_ret += sizeof(l_emission->data.type_presale); break; - // case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_256_UNDEFINED: case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_UNDEFINED: default: break; @@ -315,16 +305,20 @@ dap_chain_datum_token_emission_t *dap_chain_datum_emission_read(byte_t *a_emissi size_t l_old_hdr_size = sizeof(struct dap_chain_emission_header_v0); size_t l_add_size = sizeof(l_emission->hdr) - l_old_hdr_size; l_emission = DAP_NEW_Z_SIZE(dap_chain_datum_token_emission_t, l_emission_size + l_add_size); - l_emission->hdr.version = 1; - // l_emission->hdr.type_256 = false; + l_emission->hdr.version = 2; memcpy(l_emission, a_emission_serial, l_old_hdr_size); memcpy((byte_t *)l_emission + sizeof(l_emission->hdr), a_emission_serial + l_old_hdr_size, l_emission_size - l_old_hdr_size); + l_emission->hdr.value_256 = dap_chain_uint256_from( + ((dap_chain_datum_token_emission_t *)a_emission_serial)->hdr.value); l_emission_size += l_add_size; (*a_emission_size) = l_emission_size; } else { l_emission = DAP_DUP_SIZE(a_emission_serial, (*a_emission_size)); + if (((dap_chain_datum_token_emission_t *)a_emission_serial)->hdr.version == 1) + l_emission->hdr.value_256 = dap_chain_uint256_from( + ((dap_chain_datum_token_emission_t *)a_emission_serial)->hdr.value); } return l_emission; } diff --git a/modules/global-db/dap_chain_global_db.c b/modules/global-db/dap_chain_global_db.c index 1f630e4409..36ecf003b5 100644 --- a/modules/global-db/dap_chain_global_db.c +++ b/modules/global-db/dap_chain_global_db.c @@ -390,7 +390,7 @@ char l_group[DAP_DB_K_MAXGRPLEN]; int l_res = 0; if(!a_key) - return NULL; + return false; store_data.key = a_key; dap_snprintf(l_group, sizeof(l_group) - 1, "%s.del", a_group); diff --git a/modules/mempool/dap_chain_mempool.c b/modules/mempool/dap_chain_mempool.c index a4e0ce9e4d..052155dbf3 100644 --- a/modules/mempool/dap_chain_mempool.c +++ b/modules/mempool/dap_chain_mempool.c @@ -124,10 +124,10 @@ dap_hash_fast_t* dap_chain_mempool_tx_create(dap_chain_t * a_chain, dap_enc_key_ SUM_256_256(a_value, a_value_fee, &l_value_need); dap_list_t *l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(a_chain->ledger, a_token_ticker, a_addr_from, l_value_need, &l_value_transfer); - // if (!l_list_used_out) { - // log_it(L_WARNING,"Not enough funds to transfer"); - // return NULL; - // } + if (!l_list_used_out) { + log_it(L_WARNING,"Not enough funds to transfer"); + return NULL; + } // create empty transaction dap_chain_datum_tx_t *l_tx = dap_chain_datum_tx_create(); // add 'in' items diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c index 602e6e6812..09b121692f 100644 --- a/modules/net/dap_chain_net.c +++ b/modules/net/dap_chain_net.c @@ -2883,24 +2883,32 @@ dap_chain_datum_tx_t * dap_chain_net_get_tx_by_hash(dap_chain_net_t * a_net, dap switch (a_search_type) { case TX_SEARCH_TYPE_NET: case TX_SEARCH_TYPE_CELL: - case TX_SEARCH_TYPE_LOCAL:{ + case TX_SEARCH_TYPE_LOCAL: + case TX_SEARCH_TYPE_CELL_SPENT: + case TX_SEARCH_TYPE_NET_SPENT: { + if ( ! l_tx ){ // pass all chains 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); - if (l_tx) + if (l_tx) { + if ((a_search_type == TX_SEARCH_TYPE_CELL_SPENT || + a_search_type == TX_SEARCH_TYPE_NET_SPENT) && + (!dap_chain_ledger_tx_spent_find_by_hash(l_ledger, a_tx_hash))) + return NULL; break; + } } } } - }break; + } break; case TX_SEARCH_TYPE_NET_UNSPENT: - case TX_SEARCH_TYPE_CELL_UNSPENT:{ + case TX_SEARCH_TYPE_CELL_UNSPENT: l_tx = dap_chain_ledger_tx_find_by_hash(l_ledger, a_tx_hash); - }break; + break; } return l_tx; } diff --git a/modules/net/include/dap_chain_net.h b/modules/net/include/dap_chain_net.h index 8de81bd720..58e3c38064 100644 --- a/modules/net/include/dap_chain_net.h +++ b/modules/net/include/dap_chain_net.h @@ -145,7 +145,11 @@ typedef enum dap_chain_net_tx_search_type { /// Do the search in whole network and request tx from others cells if need TX_SEARCH_TYPE_NET, /// Do the search in whole network but search only unspent - TX_SEARCH_TYPE_NET_UNSPENT + TX_SEARCH_TYPE_NET_UNSPENT, + /// Do the request for spent txs in cell + TX_SEARCH_TYPE_CELL_SPENT, + /// Do the search in whole + TX_SEARCH_TYPE_NET_SPENT }dap_chain_net_tx_search_type_t; 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, -- GitLab