diff --git a/dap-sdk b/dap-sdk index 02a8df370be77507ea281fc19d8fcc49114e31f3..37c3f575570953da1cbf58d72402612cf3cfc0eb 160000 --- a/dap-sdk +++ b/dap-sdk @@ -1 +1 @@ -Subproject commit 02a8df370be77507ea281fc19d8fcc49114e31f3 +Subproject commit 37c3f575570953da1cbf58d72402612cf3cfc0eb diff --git a/modules/chain/dap_chain_ledger.c b/modules/chain/dap_chain_ledger.c index 61dcf4d4841f0a4c46fe07c8981ffd168607a965..b193c742b87b6d13b3ad8a8b2145828d87c12dfd 100644 --- a/modules/chain/dap_chain_ledger.c +++ b/modules/chain/dap_chain_ledger.c @@ -205,24 +205,14 @@ typedef struct dap_chain_ledger_tx_item { char token_ticker[DAP_CHAIN_TICKER_SIZE_MAX]; byte_t padding[6]; byte_t multichannel; - byte_t pad[15]; + dap_time_t ts_spent; + byte_t pad[7]; // 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 } DAP_ALIGN_PACKED 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; - struct { - dap_time_t spent_time; - char token_ticker[DAP_CHAIN_TICKER_SIZE_MAX]; - char padding[22]; - dap_chain_hash_fast_t tx_hash_spent_fast; // spent outs list - } DAP_ALIGN_PACKED cache_data; - UT_hash_handle hh; -} dap_chain_ledger_tx_spent_item_t; - typedef struct dap_chain_ledger_tokenizer { char token_ticker[DAP_CHAIN_TICKER_SIZE_MAX]; uint256_t sum; @@ -290,7 +280,6 @@ typedef struct dap_ledger_private { 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; dap_chain_ledger_token_item_t *tokens; dap_chain_ledger_stake_lock_item_t *emissions_for_stake_lock; dap_ledger_wallet_balance_t *balance_accounts; @@ -853,161 +842,167 @@ static void s_tx_header_print(dap_string_t *a_str_out, dap_chain_datum_tx_t *a_t DAP_DELETE(l_tx_hash_str); } -char * dap_ledger_token_tx_item_list(dap_ledger_t * a_ledger, dap_chain_addr_t *a_addr, const char *a_hash_out_type) -{ - dap_string_t *l_str_out =dap_string_new(NULL); - if (!l_str_out) { - log_it(L_CRITICAL, "Memory allocation error"); - return NULL; +static void s_dump_datum_tx_for_addr(dap_chain_ledger_tx_item_t *a_item, bool a_unspent, dap_ledger_t *a_ledger, dap_chain_addr_t *a_addr, const char *a_hash_out_type, dap_string_t *a_str_out) { + if (a_unspent && a_item->cache_data.ts_spent) { + // With 'unspent' flag spent ones are ignored + return; + } + dap_chain_datum_tx_t *l_tx = a_item->tx; + dap_chain_hash_fast_t *l_tx_hash = &a_item->tx_hash_fast; + dap_list_t *l_list_in_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_IN_ALL, NULL); + if (!l_list_in_items) { // a bad tx + return; + } + dap_chain_addr_t *l_src_addr = NULL; + bool l_base_tx = false; + const char *l_src_token = NULL; + int l_src_subtype = DAP_CHAIN_TX_OUT_COND_SUBTYPE_UNDEFINED; + dap_list_t *l_in_item; + DL_FOREACH(l_list_in_items, l_in_item) { + //assert(it->data); + dap_chain_hash_fast_t *l_tx_prev_hash; + int l_tx_prev_out_idx; + dap_chain_datum_tx_t *l_tx_prev = NULL; + if (*(byte_t*)l_in_item->data == TX_ITEM_TYPE_IN) { + dap_chain_tx_in_t *l_tx_in = (dap_chain_tx_in_t*)l_in_item->data; + l_tx_prev_hash = &l_tx_in->header.tx_prev_hash; + l_tx_prev_out_idx = l_tx_in->header.tx_out_prev_idx; + } else { // TX_ITEM_TYPE_IN_COND + dap_chain_tx_in_cond_t *l_tx_in_cond = (dap_chain_tx_in_cond_t*)l_in_item->data; + l_tx_prev_hash = &l_tx_in_cond->header.tx_prev_hash; + l_tx_prev_out_idx = l_tx_in_cond->header.tx_out_prev_idx; + } + if (dap_hash_fast_is_blank(l_tx_prev_hash)) { + l_base_tx = true; + dap_chain_tx_in_ems_t *l_token = (dap_chain_tx_in_ems_t *)dap_chain_datum_tx_item_get( + l_tx, NULL, TX_ITEM_TYPE_IN_EMS, NULL); + if (l_token) + l_src_token = l_token->header.ticker; + break; } - - //dap_chain_tx_hash_processed_ht_t *l_tx_data_ht = NULL; - dap_chain_ledger_tx_item_t *l_tx_item, *l_tx_tmp; - dap_ledger_private_t * l_ledger_pvt = PVT(a_ledger); - - pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock); - //unsigned test = dap_chain_ledger_count(a_ledger); - HASH_ITER(hh, l_ledger_pvt->ledger_items, l_tx_item, l_tx_tmp) { - - dap_chain_datum_tx_t *l_tx = l_tx_item->tx; - dap_chain_hash_fast_t *l_tx_hash = &l_tx_item->tx_hash_fast; - dap_list_t *l_list_in_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_IN_ALL, NULL); - if (!l_list_in_items) { // a bad tx + l_tx_prev = dap_chain_ledger_tx_find_by_hash (a_ledger,l_tx_prev_hash); + if (l_tx_prev) { + uint8_t *l_prev_out_union = dap_chain_datum_tx_item_get_nth(l_tx_prev, TX_ITEM_TYPE_OUT_ALL, l_tx_prev_out_idx); + if (!l_prev_out_union) continue; + switch (*l_prev_out_union) { + case TX_ITEM_TYPE_OUT: + l_src_addr = &((dap_chain_tx_out_t *)l_prev_out_union)->addr; + break; + case TX_ITEM_TYPE_OUT_EXT: + l_src_addr = &((dap_chain_tx_out_ext_t *)l_prev_out_union)->addr; + l_src_token = (const char *)(((dap_chain_tx_out_ext_t *)l_prev_out_union)->token); + break; + case TX_ITEM_TYPE_OUT_COND: + l_src_subtype = ((dap_chain_tx_out_cond_t *)l_prev_out_union)->header.subtype; + default: + break; } - dap_chain_addr_t *l_src_addr = NULL; - bool l_base_tx = false; - const char *l_src_token = NULL; - int l_src_subtype = DAP_CHAIN_TX_OUT_COND_SUBTYPE_UNDEFINED; - dap_list_t *l_in_item; - DL_FOREACH(l_list_in_items, l_in_item) { - //assert(it->data); - dap_chain_hash_fast_t *l_tx_prev_hash; - int l_tx_prev_out_idx; - dap_chain_datum_tx_t *l_tx_prev = NULL; - if (*(byte_t*)l_in_item->data == TX_ITEM_TYPE_IN) { - dap_chain_tx_in_t *l_tx_in = (dap_chain_tx_in_t*)l_in_item->data; - l_tx_prev_hash = &l_tx_in->header.tx_prev_hash; - l_tx_prev_out_idx = l_tx_in->header.tx_out_prev_idx; - } else { // TX_ITEM_TYPE_IN_COND - dap_chain_tx_in_cond_t *l_tx_in_cond = (dap_chain_tx_in_cond_t*)l_in_item->data; - l_tx_prev_hash = &l_tx_in_cond->header.tx_prev_hash; - l_tx_prev_out_idx = l_tx_in_cond->header.tx_out_prev_idx; - } - if (dap_hash_fast_is_blank(l_tx_prev_hash)) { - l_base_tx = true; - dap_chain_tx_in_ems_t *l_token = (dap_chain_tx_in_ems_t *)dap_chain_datum_tx_item_get( - l_tx, NULL, TX_ITEM_TYPE_IN_EMS, NULL); - if (l_token) - l_src_token = l_token->header.ticker; - break; - } - l_tx_prev = dap_chain_ledger_tx_find_by_hash (a_ledger,l_tx_prev_hash); - if (l_tx_prev) { - uint8_t *l_prev_out_union = dap_chain_datum_tx_item_get_nth(l_tx_prev, TX_ITEM_TYPE_OUT_ALL, l_tx_prev_out_idx); - if (!l_prev_out_union) - continue; - switch (*l_prev_out_union) { - case TX_ITEM_TYPE_OUT: - l_src_addr = &((dap_chain_tx_out_t *)l_prev_out_union)->addr; - break; - case TX_ITEM_TYPE_OUT_EXT: - l_src_addr = &((dap_chain_tx_out_ext_t *)l_prev_out_union)->addr; - l_src_token = (const char *)(((dap_chain_tx_out_ext_t *)l_prev_out_union)->token); - break; - case TX_ITEM_TYPE_OUT_COND: - l_src_subtype = ((dap_chain_tx_out_cond_t *)l_prev_out_union)->header.subtype; - default: - break; - } - } - else - { - continue; //temporary stub - } - if (!l_src_token){ - l_src_token = dap_chain_ledger_tx_get_token_ticker_by_hash(a_ledger, l_tx_prev_hash); - l_src_token = l_tx_item->cache_data.token_ticker; - } - if (l_src_addr && memcmp(l_src_addr, a_addr, sizeof(dap_chain_addr_t))) - break; //it's not our addr - } - dap_list_free(l_list_in_items); + } + else + { + continue; //temporary stub + } + if (!l_src_token){ + l_src_token = a_item->cache_data.token_ticker; + } + if (l_src_addr && memcmp(l_src_addr, a_addr, sizeof(dap_chain_addr_t))) + break; //it's not our addr + } + dap_list_free(l_list_in_items); - bool l_header_printed = false; - dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_ALL, NULL); - if(!l_list_out_items) - continue; - for(dap_list_t *l_list_out = l_list_out_items; l_list_out; l_list_out = dap_list_next(l_list_out)) { - assert(l_list_out->data); - dap_chain_addr_t *l_dst_addr = NULL; - dap_chain_tx_item_type_t l_type = *(uint8_t *)l_list_out->data; - uint256_t l_value; - switch (l_type) { - case TX_ITEM_TYPE_OUT: - l_dst_addr = &((dap_chain_tx_out_t *)l_list_out->data)->addr; - l_value = ((dap_chain_tx_out_t *)l_list_out->data)->header.value; - break; - case TX_ITEM_TYPE_OUT_EXT: - l_dst_addr = &((dap_chain_tx_out_ext_t *)l_list_out->data)->addr; - l_value = ((dap_chain_tx_out_ext_t *)l_list_out->data)->header.value; - break; - case TX_ITEM_TYPE_OUT_COND: - l_value = ((dap_chain_tx_out_cond_t *)l_list_out->data)->header.value; - default: - break; - } - if (l_src_addr && l_dst_addr && !memcmp(l_dst_addr, l_src_addr, sizeof(dap_chain_addr_t))) - continue; // send to self - if (l_src_addr && !memcmp(l_src_addr, a_addr, sizeof(dap_chain_addr_t))) { - if (!l_header_printed) { - s_tx_header_print(l_str_out, l_tx, a_hash_out_type, l_tx_hash); - l_header_printed = true; - } - //const char *l_token_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, &l_tx_hash); - const char *l_dst_addr_str = l_dst_addr ? dap_chain_addr_to_str(l_dst_addr) - : dap_chain_tx_out_cond_subtype_to_str( - ((dap_chain_tx_out_cond_t *)l_list_out->data)->header.subtype); - char *l_value_str = dap_chain_balance_print(l_value); - dap_string_append_printf(l_str_out, "\tsend %s %s to %s\n", - l_value_str, - l_src_token ? l_src_token : "UNKNOWN", - l_dst_addr_str); - if (l_dst_addr) - DAP_DELETE(l_dst_addr_str); - DAP_DELETE(l_value_str); - } - if (l_dst_addr && !memcmp(l_dst_addr, a_addr, sizeof(dap_chain_addr_t))) { - if (!l_header_printed) { - s_tx_header_print(l_str_out, l_tx, a_hash_out_type, l_tx_hash); - l_header_printed = true; - } - const char *l_dst_token = (l_type == TX_ITEM_TYPE_OUT_EXT) ? - (const char *)(((dap_chain_tx_out_ext_t *)l_list_out->data)->token) : NULL; - const char *l_src_addr_str = l_base_tx ? "emission" - : (l_src_addr ? dap_chain_addr_to_str(l_src_addr) - : dap_chain_tx_out_cond_subtype_to_str( - l_src_subtype)); - char *l_value_str = dap_chain_balance_print(l_value); - dap_string_append_printf(l_str_out, "\trecv %s %s from %s\n", - l_value_str, - l_dst_token ? l_dst_token : - (l_src_token ? l_src_token : "UNKNOWN"), - l_src_addr_str); - if (l_src_addr) - DAP_DELETE(l_src_addr_str); - DAP_DELETE(l_value_str); - } - } - dap_list_free(l_list_out_items); + bool l_header_printed = false; + dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_ALL, NULL); + if(!l_list_out_items) + return; + for(dap_list_t *l_list_out = l_list_out_items; l_list_out; l_list_out = dap_list_next(l_list_out)) { + assert(l_list_out->data); + dap_chain_addr_t *l_dst_addr = NULL; + dap_chain_tx_item_type_t l_type = *(uint8_t *)l_list_out->data; + uint256_t l_value; + switch (l_type) { + case TX_ITEM_TYPE_OUT: + l_dst_addr = &((dap_chain_tx_out_t *)l_list_out->data)->addr; + l_value = ((dap_chain_tx_out_t *)l_list_out->data)->header.value; + break; + case TX_ITEM_TYPE_OUT_EXT: + l_dst_addr = &((dap_chain_tx_out_ext_t *)l_list_out->data)->addr; + l_value = ((dap_chain_tx_out_ext_t *)l_list_out->data)->header.value; + break; + case TX_ITEM_TYPE_OUT_COND: + l_value = ((dap_chain_tx_out_cond_t *)l_list_out->data)->header.value; + default: + break; } - pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock); + if (l_src_addr && l_dst_addr && !memcmp(l_dst_addr, l_src_addr, sizeof(dap_chain_addr_t))) + continue; // send to self + if (l_src_addr && !memcmp(l_src_addr, a_addr, sizeof(dap_chain_addr_t))) { + if (!l_header_printed) { + s_tx_header_print(a_str_out, l_tx, a_hash_out_type, l_tx_hash); + l_header_printed = true; + } + //const char *l_token_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, &l_tx_hash); + const char *l_dst_addr_str = l_dst_addr ? dap_chain_addr_to_str(l_dst_addr) + : dap_chain_tx_out_cond_subtype_to_str( + ((dap_chain_tx_out_cond_t *)l_list_out->data)->header.subtype); + char *l_value_str = dap_chain_balance_print(l_value); + dap_string_append_printf(a_str_out, "\tsend %s %s to %s\n", + l_value_str, + l_src_token ? l_src_token : "UNKNOWN", + l_dst_addr_str); + if (l_dst_addr) + DAP_DELETE(l_dst_addr_str); + DAP_DELETE(l_value_str); + } + if (l_dst_addr && !memcmp(l_dst_addr, a_addr, sizeof(dap_chain_addr_t))) { + if (!l_header_printed) { + s_tx_header_print(a_str_out, l_tx, a_hash_out_type, l_tx_hash); + l_header_printed = true; + } + const char *l_dst_token = (l_type == TX_ITEM_TYPE_OUT_EXT) ? + (const char *)(((dap_chain_tx_out_ext_t *)l_list_out->data)->token) : NULL; + const char *l_src_addr_str = l_base_tx ? "emission" + : (l_src_addr ? dap_chain_addr_to_str(l_src_addr) + : dap_chain_tx_out_cond_subtype_to_str( + l_src_subtype)); + char *l_value_str = dap_chain_balance_print(l_value); + dap_string_append_printf(a_str_out, "\trecv %s %s from %s\n", + l_value_str, + l_dst_token ? l_dst_token : + (l_src_token ? l_src_token : "UNKNOWN"), + l_src_addr_str); + if (l_src_addr) + DAP_DELETE(l_src_addr_str); + DAP_DELETE(l_value_str); + } + } + dap_list_free(l_list_out_items); +} + +char *dap_ledger_token_tx_item_list(dap_ledger_t * a_ledger, dap_chain_addr_t *a_addr, const char *a_hash_out_type, bool a_unspent_only) +{ + dap_string_t *l_str_out = dap_string_new(NULL); + if (!l_str_out) { + log_it(L_CRITICAL, "Memory allocation error"); + return NULL; + } - // if no history - if(!l_str_out->len) - dap_string_append(l_str_out, "\tempty"); - char *l_ret_str = l_str_out ? dap_string_free(l_str_out, false) : NULL; - return l_ret_str; + //dap_chain_tx_hash_processed_ht_t *l_tx_data_ht = NULL; + dap_chain_ledger_tx_item_t *l_tx_item, *l_tx_tmp; + dap_ledger_private_t * l_ledger_pvt = PVT(a_ledger); + + pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock); + //unsigned test = dap_chain_ledger_count(a_ledger); + HASH_ITER(hh, l_ledger_pvt->ledger_items, l_tx_item, l_tx_tmp) { + s_dump_datum_tx_for_addr(l_tx_item, a_unspent_only, a_ledger, a_addr, a_hash_out_type, l_str_out); + } + pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock); + + // if no history + if(!l_str_out->len) + dap_string_append(l_str_out, "\tempty"); + char *l_ret_str = l_str_out ? dap_string_free(l_str_out, false) : NULL; + return l_ret_str; } /** @@ -1104,26 +1099,7 @@ int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t * return -1; } - dap_chain_datum_token_t *l_token = NULL; - size_t l_token_size = a_token_size; - - switch (a_token->type) { - case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_SIMPLE: - case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_DECL: - case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_UPDATE: - case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_NATIVE_DECL: - case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_NATIVE_UPDATE: - case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PUBLIC: - l_token = dap_chain_datum_token_read((byte_t *) a_token, &l_token_size); - break; - default: - l_token = DAP_DUP_SIZE(a_token, a_token_size); - if ( !l_token ) { - log_it(L_CRITICAL, "Memory allocation error"); - return -6; - } - break; - } + dap_chain_datum_token_t *l_token = a_token; dap_chain_ledger_token_item_t *l_token_item; pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock); @@ -1131,15 +1107,17 @@ int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t * pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock); if (l_token_item) { - if (l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE) { + if (l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE + && l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_UPDATE + && l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_NATIVE_UPDATE) { log_it(L_ERROR, "Duplicate token declaration for ticker '%s'", l_token->ticker); - DAP_DEL_Z(l_token); + DAP_DELETE(l_token); return -3; } - if (s_ledger_token_update_check(l_token_item, l_token, l_token_size)) { - if (!s_ledger_update_token_add_in_hash_table(l_token_item, l_token, l_token_size)) { + if (s_ledger_token_update_check(l_token_item, l_token, a_token_size)) { + if (!s_ledger_update_token_add_in_hash_table(l_token_item, l_token, a_token_size)) { log_it(L_ERROR, "Failed to update token with ticker '%s' in ledger", l_token->ticker); - DAP_DEL_Z(l_token); + DAP_DELETE(l_token); return -5; } if (!IS_ZERO_256(l_token->total_supply)) { @@ -1163,7 +1141,7 @@ int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t * if (!l_token_item) { size_t l_auth_signs_total, l_auth_signs_valid; - dap_sign_t **l_signs = dap_chain_datum_token_signs_parse(l_token, l_token_size, &l_auth_signs_total, &l_auth_signs_valid); + dap_sign_t **l_signs = dap_chain_datum_token_signs_parse(l_token, a_token_size, &l_auth_signs_total, &l_auth_signs_valid); if (!l_signs || !l_auth_signs_total) { log_it(L_ERROR, "No auth signs in token '%s' datum!", l_token->ticker); DAP_DEL_Z(l_token); @@ -1212,11 +1190,13 @@ int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t * } - l_token_item->datum_token_size = l_token_size; + l_token_item->datum_token_size = a_token_size; l_token_item->datum_token = l_token; l_token_item->datum_token->type = l_token->type; - if (l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE) { + if(l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE + && l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_UPDATE + && l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_NATIVE_UPDATE) { pthread_rwlock_wrlock(&PVT(a_ledger)->tokens_rwlock); HASH_ADD_STR(PVT(a_ledger)->tokens, ticker, l_token_item); pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock); @@ -1243,15 +1223,15 @@ int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t * debug_if(s_debug_more, L_INFO, "Private token %s declared, total_supply: %s, total_signs_valid: %hu, signs_total: %hu", l_token->ticker, l_balance_dbg, l_token->signs_valid, l_token->signs_total); - l_res_token_tsd_parse = s_token_tsd_parse(a_ledger, l_token_item, l_token, l_token_size); - s_tsd_sign_apply(a_ledger, l_token_item, l_token, l_token_size); + l_res_token_tsd_parse = s_token_tsd_parse(a_ledger, l_token_item, l_token, a_token_size); + s_tsd_sign_apply(a_ledger, l_token_item, l_token, a_token_size); break; case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: debug_if(s_debug_more, L_INFO, "CF20 token %s declared, total_supply: %s, total_signs_valid: %hu, signs_total: %hu", l_token->ticker, l_balance_dbg, l_token->signs_valid, l_token->signs_total); - l_res_token_tsd_parse = s_token_tsd_parse(a_ledger, l_token_item, l_token, l_token_size); - s_tsd_sign_apply(a_ledger, l_token_item, l_token, l_token_size); + l_res_token_tsd_parse = s_token_tsd_parse(a_ledger, l_token_item, l_token, a_token_size); + s_tsd_sign_apply(a_ledger, l_token_item, l_token, a_token_size); break; default: /* Bogdanoff, unknown token subtype declaration. What shall we TODO? */ @@ -1274,15 +1254,15 @@ int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t * debug_if(s_debug_more, L_INFO, "Private token %s updated, total_supply: %s, total_signs_valid: %hu, signs_total: %hu", l_token->ticker, l_balance_dbg, l_token->signs_valid, l_token->signs_total); - l_res_token_tsd_parse = s_token_tsd_parse(a_ledger, l_token_item, l_token, l_token_size); - s_tsd_sign_apply(a_ledger, l_token_item, l_token, l_token_size); + l_res_token_tsd_parse = s_token_tsd_parse(a_ledger, l_token_item, l_token, a_token_size); + s_tsd_sign_apply(a_ledger, l_token_item, l_token, a_token_size); break; case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: debug_if(s_debug_more, L_INFO, "CF20 token %s updated, total_supply: %s, total_signs_valid: %hu, signs_total: %hu", l_token->ticker, l_balance_dbg, l_token->signs_valid, l_token->signs_total); - l_res_token_tsd_parse = s_token_tsd_parse(a_ledger, l_token_item, l_token, l_token_size); - s_tsd_sign_apply(a_ledger, l_token_item, l_token, l_token_size); + l_res_token_tsd_parse = s_token_tsd_parse(a_ledger, l_token_item, l_token, a_token_size); + s_tsd_sign_apply(a_ledger, l_token_item, l_token, a_token_size); break; default: /* Bogdanoff, unknown token type update. What shall we TODO? */ @@ -1380,11 +1360,8 @@ static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_ite // Check if its correct dap_chain_addr_t * l_add_addr = (dap_chain_addr_t *) l_tsd->data; - int l_add_addr_check; - if ( (l_add_addr_check=dap_chain_addr_check_sum(l_add_addr))!=1){ - if(s_debug_more) - log_it(L_ERROR,"Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_ADD (code %d)", - l_add_addr_check); + if (dap_chain_addr_check_sum(l_add_addr)) { + debug_if(s_debug_more, L_ERROR, "Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_ADD"); return -12; } // Check if its already present @@ -1422,11 +1399,8 @@ static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_ite if( l_tsd->size == sizeof (dap_chain_addr_t) ){ // Check if its correct dap_chain_addr_t * l_add_addr = (dap_chain_addr_t *) l_tsd->data; - int l_add_addr_check; - if ( (l_add_addr_check=dap_chain_addr_check_sum(l_add_addr))!=0){ - if(s_debug_more) - log_it(L_ERROR,"Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_REMOVE (code %d)", - l_add_addr_check); + if (dap_chain_addr_check_sum(l_add_addr)) { + debug_if(s_debug_more, L_ERROR, "Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_REMOVE"); return -12; } bool l_was_found=false; @@ -1473,12 +1447,8 @@ static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_ite (a_token_item->tx_recv_block_size + 1) * sizeof(*a_token_item->tx_recv_block)); // Check if its correct dap_chain_addr_t * l_add_addr = (dap_chain_addr_t *) l_tsd->data; - int l_add_addr_check; - if ((l_add_addr_check=dap_chain_addr_check_sum(l_add_addr)) != 1) { - if(s_debug_more) - log_it(L_ERROR,"Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_ADD (code %d)", - l_add_addr_check); - DAP_DELETE(l_addrs); + if (dap_chain_addr_check_sum(l_add_addr)) { + debug_if(s_debug_more, L_ERROR, "Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_ADD"); return -12; } // Check if its already present @@ -1516,11 +1486,8 @@ static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_ite if( l_tsd->size == sizeof (dap_chain_addr_t) ){ // Check if its correct dap_chain_addr_t * l_add_addr = (dap_chain_addr_t *) l_tsd->data; - int l_add_addr_check; - if ( (l_add_addr_check=dap_chain_addr_check_sum(l_add_addr))!=0){ - if(s_debug_more) - log_it(L_ERROR,"Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_REMOVE (code %d)", - l_add_addr_check); + if (dap_chain_addr_check_sum(l_add_addr)) { + debug_if(s_debug_more, L_ERROR, "Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_REMOVE"); return -12; } bool l_was_found=false; @@ -1565,12 +1532,8 @@ static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_ite : DAP_REALLOC(a_token_item->tx_send_allow,(a_token_item->tx_send_allow_size+1)*sizeof (*a_token_item->tx_send_allow) ); // Check if its correct dap_chain_addr_t * l_add_addr = (dap_chain_addr_t *) l_tsd->data; - int l_add_addr_check; - if ( (l_add_addr_check=dap_chain_addr_check_sum(l_add_addr)) != 1){ - if(s_debug_more) - log_it(L_ERROR,"Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD (code %d)", - l_add_addr_check); - DAP_DELETE(l_addrs); + if (dap_chain_addr_check_sum(l_add_addr)) { + debug_if(s_debug_more, L_ERROR, "Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD"); return -12; } // Check if its already present @@ -1604,11 +1567,8 @@ static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_ite if( l_tsd->size == sizeof (dap_chain_addr_t) ){ // Check if its correct dap_chain_addr_t * l_add_addr = (dap_chain_addr_t *) l_tsd->data; - int l_add_addr_check; - if ( (l_add_addr_check=dap_chain_addr_check_sum(l_add_addr))!=0){ - if(s_debug_more) - log_it(L_ERROR,"Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_REMOVE (code %d)", - l_add_addr_check); + if (dap_chain_addr_check_sum(l_add_addr)) { + debug_if(s_debug_more, L_ERROR, "Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_REMOVE"); return -12; } bool l_was_found=false; @@ -1649,18 +1609,13 @@ static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_ite //Blocked tx sender addres list add, remove or clear case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_ADD:{ if( l_tsd->size == sizeof (dap_chain_addr_t) ){ - dap_chain_addr_t * l_addrs = a_token_item->tx_send_block ? DAP_NEW_Z_SIZE( dap_chain_addr_t, - sizeof(*a_token_item->tx_send_block) ) - : DAP_REALLOC(a_token_item->tx_send_block,(a_token_item->tx_send_block_size+1)*sizeof (*a_token_item->tx_send_block) ); + dap_chain_addr_t *l_addrs = a_token_item->tx_send_block + ? DAP_NEW_Z_SIZE(dap_chain_addr_t, sizeof(*a_token_item->tx_send_block)) + : DAP_REALLOC(a_token_item->tx_send_block, (a_token_item->tx_send_block_size + 1) * sizeof(*a_token_item->tx_send_block)); // Check if its correct dap_chain_addr_t * l_add_addr = (dap_chain_addr_t *) l_tsd->data; - int l_add_addr_check; - if ((l_add_addr_check=dap_chain_addr_check_sum(l_add_addr)) != 1) { - if(s_debug_more) - log_it(L_ERROR,"Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD (code %d)", - l_add_addr_check); - if (l_addrs) - DAP_DELETE(l_addrs); + if (dap_chain_addr_check_sum(l_add_addr)) { + debug_if(s_debug_more, L_ERROR, "Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_ADD"); return -12; } // Check if its already present @@ -1695,11 +1650,8 @@ static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_ite if( l_tsd->size == sizeof (dap_chain_addr_t) ){ // Check if its correct dap_chain_addr_t * l_add_addr = (dap_chain_addr_t *) l_tsd->data; - int l_add_addr_check; - if ( (l_add_addr_check=dap_chain_addr_check_sum(l_add_addr))!=0){ - if(s_debug_more) - log_it(L_ERROR,"Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_REMOVE (code %d)", - l_add_addr_check); + if (dap_chain_addr_check_sum(l_add_addr)) { + debug_if(s_debug_more, L_ERROR, "Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_REMOVE"); return -12; } bool l_was_found=false; @@ -1815,17 +1767,24 @@ static int s_tsd_sign_apply(dap_ledger_t *a_ledger, dap_chain_ledger_token_item_ return 0; } -int dap_chain_ledger_token_load(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token, size_t a_token_size) +int dap_chain_ledger_token_load(dap_ledger_t *a_ledger, byte_t *a_token, size_t a_token_size) { + dap_chain_datum_token_t *l_token = dap_chain_datum_token_read(a_token, &a_token_size); + if (PVT(a_ledger)->load_mode) { dap_chain_ledger_token_item_t *l_token_item; pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock); - HASH_FIND_STR(PVT(a_ledger)->tokens, a_token->ticker, l_token_item); + HASH_FIND_STR(PVT(a_ledger)->tokens, l_token->ticker, l_token_item); pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock); - if (l_token_item && a_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE) + if (l_token_item + && l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE + && l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_NATIVE_UPDATE + && l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_UPDATE) { + DAP_DELETE(l_token); return 0; + } } - return dap_chain_ledger_token_add(a_ledger, a_token, a_token_size); + return dap_chain_ledger_token_add(a_ledger, l_token, a_token_size); } dap_string_t *dap_chain_ledger_threshold_info(dap_ledger_t *a_ledger) @@ -1883,7 +1842,7 @@ dap_string_t *dap_chain_ledger_threshold_hash_info(dap_ledger_t *a_ledger, dap_c dap_string_t *l_str_ret = dap_string_new(""); pthread_rwlock_rdlock(&l_ledger_pvt->threshold_txs_rwlock); HASH_ITER(hh, l_ledger_pvt->threshold_txs, l_tx_item, l_tx_tmp){ - if (!memcmp(l_threshold_hash,&l_tx_item->tx_hash_fast, sizeof(dap_chain_hash_fast_t))){ + if (!memcmp(l_threshold_hash, &l_tx_item->tx_hash_fast, sizeof(dap_chain_hash_fast_t))){ char l_tx_hash_str[70]={0}; dap_chain_hash_fast_to_str(l_threshold_hash,l_tx_hash_str,sizeof(l_tx_hash_str)); dap_string_append(l_str_ret, "Hash was found in ledger tx threshold:"); @@ -2271,43 +2230,6 @@ static bool s_load_cache_gdb_loaded_balances_callback(dap_global_db_instance_t * return true; } -/** - * @brief s_load_cache_gdb_loaded_spent_txs_callback - * @param a_global_db_context - * @param a_rc - * @param a_group - * @param a_key - * @param a_values_total - * @param a_values_shift - * @param a_values_count - * @param a_values - * @param a_arg - */ -static bool s_load_cache_gdb_loaded_spent_txs_callback(dap_global_db_instance_t *a_dbi, - int a_rc, const char *a_group, - const size_t a_values_total, const size_t a_values_count, - dap_global_db_obj_t *a_values, void *a_arg) -{ - dap_ledger_t * l_ledger = (dap_ledger_t*) a_arg; - dap_ledger_private_t * l_ledger_pvt = PVT(l_ledger); - - for (size_t i = 0; i < a_values_count; i++) { - dap_chain_ledger_tx_spent_item_t *l_tx_spent_item = DAP_NEW_Z(dap_chain_ledger_tx_spent_item_t); - if ( !l_tx_spent_item ) { - log_it(L_CRITICAL, "Memory allocation error"); - return false; - } - dap_chain_hash_fast_from_str(a_values[i].key, &l_tx_spent_item->tx_hash_fast); - l_tx_spent_item->cache_data = *(typeof(l_tx_spent_item->cache_data)*)a_values[i].value; - HASH_ADD(hh, l_ledger_pvt->spent_items, tx_hash_fast, sizeof(dap_chain_hash_fast_t), l_tx_spent_item); - } - - char *l_gdb_group = dap_chain_ledger_get_gdb_group(l_ledger, DAP_CHAIN_LEDGER_BALANCES_STR); - dap_global_db_get_all(l_gdb_group, 0, s_load_cache_gdb_loaded_balances_callback, l_ledger); - DAP_DELETE(l_gdb_group); - return true; -} - /** * @brief s_load_cache_gdb_loaded_txs_callback * @param a_global_db_context @@ -2345,10 +2267,6 @@ static bool s_load_cache_gdb_loaded_txs_callback(dap_global_db_instance_t *a_dbi l_tx_item->ts_added = dap_nanotime_now(); HASH_ADD_INORDER(hh, l_ledger_pvt->ledger_items, tx_hash_fast, sizeof(dap_chain_hash_fast_t), l_tx_item, s_sort_ledger_tx_item); } - - char *l_gdb_group = dap_chain_ledger_get_gdb_group(l_ledger, DAP_CHAIN_LEDGER_SPENT_TXS_STR); - dap_global_db_get_all(l_gdb_group, 0, s_load_cache_gdb_loaded_spent_txs_callback, l_ledger); - DAP_DELETE(l_gdb_group); return true; } @@ -2469,6 +2387,7 @@ static bool s_load_cache_gdb_loaded_tokens_callback(dap_global_db_instance_t *a_ log_it(L_WARNING, "Corrupted token with ticker [%s], need to 'ledger reload' to update cache", a_values[i].key); continue; } + // TODO: rework! Old token types may be passed unchecked! dap_chain_ledger_token_add(l_ledger, l_token, l_token_size); dap_chain_ledger_token_item_t *l_token_item = NULL; HASH_FIND_STR(l_ledger_pvt->tokens, l_token->ticker, l_token_item); @@ -3162,15 +3081,8 @@ const char* dap_chain_ledger_tx_get_token_ticker_by_hash(dap_ledger_t *a_ledger, HASH_VALUE(a_tx_hash, sizeof(*a_tx_hash), l_hash_value); pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock); HASH_FIND_BYHASHVALUE(hh, l_ledger_pvt->ledger_items, a_tx_hash, sizeof(*a_tx_hash), l_hash_value, l_item); - if (l_item) { - pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock); - return l_item->cache_data.token_ticker; - } - dap_chain_ledger_tx_spent_item_t *l_spent_item; - HASH_FIND_BYHASHVALUE(hh, l_ledger_pvt->spent_items, a_tx_hash, sizeof(*a_tx_hash), l_hash_value, l_spent_item); pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock); - return l_spent_item ? l_spent_item->cache_data.token_ticker : NULL; - + return l_item ? l_item->cache_data.token_ticker : NULL; } /** @@ -3300,7 +3212,7 @@ void dap_chain_ledger_addr_get_token_ticker_all(dap_ledger_t *a_ledger, dap_chai * return transaction, or NULL if transaction not found in the cache */ static dap_chain_datum_tx_t* s_find_datum_tx_by_hash(dap_ledger_t *a_ledger, - dap_chain_hash_fast_t *a_tx_hash, dap_chain_ledger_tx_item_t **a_item_out) + dap_chain_hash_fast_t *a_tx_hash, dap_chain_ledger_tx_item_t **a_item_out, bool a_unspent_only) { if(!a_tx_hash) return NULL; @@ -3314,9 +3226,11 @@ static dap_chain_datum_tx_t* s_find_datum_tx_by_hash(dap_ledger_t *a_ledger, HASH_FIND(hh, l_ledger_pvt->ledger_items, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_tx_item); pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock); if(l_tx_item) { - l_tx_ret = l_tx_item->tx; - if(a_item_out) - *a_item_out = l_tx_item; + if (!a_unspent_only || !l_tx_item->cache_data.ts_spent) { + l_tx_ret = l_tx_item->tx; + if(a_item_out) + *a_item_out = l_tx_item; + } } return l_tx_ret; } @@ -3327,18 +3241,14 @@ static dap_chain_datum_tx_t* s_find_datum_tx_by_hash(dap_ledger_t *a_ledger, * @return */ -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) +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) { - return s_find_datum_tx_by_hash(a_ledger, a_tx_hash, NULL); + return s_find_datum_tx_by_hash(a_ledger, a_tx_hash, NULL, true); } -void *dap_chain_ledger_tx_spent_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash) +dap_chain_datum_tx_t *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; + return s_find_datum_tx_by_hash(a_ledger, a_tx_hash, NULL, false); } dap_hash_fast_t *dap_chain_ledger_get_final_chain_tx_hash(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_cond_type, dap_chain_hash_fast_t *a_tx_hash) @@ -3353,28 +3263,17 @@ dap_hash_fast_t *dap_chain_ledger_get_final_chain_tx_hash(dap_ledger_t *a_ledger while (l_tx_hash) { HASH_VALUE(l_tx_hash, sizeof(*l_tx_hash), l_hash_value); HASH_FIND_BYHASHVALUE(hh, l_ledger_pvt->ledger_items, l_tx_hash, sizeof(*l_tx_hash), l_hash_value, l_item); - if (l_item) { - int l_out_num = 0; - dap_chain_datum_tx_out_cond_get(l_item->tx, a_cond_type, &l_out_num); - if (l_out_num != -1 && l_out_num < MAX_OUT_ITEMS) { - if (dap_hash_fast_is_blank(&l_item->cache_data.tx_hash_spent_fast[l_out_num])) - break; // We have unused conditional output - else { - l_tx_hash = &l_item->cache_data.tx_hash_spent_fast[l_out_num]; - continue; // Conditional output is used out - } - } else { // No conditional output found - l_tx_hash = NULL; - break; - } + if (!l_item) { + l_tx_hash = NULL; + break; // Not found in ledger + } + int l_out_num = 0; + if (dap_hash_fast_is_blank(&l_item->cache_data.tx_hash_spent_fast[l_out_num]) || !dap_chain_datum_tx_out_cond_get(l_item->tx, a_cond_type, &l_out_num)) + break; // Unused conditional output found, that's what we need + else { + l_tx_hash = &l_item->cache_data.tx_hash_spent_fast[l_out_num]; + continue; // Conditional output is used out } - dap_chain_ledger_tx_spent_item_t *l_spent_item; - HASH_FIND_BYHASHVALUE(hh, l_ledger_pvt->spent_items, l_tx_hash, sizeof(*l_tx_hash), l_hash_value, l_spent_item); - if (l_spent_item && // We have condional output with spent item - !dap_hash_fast_is_blank(&l_spent_item->cache_data.tx_hash_spent_fast)) { - l_tx_hash = &l_spent_item->cache_data.tx_hash_spent_fast; - } else - l_tx_hash = NULL; // We can't find pointed hash in the ledger or it's a not conditional tx } pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock); return l_tx_hash; @@ -3783,16 +3682,20 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t break; } if (!EQUAL_256(l_value_expected, l_stake_lock_ems_value)) { - char *l_value_expected_str = dap_chain_balance_print(l_value_expected); - char *l_locked_value_str = dap_chain_balance_print(l_stake_lock_ems_value); - - debug_if(s_debug_more, L_WARNING, "Value %s != %s expected for [%s]",l_locked_value_str, l_value_expected_str, - l_tx_in_ems->header.ticker); - - DAP_DEL_Z(l_value_expected_str); - DAP_DEL_Z(l_locked_value_str); - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_UNEXPECTED_VALUE; - break; + // !!! A terrible legacy crutch, TODO !!! + SUM_256_256(l_value_expected, GET_256_FROM_64(10), &l_value_expected); + if (!EQUAL_256(l_value_expected, l_stake_lock_ems_value)) { + char *l_value_expected_str = dap_chain_balance_print(l_value_expected); + char *l_locked_value_str = dap_chain_balance_print(l_stake_lock_ems_value); + + debug_if(s_debug_more, L_WARNING, "Value %s != %s expected for [%s]",l_locked_value_str, l_value_expected_str, + l_tx_in_ems->header.ticker); + + DAP_DEL_Z(l_value_expected_str); + DAP_DEL_Z(l_locked_value_str); + l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_UNEXPECTED_VALUE; + break; + } } if (!l_girdled_ems) { // check tiker @@ -3822,17 +3725,15 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t } else { //It's not the emission TX // Get previous transaction in the cache by hash dap_chain_ledger_tx_item_t *l_item_out = NULL; - l_tx_prev = s_find_datum_tx_by_hash(a_ledger, &l_tx_prev_hash, &l_item_out); + l_tx_prev = s_find_datum_tx_by_hash(a_ledger, &l_tx_prev_hash, &l_item_out, false); if (!l_tx_prev) { // Unchained transaction or previous TX was already spent and removed from ledger - dap_chain_ledger_tx_spent_item_t *l_used_item = dap_chain_ledger_tx_spent_find_by_hash(a_ledger, &l_tx_prev_hash); - if (l_used_item) { - l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_OUT_ITEM_ALREADY_USED; - debug_if(s_debug_more, L_INFO, "All 'out' items of previous tx %s were already spent", l_tx_prev_hash_str); - break; - } debug_if(s_debug_more && !a_from_threshold, L_DEBUG, "No previous transaction was found for hash %s", l_tx_prev_hash_str); l_err_num = DAP_CHAIN_CS_VERIFY_CODE_TX_NO_PREVIOUS; break; + } else if (l_item_out->cache_data.ts_spent) { + l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_OUT_ITEM_ALREADY_USED; + debug_if(s_debug_more, L_INFO, "All 'out' items of previous tx %s were already spent", l_tx_prev_hash_str); + break; } bound_item->item_out = l_item_out; l_token = l_item_out->cache_data.token_ticker; @@ -4615,29 +4516,10 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d l_cache_used_outs[i].timestamp = dap_nanotime_now(); } - // delete previous transactions from cache because all out is used - if(l_prev_item_out->cache_data.n_outs_used == l_prev_item_out->cache_data.n_outs) { - dap_chain_hash_fast_t *l_tx_prev_hash_to_del = &l_prev_item_out->tx_hash_fast; //&bound_item->tx_prev_hash; - char l_tx_prev_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; - dap_chain_hash_fast_to_str(l_tx_prev_hash_to_del, l_tx_prev_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE); - // remove from memory ledger - int res = dap_chain_ledger_tx_remove(a_ledger, l_tx_prev_hash_to_del, a_tx->header.ts_created); - switch (res) { - case 1: - debug_if(s_debug_more, L_INFO, "Deleted prev tx %s from ledger", l_tx_prev_hash_str); - break; - case -2: - debug_if(s_debug_more, L_ERROR, "Can't delete previous transactions %s: hash not found", l_tx_prev_hash_str); - l_ret = -100; - l_outs_used = i; - goto FIN; - default: - debug_if(s_debug_more, L_ERROR, "Can't delete previous transaction %s, res code %d", l_tx_prev_hash_str, res); - l_ret = -101; - l_outs_used = i; - goto FIN; - } - } + // mark previous transactions as used with the extra timestamp + if(l_prev_item_out->cache_data.n_outs_used == l_prev_item_out->cache_data.n_outs) + l_prev_item_out->cache_data.ts_spent = a_tx->header.ts_created; + // go to next previous transaction l_list_tmp = dap_list_next(l_list_tmp); } @@ -4847,84 +4729,10 @@ int dap_chain_ledger_tx_load(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, 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_BYHASHVALUE(hh, PVT(a_ledger)->spent_items, a_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 DAP_CHAIN_LEDGER_TX_CACHE_CHECK_OUT_ITEM_ALREADY_USED; } return dap_chain_ledger_tx_add(a_ledger, a_tx, a_tx_hash, false); } -/** - * Delete transaction from the cache - * - * return 1 OK, -1 error, -2 tx_hash not found - */ -int dap_chain_ledger_tx_remove(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash, dap_time_t a_spent_time) -{ - if(!a_tx_hash) - return -1; - int l_ret = -1; - dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); - dap_chain_ledger_tx_item_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_pvt->ledger_rwlock); - HASH_FIND_BYHASHVALUE(hh, l_ledger_pvt->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_pvt->ledger_items, l_item_tmp); - if (PVT(a_ledger)->cached) { - // 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_STR_SIZE]; - dap_chain_hash_fast_to_str(a_tx_hash, l_tx_hash_str, sizeof(l_tx_hash_str)); - dap_global_db_del(l_gdb_group, l_tx_hash_str, NULL, NULL); - DAP_DELETE(l_gdb_group); - } - l_ret = 1; - dap_chain_ledger_tx_spent_item_t *l_item_used; - HASH_FIND_BYHASHVALUE(hh, l_ledger_pvt->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); - if ( !l_item_used ) { - log_it(L_CRITICAL, "Memory allocation error"); - if (l_item_tmp->tx) - DAP_DELETE(l_item_tmp->tx); - if (l_item_tmp) - DAP_DELETE(l_item_tmp); - pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock); - return -1; - } - l_item_used->tx_hash_fast = *a_tx_hash; - l_item_used->cache_data.spent_time = a_spent_time; - strncpy(l_item_used->cache_data.token_ticker, l_item_tmp->cache_data.token_ticker, DAP_CHAIN_TICKER_SIZE_MAX); - int l_out_num = 0; - dap_chain_datum_tx_out_cond_get(l_item_tmp->tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_ALL, &l_out_num); - if (l_out_num != -1 && l_out_num < MAX_OUT_ITEMS) - l_item_used->cache_data.tx_hash_spent_fast = l_item_tmp->cache_data.tx_hash_spent_fast[l_out_num]; - HASH_ADD_BYHASHVALUE(hh, l_ledger_pvt->spent_items, tx_hash_fast, sizeof(dap_chain_hash_fast_t), l_hash_value, l_item_used); - if (PVT(a_ledger)->cached) { - // Add it to cache - char *l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_SPENT_TXS_STR); - char l_tx_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; - dap_chain_hash_fast_to_str(a_tx_hash, l_tx_hash_str, sizeof(l_tx_hash_str)); - if (dap_global_db_set(l_gdb_group, l_tx_hash_str, &l_item_used->cache_data, sizeof(l_item_used->cache_data), false, NULL, NULL)) - debug_if(s_debug_more, L_WARNING, "Ledger cache mismatch"); - DAP_DELETE(l_gdb_group); - } - } - // delete tx & its item - DAP_DEL_Z(l_item_tmp->tx); - DAP_DELETE(l_item_tmp); - } - else - // hash not found in the cache - l_ret = -2; - pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock); - return l_ret; -} - /** * Delete all transactions from the cache */ @@ -4952,12 +4760,6 @@ void dap_chain_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db) DAP_DELETE(l_gdb_group); } - /* Delete spent transactions */ - dap_chain_ledger_tx_spent_item_t *l_spent_item_current, *l_spent_item_tmp; - HASH_ITER(hh, l_ledger_pvt->spent_items, l_spent_item_current, l_spent_item_tmp) { - HASH_DEL(l_ledger_pvt->spent_items, l_spent_item_current); - DAP_DEL_Z(l_item_current); - } if (!a_preserve_db) { l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_SPENT_TXS_STR); dap_global_db_del(l_gdb_group, NULL, NULL, NULL); @@ -5034,7 +4836,6 @@ void dap_chain_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db) } l_ledger_pvt->ledger_items = NULL; - l_ledger_pvt->spent_items = NULL; l_ledger_pvt->balance_accounts = NULL; l_ledger_pvt->tokens = NULL; l_ledger_pvt->threshold_emissions = NULL; @@ -5122,9 +4923,8 @@ size_t dap_chain_ledger_count_tps(dap_ledger_t *a_ledger, struct timespec *a_ts_ bool dap_chain_ledger_tx_hash_is_used_out_item(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash, int a_idx_out, dap_hash_fast_t *a_out_spender) { dap_chain_ledger_tx_item_t *l_item_out = NULL; - //dap_chain_datum_tx_t *l_tx = - s_find_datum_tx_by_hash(a_ledger, a_tx_hash, &l_item_out); - return s_ledger_tx_hash_is_used_out_item(l_item_out, a_idx_out, a_out_spender); + /*dap_chain_datum_tx_t *l_tx =*/ s_find_datum_tx_by_hash(a_ledger, a_tx_hash, &l_item_out, false); + return l_item_out ? s_ledger_tx_hash_is_used_out_item(l_item_out, a_idx_out, a_out_spender) : true; } /** @@ -5163,7 +4963,7 @@ uint256_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_c { uint256_t balance = uint256_0; - if(!a_addr || !dap_chain_addr_check_sum(a_addr)) + if(!a_addr || dap_chain_addr_check_sum(a_addr)) return balance; dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); @@ -5629,9 +5429,10 @@ int dap_chain_ledger_verificator_add(dap_chain_tx_out_cond_subtype_t a_subtype, return 0; } -dap_list_t * dap_chain_ledger_get_txs(dap_ledger_t *a_ledger, size_t a_count, size_t a_page, bool a_reverse) +dap_list_t *dap_chain_ledger_get_txs(dap_ledger_t *a_ledger, size_t a_count, size_t a_page, bool a_reverse, bool a_unspent_only) { dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); + pthread_rwlock_rdlock(&PVT(a_ledger)->ledger_rwlock); size_t l_offset = a_page < 2 ? 0 : a_count * (a_page - 1); if (!l_ledger_pvt->ledger_items || l_offset > HASH_COUNT(l_ledger_pvt->ledger_items)){ return NULL; @@ -5642,11 +5443,13 @@ dap_list_t * dap_chain_ledger_get_txs(dap_ledger_t *a_ledger, size_t a_count, si dap_chain_ledger_tx_item_t *l_item_current, *l_item_tmp; HASH_ITER(hh, l_ledger_pvt->ledger_items, l_item_current, l_item_tmp) { if (l_counter++ >= l_offset) { - l_list = a_reverse - ? dap_list_prepend(l_list, l_item_current->tx) - : dap_list_append(l_list, l_item_current->tx); + if (!a_unspent_only || !l_item_current->cache_data.ts_spent) + l_list = a_reverse + ? dap_list_prepend(l_list, l_item_current->tx) + : dap_list_append(l_list, l_item_current->tx); } } + pthread_rwlock_unlock(&PVT(a_ledger)->ledger_rwlock); return l_list; } diff --git a/modules/chain/include/dap_chain_ledger.h b/modules/chain/include/dap_chain_ledger.h index 5b4e11f4f511733763a736706e9ada35705e9d8f..12dbb04da3fb9f6164f6541d45c2b11005f29d8d 100644 --- a/modules/chain/include/dap_chain_ledger.h +++ b/modules/chain/include/dap_chain_ledger.h @@ -200,7 +200,7 @@ char* dap_chain_ledger_tx_check_err_str(int a_code); * */ -char * dap_ledger_token_tx_item_list(dap_ledger_t * a_ledger, dap_chain_addr_t *a_addr, const char *a_hash_out_type); +char * dap_ledger_token_tx_item_list(dap_ledger_t * a_ledger, dap_chain_addr_t *a_addr, const char *a_hash_out_type, bool a_unspent_only); /** * Check token ticker existance @@ -215,7 +215,7 @@ dap_chain_datum_token_t *dap_chain_ledger_token_ticker_check(dap_ledger_t * a_le */ int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token, size_t a_token_size); -int dap_chain_ledger_token_load(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token, size_t a_token_size); +int dap_chain_ledger_token_load(dap_ledger_t *a_ledger, byte_t *a_token, size_t a_token_size); int dap_chain_ledger_token_decl_add_check(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token, size_t a_token_size); char *dap_chain_ledger_token_decl_add_err_code_to_str(int a_code); dap_list_t *dap_chain_ledger_token_info(dap_ledger_t *a_ledger); @@ -262,13 +262,6 @@ bool dap_chain_ledger_tx_poa_signed(dap_ledger_t *a_ledger, dap_chain_datum_tx_t int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, bool a_from_threshold, dap_list_t **a_list_bound_items, dap_list_t **a_list_tx_out, char **a_main_ticker); -/** - * Delete transaction from the cache - * - * return 1 OK, -1 error, -2 tx_hash not found - */ -int dap_chain_ledger_tx_remove(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash, dap_time_t a_spent_time); - /** * Delete all transactions from the cache */ @@ -283,7 +276,6 @@ void dap_chain_ledger_load_end(dap_ledger_t *a_ledger); * Return number transactions from the cache */ unsigned dap_chain_ledger_count(dap_ledger_t *a_ledger); - uint64_t dap_chain_ledger_count_from_to(dap_ledger_t * a_ledger, dap_time_t a_ts_from, dap_time_t a_ts_to); size_t dap_chain_ledger_count_tps(dap_ledger_t *a_ledger, struct timespec *a_ts_from, struct timespec *a_ts_to); void dap_chain_ledger_set_tps_start_time(dap_ledger_t *a_ledger); @@ -309,7 +301,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); -void *dap_chain_ledger_tx_spent_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash); +dap_chain_datum_tx_t* dap_chain_ledger_tx_spent_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash); dap_hash_fast_t *dap_chain_ledger_get_final_chain_tx_hash(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_cond_type, dap_chain_hash_fast_t *a_tx_hash); // Get the transaction in the cache by the addr in out item @@ -346,7 +338,7 @@ int dap_chain_ledger_verificator_add(dap_chain_tx_out_cond_subtype_t a_subtype, dap_chain_ledger_updater_callback_t a_callback_added); // Getting a list of transactions from the ledger. -dap_list_t * dap_chain_ledger_get_txs(dap_ledger_t *a_ledger, size_t a_count, size_t a_page, bool a_reverse); +dap_list_t * dap_chain_ledger_get_txs(dap_ledger_t *a_ledger, size_t a_count, size_t a_page, bool a_reverse, bool a_unspent_only); //bool dap_chain_ledger_fee_verificator(dap_ledger_t* a_ledger, dap_chain_tx_out_cond_t* a_cond, dap_chain_datum_tx_t* a_tx, bool a_owner); diff --git a/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c index fc4c89d08ea95a5ff462bb9acad1eddd8fa3c2d2..2c6ffd5ea1bd2bd5dbccac73442a4207583677fb 100644 --- a/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c +++ b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c @@ -241,7 +241,7 @@ static void s_service_start(dap_stream_ch_t* a_ch , dap_stream_ch_chain_net_srv_ if ( ! l_net ) { // Network not found - log_it( L_WARNING, "Can't find net with id %"DAP_UINT64_FORMAT_U, a_request->hdr.srv_uid.uint64); + log_it( L_WARNING, "Can't find net with id 0x%016"DAP_UINT64_FORMAT_x"", a_request->hdr.srv_uid.uint64); l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_NETWORK_NOT_FOUND; if(a_ch) dap_stream_ch_pkt_write_unsafe(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof (l_err)); diff --git a/modules/common/dap_chain_common.c b/modules/common/dap_chain_common.c index 08b1c2aa279131b4b4386c7c11feea6471292c6f..8ccb6fd45271b4aa2e91409d7b2b457c1473d2bc 100644 --- a/modules/common/dap_chain_common.c +++ b/modules/common/dap_chain_common.c @@ -131,17 +131,14 @@ dap_chain_addr_t* dap_chain_addr_from_str(const char *a_str) size_t l_str_len = (a_str) ? strlen(a_str) : 0; if(l_str_len <= 0) return NULL; - if (dap_strcmp(a_str, "null") == 0) { + if (!dap_strcmp(a_str, "null") || !dap_strcmp(a_str, "0")) { return DAP_NEW_Z(dap_chain_addr_t); } size_t l_ret_size = DAP_ENC_BASE58_DECODE_SIZE(l_str_len); - dap_chain_addr_t * l_addr = DAP_NEW_Z_SIZE(dap_chain_addr_t, l_ret_size); - if(dap_enc_base58_decode(a_str, l_addr) == sizeof(dap_chain_addr_t) && - dap_chain_addr_check_sum(l_addr)==1) - return l_addr; - else - DAP_DELETE(l_addr); - return NULL; + dap_chain_addr_t *l_addr = DAP_NEW_Z_SIZE(dap_chain_addr_t, l_ret_size); + return (dap_enc_base58_decode(a_str, l_addr) == sizeof(dap_chain_addr_t)) && !dap_chain_addr_check_sum(l_addr) + ? l_addr + : ({ DAP_DELETE(l_addr); NULL; }); } bool dap_chain_addr_is_blank(const dap_chain_addr_t *a_addr) @@ -247,19 +244,18 @@ void dap_chain_addr_fill(dap_chain_addr_t *a_addr, dap_sign_type_t a_type, dap_c /** * @brief dap_chain_addr_check_sum * @param a_addr - * @return 1 Ok, -1 Invalid a_addr or checksum + * @return 0 - Ok, otherwise - Invalid a_addr or checksum */ int dap_chain_addr_check_sum(const dap_chain_addr_t *a_addr) { if(!a_addr) return -1; - if (dap_chain_addr_is_blank(a_addr)) return 1; + if (dap_chain_addr_is_blank(a_addr)) + return 0; dap_chain_hash_fast_t l_checksum; // calc checksum dap_hash_fast(a_addr, sizeof(dap_chain_addr_t) - sizeof(dap_chain_hash_fast_t), &l_checksum); - if(!memcmp(a_addr->checksum.raw, l_checksum.raw, sizeof(l_checksum.raw))) - return 1; - return -1; + return memcmp(a_addr->checksum.raw, l_checksum.raw, sizeof(l_checksum.raw)); } diff --git a/modules/common/dap_chain_datum_token.c b/modules/common/dap_chain_datum_token.c index c7090dea095c6c0e67ae2b2cc189375cd0c1396d..4566139492d26ceec1df06cc892001b4d3aa1508 100644 --- a/modules/common/dap_chain_datum_token.c +++ b/modules/common/dap_chain_datum_token.c @@ -184,9 +184,12 @@ dap_chain_datum_token_t *dap_chain_datum_token_read(const byte_t *a_token_serial *a_token_size = l_token_size; return l_token; } + case DAP_CHAIN_DATUM_TOKEN_TYPE_DECL: + case DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE: + return DAP_DUP_SIZE(a_token_serial, *a_token_size); default: log_it(L_NOTICE, "Unknown token type '%d' read", ((dap_chain_datum_token_t*)a_token_serial)->type); - return DAP_DUP_SIZE(a_token_serial, *a_token_size); + return NULL; } } diff --git a/modules/common/dap_chain_datum_tx_items.c b/modules/common/dap_chain_datum_tx_items.c index 22a5c1557310575d029546262bc505bbcd3bba37..64e09ba41a5304fa982667ef72dc667f4388616f 100644 --- a/modules/common/dap_chain_datum_tx_items.c +++ b/modules/common/dap_chain_datum_tx_items.c @@ -806,7 +806,7 @@ uint8_t *dap_chain_datum_tx_item_get_nth(dap_chain_datum_tx_t *a_tx, dap_chain_t dap_chain_tx_out_cond_t *dap_chain_datum_tx_out_cond_get(dap_chain_datum_tx_t *a_tx, dap_chain_tx_item_type_t a_cond_type, int *a_out_num) { dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_OUT_ALL, NULL), *l_item; - int l_prev_cond_idx = a_out_num ? *a_out_num : 0; + int l_prev_cond_idx = 0; dap_chain_tx_out_cond_t *l_res = NULL; for (dap_list_t *l_item = l_list_out_items; l_item; l_item = l_item->next, ++l_prev_cond_idx) { // Start from *a_out_num + 1 item if a_out_num != NULL diff --git a/modules/mempool/dap_chain_mempool.c b/modules/mempool/dap_chain_mempool.c index a7b58980f1a8c53d79a6a7a5ee9dc497c5a67624..2b5537d75603ad2ce45d7e11dc4c0f9ccbca829f 100644 --- a/modules/mempool/dap_chain_mempool.c +++ b/modules/mempool/dap_chain_mempool.c @@ -147,7 +147,7 @@ char *dap_chain_mempool_tx_create(dap_chain_t * a_chain, dap_enc_key_t *a_key_fr { // check valid param if(!a_chain | !a_key_from || ! a_addr_from || !a_key_from->priv_key_data || !a_key_from->priv_key_data_size || - !dap_chain_addr_check_sum(a_addr_from) || (a_addr_to && !dap_chain_addr_check_sum(a_addr_to)) || IS_ZERO_256(a_value)) + dap_chain_addr_check_sum(a_addr_from) || (a_addr_to && dap_chain_addr_check_sum(a_addr_to)) || IS_ZERO_256(a_value)) return NULL; const char *l_native_ticker = dap_chain_net_by_id(a_chain->net_id)->pub.native_ticker; @@ -394,7 +394,7 @@ int dap_chain_mempool_tx_create_massive( dap_chain_t * a_chain, dap_enc_key_t *a { // check valid paramdap_chain_mempool_tx_coll_fee_create if(!a_chain | !a_key_from || !a_addr_from || !a_key_from->priv_key_data || !a_key_from->priv_key_data_size || - !dap_chain_addr_check_sum(a_addr_from) || !dap_chain_addr_check_sum(a_addr_to) || + dap_chain_addr_check_sum(a_addr_from) || dap_chain_addr_check_sum(a_addr_to) || IS_ZERO_256(a_value) || !a_tx_num){ log_it(L_ERROR, "Wrong parameters in dap_chain_mempool_tx_create_massive() call"); return -1; @@ -628,7 +628,7 @@ char* dap_chain_mempool_tx_create_cond_input(dap_chain_net_t *a_net, dap_chain_h return NULL; } - if ( ! dap_chain_addr_check_sum (a_addr_to) ){ + if (dap_chain_addr_check_sum (a_addr_to)) { log_it(L_ERROR, "Wrong address_to checksum"); if (a_ret_status) *a_ret_status = DAP_CHAIN_MEMPOOl_RET_STATUS_WRONG_ADDR; diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c index 2527796b69d0f2b96e35111808fbbc26ed06f43b..46e24a3c8e9cb8b16f14c25a1d42c6c6a9440266 100644 --- a/modules/net/dap_chain_net.c +++ b/modules/net/dap_chain_net.c @@ -176,7 +176,6 @@ typedef struct dap_chain_net_pvt{ uint16_t seed_nodes_count; struct sockaddr_in *seed_nodes_ipv4; struct sockaddr_in6 *seed_nodes_ipv6; // TODO - _Atomic(dap_chain_net_state_t) state, state_target; uint16_t acl_idx; @@ -262,8 +261,8 @@ int dap_chain_net_init() dap_chain_node_client_init(); dap_chain_node_net_ban_list_init(); dap_cli_server_cmd_add ("net", s_cli_net, "Network commands", - "net list [chains -n <chain net name>]" - "\tList all networks or list all chains in selected network" + "net list [chains -net <chain net name>]\n" + "\tList all networks or list all chains in selected network\n" "net -net <chain net name> [-mode {update | all}] go {online | offline | sync}\n" "\tFind and establish links and stay online. \n" "\tMode \"update\" is by default when only new chains and gdb are updated. Mode \"all\" updates everything from zero\n" @@ -274,7 +273,7 @@ int dap_chain_net_init() "net -net <chain net name> [-mode {update | all}] sync {all | gdb | chains}\n" "\tSyncronyze gdb, chains or everything\n" "\tMode \"update\" is by default when only new chains and gdb are updated. Mode \"all\" updates everything from zero\n" - "net -net <chain net name> link {list | add | del | info | disconnect_all}\n" + "net -net <chain net name> link {list | add | del | info [-addr] | disconnect_all}\n" "\tList, add, del, dump or establish links\n" "net -net <chain net name> ca add {-cert <cert name> | -hash <cert hash>}\n" "\tAdd certificate to list of authority cetificates in GDB group\n" @@ -387,7 +386,7 @@ dap_chain_net_state_t dap_chain_net_get_target_state(dap_chain_net_t *a_net) dap_chain_node_info_t *dap_chain_net_balancer_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 = {}; + struct in_addr l_addr = { }; uint16_t i, l_port = 0; if (l_net_pvt->seed_nodes_count) { i = dap_random_uint16() % l_net_pvt->seed_nodes_count; @@ -1488,9 +1487,17 @@ static int s_cli_net(int argc, char **argv, char **a_str_reply) if (dap_strcmp(l_list_cmd,"chains")==0){ const char * l_net_str = NULL; dap_chain_net_t* l_net = NULL; - dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-net", &l_net_str); + if (dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-net", &l_net_str) && !l_net_str) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Parameter '-net' require <net name>"); + return -1; + } l_net = dap_chain_net_by_name(l_net_str); + if (l_net_str && !l_net) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Wrong <net name>, use 'net list' " + "command to display a list of available networks"); + return -1; + } if (l_net){ dap_string_append(l_string_ret,"Chains:\n"); @@ -1524,6 +1531,12 @@ static int s_cli_net(int argc, char **argv, char **a_str_reply) } }else{ + // plug for wrong command arguments + if (argc > 2) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "To many arguments for 'net list' command see help"); + return -1; + } + dap_string_append(l_string_ret,"Networks:\n"); // show list of nets dap_chain_net_item_t * l_net_item, *l_net_item_tmp; @@ -2087,7 +2100,7 @@ int s_net_init(const char * a_net_name, uint16_t a_acl_idx) ,dap_config_get_item_str(l_cfg , "general" , "name" )); l_net_item->chain_net = l_net; l_net_item->net_id.uint64 = l_net->pub.id.uint64; - HASH_ADD_STR(s_net_items, name,l_net_item); + HASH_ADD_STR(s_net_items, name, l_net_item); HASH_ADD(hh2, s_net_ids, net_id, sizeof(l_net_item->net_id), l_net_item); // Maximum number of prepared connections to other nodes @@ -3142,7 +3155,7 @@ int dap_chain_datum_add(dap_chain_t *a_chain, dap_chain_datum_t *a_datum, size_t return dap_chain_net_anchor_load(l_anchor, a_chain); } case DAP_CHAIN_DATUM_TOKEN_DECL: - return dap_chain_ledger_token_load(l_ledger, (dap_chain_datum_token_t *)a_datum->data, a_datum->header.data_size); + return dap_chain_ledger_token_load(l_ledger, a_datum->data, a_datum->header.data_size); case DAP_CHAIN_DATUM_TOKEN_EMISSION: return dap_chain_ledger_token_emission_load(l_ledger, a_datum->data, a_datum->header.data_size, a_datum_hash); diff --git a/modules/net/dap_chain_net_tx.c b/modules/net/dap_chain_net_tx.c index 1b83023b261119586544b5d193a85c21b9d5e6a4..9f983be66b01e70a7d89a74304cc092ef8ab8d1a 100644 --- a/modules/net/dap_chain_net_tx.c +++ b/modules/net/dap_chain_net_tx.c @@ -93,7 +93,7 @@ dap_chain_datum_tx_spends_items_t * dap_chain_net_get_tx_cond_all_with_spends_by if(a_search_type == TX_SEARCH_TYPE_CELL_SPENT || a_search_type == TX_SEARCH_TYPE_NET_SPENT ){ dap_hash_fast_t * l_tx_hash = dap_chain_node_datum_tx_calc_hash(l_tx); - bool l_is_spent = dap_chain_ledger_tx_spent_find_by_hash(l_ledger,l_tx_hash); + bool l_is_spent = !!dap_chain_ledger_tx_spent_find_by_hash(l_ledger,l_tx_hash); DAP_DELETE(l_tx_hash); if(!l_is_spent) continue; @@ -524,8 +524,8 @@ dap_list_t * dap_chain_net_get_tx_cond_all_by_srv_uid(dap_chain_net_t * a_net, c continue; if(a_search_type == TX_SEARCH_TYPE_CELL_SPENT || a_search_type == TX_SEARCH_TYPE_NET_SPENT ){ - dap_hash_fast_t * l_tx_hash = dap_chain_node_datum_tx_calc_hash(l_tx); - bool l_is_spent = dap_chain_ledger_tx_spent_find_by_hash(l_ledger,l_tx_hash); + dap_hash_fast_t *l_tx_hash = dap_chain_node_datum_tx_calc_hash(l_tx); + bool l_is_spent = !!dap_chain_ledger_tx_spent_find_by_hash(l_ledger,l_tx_hash); DAP_DELETE(l_tx_hash); if(!l_is_spent) continue; diff --git a/modules/net/dap_chain_node_cli.c b/modules/net/dap_chain_node_cli.c index e6b33293972fd172f559570878756351da6e93ba..eeb9a77da79c3818bbc184e2975138c9788bacc5 100644 --- a/modules/net/dap_chain_node_cli.c +++ b/modules/net/dap_chain_node_cli.c @@ -302,7 +302,7 @@ int dap_chain_node_cli_init(dap_config_t * g_config) "ledger list threshold [-hash <tx_treshold_hash>] -net <net_name>\n" "ledger list balance -net <net_name>\n" "ledger info -hash <tx_hash> -net <net_name> [-unspent]\n" - "ledger tx -all -net <net_name>\n" + "ledger tx -all -net <net_name> [-unspent]\n" "ledger tx {-addr <addr> | -w <wallet_name> | -tx <tx_hash>} -net <net_name>\n"); // Token info diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c index 23bc259eee04eb7912f797b2de21bbe4c9642fb9..b48ae81e5d1f988a987341f5be09902fcf10c392 100644 --- a/modules/net/dap_chain_node_cli_cmd.c +++ b/modules/net/dap_chain_node_cli_cmd.c @@ -2876,7 +2876,10 @@ int com_mempool_list(int a_argc, char **a_argv, char **a_str_reply) const char * l_hash_out_type = "hex"; dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-H", &l_hash_out_type); dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, a_argc, a_argv, a_str_reply, &l_chain, &l_net); - dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-addr", &l_addr_base58); + if (dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-addr", &l_addr_base58) && !l_addr_base58) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Parameter '-addr' require <addr>"); + return -1; + } l_fast = (dap_cli_server_cmd_check_option(a_argv, arg_index, a_argc, "-fast") != -1) ? true : false; if(!l_net) return -1; @@ -5336,7 +5339,7 @@ int com_tx_create_json(int a_argc, char ** a_argv, char **a_str_reply) } //CHECK value fee l_list_used_out_fee = dap_chain_ledger_get_list_tx_outs_with_val(l_net->pub.ledger, l_native_token, - l_addr_from, l_value_need_fee, &l_value_transfer_fee); + l_addr_from, l_value_need_fee, &l_value_transfer_fee); if(!l_list_used_out_fee) { log_it(L_WARNING, "Not enough funds in previous tx to transfer"); dap_string_append_printf(l_err_str, "Can't create in transaction. Not enough funds in previous tx " @@ -5672,8 +5675,7 @@ int com_tx_create(int a_argc, char **a_argv, char **a_str_reply) return -10; } - // Check, if network ID is same as ID in destination wallet address. If not - operation is cancelled. - if (l_addr_to->net_id.uint64 != l_net->pub.id.uint64) { + if (l_addr_to->net_id.uint64 != l_net->pub.id.uint64 && !dap_chain_addr_is_blank(l_addr_to)) { bool l_found = false; for (dap_list_t *it = l_net->pub.bridged_networks; it; it = it->next) { if (((dap_chain_net_id_t *)it->data)->uint64 == l_addr_to->net_id.uint64) { @@ -6081,7 +6083,7 @@ int com_print_log(int a_argc, char **a_argv, char **a_str_reply) dap_cli_server_cmd_set_reply_text(a_str_reply, "requires valid parameter 'l_ts_after'"); return -1; } - if(!l_limit) { + if(l_limit <= 0) { dap_cli_server_cmd_set_reply_text(a_str_reply, "requires valid parameter 'limit'"); return -1; } diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c index 6c74cdc842725fc7e4c8f755f1428e15b34c6aef..b478c2ea7bc0df288083923e0165afdff2517d13 100644 --- a/modules/net/dap_chain_node_cli_cmd_tx.c +++ b/modules/net/dap_chain_node_cli_cmd_tx.c @@ -113,7 +113,9 @@ static bool s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, switch (*(dap_chain_tx_item_type_t*)l_item->data) { case TX_ITEM_TYPE_OUT: case TX_ITEM_TYPE_OUT_OLD: - case TX_ITEM_TYPE_OUT_EXT: { + case TX_ITEM_TYPE_OUT_EXT: + case TX_ITEM_TYPE_OUT_COND_OLD: + case TX_ITEM_TYPE_OUT_COND: { dap_hash_fast_t l_spender = { }; if (dap_chain_ledger_tx_hash_is_used_out_item(a_ledger, a_tx_hash, l_out_idx, &l_spender)) { char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE] = { '\0' }; @@ -467,8 +469,14 @@ static char* dap_db_chain_history_token_list(dap_chain_t * a_chain, const char * dap_chain_datum_t *l_datum = l_datums[l_datum_n]; if (!l_datum || l_datum->header.type_id != DAP_CHAIN_DATUM_TOKEN_DECL) continue; - if (a_token_name && dap_strcmp(((dap_chain_datum_token_t *)l_datum->data)->ticker, a_token_name)) - continue; + if (a_token_name) { + size_t l_token_size = l_datum->header.data_size; + dap_chain_datum_token_t *l_token = dap_chain_datum_token_read(l_datum->data, &l_token_size); + int l_cmp = dap_strcmp(l_token->ticker, a_token_name); + DAP_DELETE(l_token); + if (l_cmp) + continue; + } dap_chain_datum_dump(l_str_out, l_datum, a_hash_out_type, a_chain->net_id); (*a_token_num)++; } @@ -707,6 +715,7 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) dap_cli_server_cmd_find_option_val(a_argv, 0, a_argc, "-w", &l_wallet_name); dap_cli_server_cmd_find_option_val(a_argv, 0, a_argc, "-net", &l_net_str); dap_cli_server_cmd_find_option_val(a_argv, 0, a_argc, "-tx", &l_tx_hash_str); + bool l_unspent_flag = dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-unspent", NULL); dap_chain_tx_hash_processed_ht_t *l_list_tx_hash_processd = NULL; if(!l_is_all && !l_addr_base58 && !l_wallet_name && !l_tx_hash_str) { @@ -760,13 +769,13 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) char *l_str_out = NULL; dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(l_net_str); if(l_is_all) { - size_t l_tx_count = dap_chain_ledger_count(l_ledger); + size_t l_tx_count = dap_chain_ledger_count(l_ledger), l_tx_count_spent_count = 0; if (!l_tx_count) { dap_string_append_printf(l_str_ret, "Network ledger %s contains no transactions.\n", l_ledger->net_name); } else { dap_string_append_printf(l_str_ret, "There are %zu transactions in the network ledger %s:\n", l_tx_count, l_ledger->net_name); - dap_list_t *l_txs_list = dap_chain_ledger_get_txs(l_ledger, l_tx_count, 1, true); + dap_list_t *l_txs_list = dap_chain_ledger_get_txs(l_ledger, l_tx_count, 1, true, l_unspent_flag); for (dap_list_t *iter = l_txs_list; iter; iter = dap_list_next(iter)) { dap_chain_datum_tx_t *l_tx = iter->data; dap_hash_fast_t l_tx_hash = { }; @@ -778,23 +787,26 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) } else { if(l_addr) { - l_str_out = dap_ledger_token_tx_item_list(l_ledger,l_addr,l_hash_out_type); + l_str_out = dap_ledger_token_tx_item_list(l_ledger, l_addr, l_hash_out_type, l_unspent_flag); char *l_addr_str = dap_chain_addr_to_str(l_addr); dap_string_append_printf(l_str_ret, "history for addr %s:\n%s\n", l_addr_str, l_str_out ? l_str_out : " empty"); DAP_DELETE(l_addr_str); - }else if(l_tx_hash_str) { - dap_chain_datum_tx_t *l_tx = dap_chain_ledger_tx_find_by_hash(l_ledger,&l_tx_hash); - if(l_tx){ + } else if(l_tx_hash_str) { + dap_chain_datum_tx_t *l_tx = dap_chain_ledger_tx_find_by_hash(l_ledger, &l_tx_hash); + if (!l_tx && !l_unspent_flag) { + l_tx = dap_chain_ledger_tx_spent_find_by_hash(l_ledger, &l_tx_hash); + } + if(l_tx) { size_t l_tx_size = dap_chain_datum_tx_get_size(l_tx); dap_hash_fast_t l_tx_hash = { }; dap_hash_fast(l_tx, l_tx_size, &l_tx_hash); s_dap_chain_datum_tx_out_data(l_tx, l_ledger, l_str_ret, l_hash_out_type, &l_tx_hash); dap_string_append_printf(l_str_ret, "history for tx hash %s:\n%s\n", l_tx_hash_str, l_str_out ? l_str_out : " empty"); - } - else + } else { dap_string_append_printf(l_str_ret, "There is not transaction %s in the network ledger\n",l_tx_hash_str); + } } } DAP_DELETE(l_str_out); @@ -882,8 +894,7 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) //get net dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-net", &l_net_str); //get search type - const char *l_unspent_str = NULL; - dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-unspent", &l_unspent_str); + bool l_unspent_flag = dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-unspent", NULL); //check input if (l_tx_hash_str == NULL){ dap_cli_server_cmd_set_reply_text(a_str_reply, "Subcommand 'info' requires key -hash"); @@ -904,7 +915,7 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) return -4; } 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); + l_unspent_flag ? TX_SEARCH_TYPE_NET_UNSPENT : TX_SEARCH_TYPE_NET); if (l_datum_tx == NULL) { dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find datum for transaction hash %s in chains", l_tx_hash_str); return -5; diff --git a/modules/net/dap_chain_node_ping.c b/modules/net/dap_chain_node_ping.c index c92605d93ebe91ddcabfb84f246615810df00819..7bfc4acc011f124eabbb2c3e844c2ce852c36bf4 100644 --- a/modules/net/dap_chain_node_ping.c +++ b/modules/net/dap_chain_node_ping.c @@ -77,6 +77,11 @@ #define LOG_TAG "chain_node_ping" +typedef struct s_dap_chain_node_ping_background_arg{ + dap_chain_net_t *net; + dap_list_t *node_list; +}s_dap_chain_node_ping_background_arg_t; + static void* node_ping_proc(void *a_arg) { if(!a_arg) @@ -200,9 +205,11 @@ static void* node_ping_background_proc(void *a_arg) { if (!a_arg) return 0; - dap_chain_net_t *l_net = (dap_chain_net_t*)a_arg; - dap_list_t *l_node_list = (dap_list_t*)(a_arg + sizeof(dap_chain_net_t*)); + s_dap_chain_node_ping_background_arg_t *l_arg = (s_dap_chain_node_ping_background_arg_t*)a_arg; + dap_chain_net_t *l_net = l_arg->net; + dap_list_t *l_node_list = l_arg->node_list; dap_chain_node_addr_t l_node_addr = { 0 }; + s_node_addr_ping = DAP_NEW(dap_chain_node_addr_t); // select the nearest node from the list unsigned int l_nodes_count = dap_list_length(l_node_list); @@ -220,6 +227,11 @@ static void* node_ping_background_proc(void *a_arg) while(l_node_list) { dap_chain_node_addr_t *l_node_addr = l_node_list->data; dap_chain_node_info_t *l_node_info = dap_chain_node_info_read(l_net, l_node_addr); + if (!l_node_info) { + log_it(L_ERROR, "Can't extract node info"); + l_node_list = dap_list_next(l_node_list); + continue; + } char *host4 = DAP_NEW_STACK_SIZE(char, INET_ADDRSTRLEN); struct sockaddr_in sa4 = { .sin_family = AF_INET, .sin_addr = l_node_info->hdr.ext_addr_v4 }; @@ -256,7 +268,7 @@ static void* node_ping_background_proc(void *a_arg) int res = wait_node_ping(l_threads[l_thread_id], l_timeout_full_ms); if(res > 0 && res < best_node_reply) { best_node_pos = l_thread_id; - s_node_addr_ping = l_node_list->data; + s_node_addr_ping->uint64 = l_nodes_addr[l_thread_id]; best_node_reply = res; } struct timespec l_time_stop; @@ -277,23 +289,27 @@ static void* node_ping_background_proc(void *a_arg) log_it(L_CRITICAL, "Memory allocation error"); dap_list_free_full(l_node_list0, NULL); DAP_DEL_Z(s_node_addr_ping); + DAP_DELETE(a_arg); return 0; } memcpy(l_node_addr_tmp, s_node_addr_tr, sizeof(dap_chain_node_addr_t)); DAP_DELETE(s_node_addr_tr); s_node_addr_tr = l_node_addr_tmp; + DAP_DELETE(l_node_addr_tmp); l_node_addr_tmp = DAP_NEW(dap_chain_node_addr_t); if (!l_node_addr_tmp) { log_it(L_CRITICAL, "Memory allocation error"); dap_list_free_full(l_node_list0, NULL); DAP_DEL_Z(s_node_addr_ping); + DAP_DELETE(a_arg); return 0; } memcpy(l_node_addr_tmp, s_node_addr_ping, sizeof(dap_chain_node_addr_t)); DAP_DELETE(s_node_addr_ping); s_node_addr_ping = l_node_addr_tmp; dap_list_free_full(l_node_list0, NULL); + DAP_DELETE(a_arg); return 0; } @@ -322,14 +338,18 @@ int dap_chain_node_ping_background_start(dap_chain_net_t *a_net, dap_list_t *a_n l_node_list_tmp = dap_list_next(l_node_list_tmp); } // start searching for better nodes - uint8_t *l_arg = DAP_NEW_SIZE(uint8_t, sizeof(dap_chain_net_t*) + sizeof(dap_list_t*)); + s_dap_chain_node_ping_background_arg_t *l_arg = DAP_NEW(s_dap_chain_node_ping_background_arg_t); +// uint8_t *l_arg = DAP_NEW_SIZE(uint8_t, sizeof(dap_chain_net_t*) + sizeof(dap_list_t*)); + if (!l_arg) { log_it(L_CRITICAL, "Memory allocation error"); dap_list_free_full(l_node_list, NULL); return -1; } - memcpy(l_arg, &a_net, sizeof(dap_chain_net_t*)); - memcpy(l_arg + sizeof(dap_chain_net_t*), &l_node_list, sizeof(dap_list_t*)); + l_arg->net = a_net; + l_arg->node_list = l_node_list; +// memcpy(l_arg, &a_net, sizeof(dap_chain_net_t*)); +// memcpy(l_arg + sizeof(dap_chain_net_t*), &l_node_list, sizeof(dap_list_t*)); pthread_create(&s_thread, NULL, node_ping_background_proc, l_arg); return 0; } diff --git a/modules/net/include/dap_chain_net.h b/modules/net/include/dap_chain_net.h index 807382e720e0a9f2098ae0af2eeb57a7ea33e710..523b3e4717ecc053b5a02749e70cc12463ce4467 100644 --- a/modules/net/include/dap_chain_net.h +++ b/modules/net/include/dap_chain_net.h @@ -39,6 +39,7 @@ along with any CellFrame SDK based project. If not, see <http://www.gnu.org/lic #include "dap_chain_node.h" #include "dap_chain_ledger.h" #include "dap_chain_net_decree.h" +#include "dap_chain_net_tx.h" #include "dap_chain_datum_decree.h" #include "dap_chain_datum_anchor.h" #include "dap_chain_datum_tx.h" @@ -184,6 +185,7 @@ dap_chain_net_t **dap_chain_net_list(uint16_t *a_size); int dap_chain_net_verify_datum_for_add(dap_chain_t *a_chain, dap_chain_datum_t *a_datum, dap_hash_fast_t *a_datum_hash); char *dap_chain_net_verify_datum_err_code_to_str(dap_chain_datum_t *a_datum, int a_code); + void dap_chain_add_mempool_notify_callback(dap_chain_t *a_chain, dap_store_obj_callback_notify_t a_callback, void *a_cb_arg); void dap_chain_net_add_nodelist_notify_callback(dap_chain_net_t *a_net, dap_store_obj_callback_notify_t a_callback, void *a_cb_arg); void dap_chain_net_srv_order_add_notify_callback(dap_chain_net_t *a_net, dap_store_obj_callback_notify_t a_callback, void *a_cb_arg); diff --git a/modules/net/srv/dap_chain_net_srv.c b/modules/net/srv/dap_chain_net_srv.c index 83c929b3aec8c13bcb788b2cb70d9c7a169e181e..06f9791035761c49979bc45e0b4b7c9a05d46f0f 100644 --- a/modules/net/srv/dap_chain_net_srv.c +++ b/modules/net/srv/dap_chain_net_srv.c @@ -829,6 +829,7 @@ static bool s_pay_verificator_callback(dap_ledger_t * a_ledger, dap_chain_tx_out } int dap_chain_net_srv_price_apply_from_my_order(dap_chain_net_srv_t *a_srv, const char *a_config_section){ + // const char *l_wallet_path = dap_config_get_item_str_default(g_config, "resources", "wallets_path", NULL); // const char *l_wallet_name = dap_config_get_item_str_default(g_config, a_config_section, "wallet", NULL); @@ -838,6 +839,7 @@ int dap_chain_net_srv_price_apply_from_my_order(dap_chain_net_srv_t *a_srv, cons if (!l_wallet_addr || !l_cert_name || !l_net_name){ return -2; } + // dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_wallet_name, l_wallet_path); // if (!l_wallet) { // return -3; @@ -890,7 +892,7 @@ int dap_chain_net_srv_price_apply_from_my_order(dap_chain_net_srv_t *a_srv, cons continue; } } -// l_price->wallet = l_wallet; +// l_price->wallet = l_wallet; l_price->wallet_addr = dap_chain_addr_from_str(l_wallet_addr); if(!l_price->wallet_addr){ log_it(L_ERROR, "Can't get wallet addr from wallet_addr in config file."); @@ -909,6 +911,18 @@ int dap_chain_net_srv_price_apply_from_my_order(dap_chain_net_srv_t *a_srv, cons return -101; } + dap_hash_fast_t order_pkey_hash = { }, price_pkey_hash = { }; + dap_sign_get_pkey_hash((dap_sign_t*)l_order->ext_n_sign + l_order->ext_size, &order_pkey_hash); + dap_hash_fast(l_price->receipt_sign_cert->enc_key->pub_key_data, + l_price->receipt_sign_cert->enc_key->pub_key_data_size, &price_pkey_hash); + if (dap_hash_fast_compare(&order_pkey_hash, &price_pkey_hash)) + { + log_it(L_ERROR, "pkey in order not equal to pkey in config."); + DAP_DEL_Z(l_order); + DAP_DELETE(l_price); + dap_global_db_objs_delete(l_orders, l_orders_count); + continue; + } // TODO: find most advantageous for us order DL_APPEND(a_srv->pricelist, l_price); @@ -1125,7 +1139,6 @@ void dap_chain_net_srv_del_all(void) pthread_mutex_lock(&s_srv_list_mutex); HASH_ITER(hh, s_srv_list , l_sdata, l_sdata_tmp) { - // Clang bug at this, l_sdata should change at every loop cycle HASH_DEL(s_srv_list, l_sdata); pthread_mutex_destroy(&l_sdata->srv->banlist_mutex); DAP_DELETE(l_sdata->srv); diff --git a/modules/net/srv/dap_chain_net_srv_client.c b/modules/net/srv/dap_chain_net_srv_client.c index a234d08e04af2107ea2ea6a843ee068cb4ea2ec0..d05c7c95c99ed5a8db7f0613a703e93dc69fdef1 100644 --- a/modules/net/srv/dap_chain_net_srv_client.c +++ b/modules/net/srv/dap_chain_net_srv_client.c @@ -48,12 +48,15 @@ dap_chain_net_srv_client_t *dap_chain_net_srv_client_create_n_connect(dap_chain_ if (a_callbacks) l_ret->callbacks = *a_callbacks; l_ret->callbacks_arg = a_callbacks_arg; + dap_chain_node_client_callbacks_t l_callbacks = { .connected = s_srv_client_callback_connected, .disconnected = s_srv_client_callback_disconnected, .delete = s_srv_client_callback_deleted }; + dap_chain_node_info_t *l_info = DAP_NEW_Z(dap_chain_node_info_t); + if (!l_info) { log_it(L_CRITICAL, "Memory allocation error"); DAP_DEL_Z(l_ret); @@ -69,6 +72,10 @@ dap_chain_net_srv_client_t *dap_chain_net_srv_client_create_n_connect(dap_chain_ DAP_DELETE(l_info); return l_ret; } +void dap_chain_net_srv_client_close(dap_chain_net_srv_client_t *a_client){ + if (a_client->node_client) + dap_chain_node_client_close_mt( a_client->node_client ); +} ssize_t dap_chain_net_srv_client_write(dap_chain_net_srv_client_t *a_client, uint8_t a_type, void *a_pkt_data, size_t a_pkt_data_size) { @@ -108,8 +115,6 @@ static void s_srv_client_callback_deleted(dap_chain_node_client_t *a_node_client UNUSED(a_node_client); log_it(L_INFO, "Service client deleted"); dap_chain_net_srv_client_t *l_srv_client = (dap_chain_net_srv_client_t *)a_arg; - if (l_srv_client->callbacks.deleted) - l_srv_client->callbacks.deleted(l_srv_client, l_srv_client->callbacks_arg); DAP_DELETE(l_srv_client); } diff --git a/modules/net/srv/include/dap_chain_net_srv_client.h b/modules/net/srv/include/dap_chain_net_srv_client.h index b5da5a6b9532e5eda2ef87124830cbd16de2bebe..50e19d2562d1b58a99e9e4987784e86e07f86b1c 100644 --- a/modules/net/srv/include/dap_chain_net_srv_client.h +++ b/modules/net/srv/include/dap_chain_net_srv_client.h @@ -64,4 +64,7 @@ typedef struct dap_chain_net_srv_client { dap_chain_net_srv_client_t *dap_chain_net_srv_client_create_n_connect(dap_chain_net_t *a_net, char *a_addr, uint16_t a_port, dap_chain_net_srv_client_callbacks_t *a_callbacks, void *a_callbacks_arg); + +void dap_chain_net_srv_client_close(dap_chain_net_srv_client_t *a_client); + ssize_t dap_chain_net_srv_client_write(dap_chain_net_srv_client_t *a_client, uint8_t a_type, void *a_pkt_data, size_t a_pkt_data_size); diff --git a/modules/service/datum/dap_chain_net_srv_datum.c b/modules/service/datum/dap_chain_net_srv_datum.c index 190df48fdd2a8f6821eda60c3d6e9510ae5e81e0..87db2ea5442cffc33a5645090153962a6b518e3a 100644 --- a/modules/service/datum/dap_chain_net_srv_datum.c +++ b/modules/service/datum/dap_chain_net_srv_datum.c @@ -120,6 +120,10 @@ static int s_srv_datum_cli(int argc, char ** argv, char **a_str_reply) { } const char * l_system_datum_folder = dap_config_get_item_str(g_config, "resources", "datum_folder"); + if (!l_system_datum_folder){ + dap_cli_server_cmd_set_reply_text(a_str_reply, "Configuration wasn't loaded"); + return -6; + } const char * l_datum_cmd_str = NULL; dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "datum", &l_datum_cmd_str); diff --git a/modules/service/stake/dap_chain_net_srv_stake_lock.c b/modules/service/stake/dap_chain_net_srv_stake_lock.c index a0ba00a627ef9bd5e1e0ff9eb410fa6c039f7e78..c4a00a6fd5a48944d2ef1d6b1c67d3fa53191a3a 100644 --- a/modules/service/stake/dap_chain_net_srv_stake_lock.c +++ b/modules/service/stake/dap_chain_net_srv_stake_lock.c @@ -343,7 +343,7 @@ static enum error_code s_cli_hold(int a_argc, char **a_argv, int a_arg_index, da static enum error_code s_cli_take(int a_argc, char **a_argv, int a_arg_index, dap_string_t *output_line) { const char *l_net_str, *l_ticker_str, *l_wallet_str, *l_tx_str, *l_tx_burning_str, *l_chain_str, *l_value_fee_str; - l_net_str = l_ticker_str = l_wallet_str = l_tx_str = l_tx_burning_str = l_chain_str = NULL; + l_net_str = l_ticker_str = l_wallet_str = l_tx_str = l_tx_burning_str = l_chain_str = l_value_fee_str = NULL; dap_chain_net_t *l_net = NULL; const char *l_wallets_path = dap_chain_wallet_get_path(g_config); char l_delegated_ticker_str[DAP_CHAIN_TICKER_SIZE_MAX] = {}; @@ -985,8 +985,14 @@ static bool s_stake_lock_callback_verificator(dap_ledger_t *a_ledger, dap_chain_ DAP_DEL_Z(str3); } - if (!EQUAL_256(l_blank_out_value, l_value_delegated)) - return false; + if (!EQUAL_256(l_blank_out_value, l_value_delegated)) { + // !!! A terrible legacy crutch, TODO !!! + SUM_256_256(l_value_delegated, GET_256_FROM_64(10), &l_value_delegated); + if (!EQUAL_256(l_blank_out_value, l_value_delegated)) { + log_it(L_ERROR, "Burning and delegated value mismatch"); + return false; + } + } } return true; diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c index 6528b2e4b5870cc8f885f2ff72ff75dba627044b..9fcd359d8f2aa7ac083ffc10136b6946889c2f8b 100644 --- a/modules/service/xchange/dap_chain_net_srv_xchange.c +++ b/modules/service/xchange/dap_chain_net_srv_xchange.c @@ -1156,7 +1156,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, c dap_cli_server_cmd_set_reply_text(a_str_reply, "Incorrect chain address"); return -14; } - if (dap_chain_addr_check_sum(l_addr) != 1 ) { + if (dap_chain_addr_check_sum(l_addr)) { dap_cli_server_cmd_set_reply_text(a_str_reply, "Incorrect chain address"); return -15; } diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c index 1139f1dac85a04db0afc3ac97f9a71f856d6e2d3..1dc1d60663d010b728d4ffaaa85730c040870bcf 100644 --- a/modules/type/blocks/dap_chain_cs_blocks.c +++ b/modules/type/blocks/dap_chain_cs_blocks.c @@ -20,7 +20,6 @@ You should have received a copy of the GNU General Public License along with any DAP SDK based project. If not, see <http://www.gnu.org/licenses/>. */ - #include <pthread.h> #include "dap_common.h" #include "dap_enc_base58.h" @@ -176,7 +175,7 @@ int dap_chain_cs_blocks_init() "\t\tDump block info\n\n" "block -net <net_name> -chain <chain_name> list [-from_hash <block_hash>] [-to_hash <block_hash>]" - "[-from_dt <datetime>] [-to_dt <datetime>] [-cert <priv_cert_name> -unspent]\n" + "[-from_dt <in YYMMDD>] [-to_dt <in YYMMDD>] [-cert <priv_cert_name> -unspent]\n" "\t\t List blocks\n\n" "Commission collect:\n" "block -net <net_name> -chain <chain_name> fee collect\n" @@ -613,13 +612,20 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply) } }break; case SUBCMD_LIST:{ - const char * l_cert_name = NULL; - bool l_unspent_fl = false; + const char * l_cert_name, *l_from_hash_name, *l_to_hash_name, *l_from_dt_name, *l_to_dt_name; + l_cert_name = l_from_hash_name = l_to_hash_name = l_from_dt_name = l_to_dt_name = NULL; + bool l_unspent_fl = false,l_hash_fl = false; size_t l_block_count = 0; dap_cert_t * l_cert = NULL; - dap_pkey_t * l_pub_key = NULL; + dap_pkey_t * l_pub_key = NULL; + dap_hash_fast_t l_from_hash; + dap_hash_fast_t l_to_hash; dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-cert", &l_cert_name); + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-from_hash", &l_from_hash_name); + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-to_hash", &l_to_hash_name); + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-from_dt", &l_from_dt_name); + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-to_dt", &l_to_dt_name); if(l_cert_name) { @@ -640,6 +646,39 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply) if(dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-unspent", NULL)) l_unspent_fl = true; } + if(l_to_hash_name){ + dap_chain_hash_fast_from_hex_str(l_to_hash_name, &l_to_hash); + } + if(l_from_hash_name){ + dap_chain_hash_fast_from_hex_str(l_from_hash_name, &l_from_hash); + } + if(l_from_dt_name){ + char l_from_data_month[3] = {l_from_dt_name[2], l_from_dt_name[3], 0}; + int l_from_time_month = atoi(l_from_data_month); + if (l_from_time_month < 1 || l_from_time_month > 12) + return -21; + char l_from_data_day[3] = {l_from_dt_name[4], l_from_dt_name[5], 0}; + int l_from_time_day = atoi(l_from_data_day); + if (l_from_time_day < 1 || l_from_time_day > 31) + return -21; + } + if(l_to_dt_name){ + char l_to_data_month[3] = {l_to_dt_name[2], l_to_dt_name[3], 0}; + int l_to_time_month = atoi(l_to_data_month); + if (l_to_time_month < 1 || l_to_time_month > 12) + return -21; + char l_to_data_day[3] = {l_to_dt_name[4], l_to_dt_name[5], 0}; + int l_to_time_day = atoi(l_to_data_day); + if (l_to_time_day < 1 || l_to_time_day > 31) + return -21; + } + + dap_time_t l_from_data = dap_time_from_str_simplified(l_from_dt_name); + struct tm *u; + time_t l_to_data = (time_t)dap_time_from_str_simplified(l_to_dt_name); + u = localtime(&l_to_data); + u->tm_mday += 1; + dap_time_t l_to_data_p_one_day = mktime(u); pthread_rwlock_rdlock(&PVT(l_blocks)->rwlock); dap_string_t * l_str_tmp = dap_string_new(NULL); @@ -650,6 +689,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply) dap_sign_t * l_sign = dap_chain_block_sign_get(l_block_cache->block, l_block_cache->block_size, 0); if(l_cert) { + l_sign = dap_chain_block_sign_get(l_block_cache->block, l_block_cache->block_size, 0); if(!dap_pkey_compare_with_sign(l_pub_key, l_sign)) continue; if(l_unspent_fl){ @@ -669,19 +709,34 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply) if(!fl_found) continue; } + } + if(l_to_dt_name && (l_to_data_p_one_day < l_ts)) + break; + if(dap_hash_fast_compare(&l_from_hash,&l_block_cache->block_hash)) + l_hash_fl = true; + if((l_from_hash_name && !l_hash_fl) || + (l_from_dt_name && (l_from_data > l_ts))) + { + if(l_to_hash_name && dap_hash_fast_compare(&l_to_hash,&l_block_cache->block_hash)) + break; + continue; } dap_string_append_printf(l_str_tmp,"\t%s: ts_create=%s", l_block_cache->block_hash_str, l_buf); l_block_count++; - } + if(l_to_hash_name && dap_hash_fast_compare(&l_to_hash,&l_block_cache->block_hash)) + break; + } if(l_cert){ dap_string_append_printf(l_str_tmp,"%s.%s: Have %"DAP_UINT64_FORMAT_U" blocks signed with %s certificate :\n", l_net->pub.name,l_chain->name,l_block_count,l_cert_name); } - else - dap_string_append_printf(l_str_tmp,"%s.%s: Have %"DAP_UINT64_FORMAT_U" blocks :\n", - l_net->pub.name,l_chain->name,PVT(l_blocks)->blocks_count); + else if(l_to_hash_name || l_from_hash_name || l_from_dt_name || l_to_dt_name){ + dap_string_append_printf(l_str_tmp,"%"DAP_UINT64_FORMAT_U" filtered blocks shown :\n",l_block_count); + } + dap_string_append_printf(l_str_tmp,"%s.%s: Have %"DAP_UINT64_FORMAT_U" blocks :\n", + l_net->pub.name,l_chain->name,PVT(l_blocks)->blocks_count); pthread_rwlock_unlock(&PVT(l_blocks)->rwlock); dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_str_tmp->str);