diff --git a/modules/consensus/esbocs/dap_chain_cs_esbocs.c b/modules/consensus/esbocs/dap_chain_cs_esbocs.c index d4f85b1345701fd16c555626eef346de6fdacb2c..01456b2e0b32e2965c642b5702e67a14ba6ff24e 100644 --- a/modules/consensus/esbocs/dap_chain_cs_esbocs.c +++ b/modules/consensus/esbocs/dap_chain_cs_esbocs.c @@ -970,8 +970,11 @@ static void s_session_round_finish(dap_chain_esbocs_session_t *a_session, dap_ch f_compare = dap_hash_fast_compare(&l_store->candidate_hash,&(PVT(a_session->esbocs)->candidate_hash)); if(s_session_candidate_to_chain(a_session, &l_store->precommit_candidate_hash, l_store->candidate, l_store->candidate_size)&&f_compare) { + dap_list_t *l_block_list = NULL; l_block_cache = dap_chain_block_cs_cache_get_by_hash(l_blocks, &l_precommit_candidate_hash); - dap_chain_mempool_tx_coll_fee_create(a_session->blocks_sign_key,(PVT(a_session->esbocs)->fee_addr),l_block_cache,PVT(a_session->esbocs)->minimum_fee,"hex"); + l_block_list = dap_list_append(l_block_list, l_block_cache); + dap_chain_mempool_tx_coll_fee_create(a_session->blocks_sign_key,(PVT(a_session->esbocs)->fee_addr),l_block_list,PVT(a_session->esbocs)->minimum_fee,"hex"); + dap_list_free(l_block_list); } } diff --git a/modules/mempool/dap_chain_mempool.c b/modules/mempool/dap_chain_mempool.c index e553c4bb0b4ca7649a3a78bb58b0a8184afaa540..cac1175df59a577a8ea3b6852fa57b50c0432fc3 100644 --- a/modules/mempool/dap_chain_mempool.c +++ b/modules/mempool/dap_chain_mempool.c @@ -276,7 +276,7 @@ char *dap_chain_mempool_tx_create(dap_chain_t * a_chain, dap_enc_key_t *a_key_fr * * return hash_tx Ok, , NULL other Error */ -char *dap_chain_mempool_tx_coll_fee_create(dap_enc_key_t *a_key_from,const dap_chain_addr_t* a_addr_to,dap_chain_block_cache_t *a_block_cache, +char *dap_chain_mempool_tx_coll_fee_create(dap_enc_key_t *a_key_from,const dap_chain_addr_t* a_addr_to,dap_list_t *a_block_list, uint256_t a_value_fee, const char *a_hash_out_type) { uint256_t l_value_to_items = {}; @@ -286,7 +286,7 @@ char *dap_chain_mempool_tx_coll_fee_create(dap_enc_key_t *a_key_from,const dap_c dap_chain_addr_t l_addr_fee = {}; dap_chain_t *l_chain = NULL; - l_chain = DAP_CHAIN_CS_BLOCKS(a_block_cache)->chain; + l_chain = DAP_CHAIN_CS_BLOCKS((dap_chain_block_cache_t *)a_block_list->data)->chain; bool l_net_fee_used = dap_chain_net_tx_get_fee(l_chain->net_id, &l_net_fee, &l_addr_fee); //add tx if (NULL == (l_tx = dap_chain_datum_tx_create())) { @@ -294,18 +294,20 @@ char *dap_chain_mempool_tx_coll_fee_create(dap_enc_key_t *a_key_from,const dap_c return NULL; } - dap_list_t *l_list_used_out = dap_chain_block_get_list_tx_cond_outs_with_val(l_chain->ledger,a_block_cache,&l_value_out); - if (!l_list_used_out) { - log_it(L_WARNING, "Not enough funds to transfer"); - dap_chain_datum_tx_delete(l_tx); - return NULL; - } - - //add 'in' items + for(dap_list_t *bl = a_block_list; bl; bl = bl->next) { - l_value_to_items = dap_chain_datum_tx_add_in_cond_item_list(&l_tx, l_list_used_out); - assert(EQUAL_256(l_value_to_items, l_value_out)); - dap_list_free_full(l_list_used_out, NULL); + uint256_t l_value_out_block = {}; + dap_chain_block_cache_t *l_block_cache = (dap_chain_block_cache_t *)bl->data; + dap_list_t *l_list_used_out = dap_chain_block_get_list_tx_cond_outs_with_val(l_chain->ledger,l_block_cache,&l_value_out_block); + if (!l_list_used_out) continue; + + //add 'in' items + { + l_value_to_items = dap_chain_datum_tx_add_in_cond_item_list(&l_tx, l_list_used_out); + assert(EQUAL_256(l_value_to_items, l_value_out_block)); + dap_list_free_full(l_list_used_out, NULL); + } + SUM_256_256(l_value_out, l_value_out_block, &l_value_out); } //add 'fee' items { @@ -328,7 +330,14 @@ char *dap_chain_mempool_tx_coll_fee_create(dap_enc_key_t *a_key_from,const dap_c return NULL; } } - SUBTRACT_256_256(l_value_out,l_value_pack,&l_value_out); + if(compare256(l_value_out,l_value_pack)!=-1) + SUBTRACT_256_256(l_value_out,l_value_pack,&l_value_out); + else + { + log_it(L_WARNING, "The transaction fee is greater than the sum of the block fees"); + dap_chain_datum_tx_delete(l_tx); + return NULL; + } } //add 'out' items @@ -363,7 +372,7 @@ int dap_chain_mempool_tx_create_massive( dap_chain_t * a_chain, dap_enc_key_t *a const char a_token_ticker[10], uint256_t a_value, uint256_t a_value_fee, size_t a_tx_num) { - // check valid param + // 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) || IS_ZERO_256(a_value) || !a_tx_num){ diff --git a/modules/mempool/include/dap_chain_mempool.h b/modules/mempool/include/dap_chain_mempool.h index 23596b542494a535f95ed310868b8c570e6511bf..db6b5146590868f2ed04a6db6cff1e384fe1e2da 100644 --- a/modules/mempool/include/dap_chain_mempool.h +++ b/modules/mempool/include/dap_chain_mempool.h @@ -76,5 +76,5 @@ char *dap_chain_mempool_base_tx_create(dap_chain_t *a_chain, dap_chain_hash_fast dap_chain_datum_token_emission_t *dap_chain_mempool_emission_get(dap_chain_t *a_chain, const char *a_emission_hash_str); dap_chain_datum_token_emission_t *dap_chain_mempool_datum_emission_extract(dap_chain_t *a_chain, byte_t *a_data, size_t a_size); -char *dap_chain_mempool_tx_coll_fee_create(dap_enc_key_t *a_key_from, const dap_chain_addr_t* a_addr_to, dap_chain_block_cache_t *a_block_cache, +char *dap_chain_mempool_tx_coll_fee_create(dap_enc_key_t *a_key_from, const dap_chain_addr_t* a_addr_to, dap_list_t *a_block_list, uint256_t a_value_fee, const char *a_hash_out_type); diff --git a/modules/type/blocks/dap_chain_block_cache.c b/modules/type/blocks/dap_chain_block_cache.c index 6ff3a0028a13729f7e7545ed8c21d8e45f590297..05fac01756cbbfcd384095bc066372cfa234af4c 100644 --- a/modules/type/blocks/dap_chain_block_cache.c +++ b/modules/type/blocks/dap_chain_block_cache.c @@ -189,7 +189,7 @@ dap_list_t * dap_chain_block_get_list_tx_cond_outs_with_val(dap_ledger_t *a_ledg dap_chain_tx_out_cond_t *l_tx_out_cond = NULL; uint256_t l_value_transfer = {}; HASH_ITER(hh, a_block_cache->tx_index, l_tx_cur, l_tmp) { - int l_out_idx_tmp = -1; + int l_out_idx_tmp = 0; if (NULL == (l_tx_out_cond = dap_chain_datum_tx_out_cond_get(l_tx_cur->tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE, &l_out_idx_tmp))) { diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c index bf75ee59c751861fad0cc92ae92934189603f4e5..0b74b8eb3fdc1f65db8143c6d00ebd6412d2707a 100644 --- a/modules/type/blocks/dap_chain_cs_blocks.c +++ b/modules/type/blocks/dap_chain_cs_blocks.c @@ -119,7 +119,7 @@ static dap_chain_atom_ptr_t *s_callback_atom_iter_get_links( dap_chain_atom_iter static dap_chain_atom_ptr_t *s_callback_atom_iter_get_lasts( dap_chain_atom_iter_t * a_atom_iter ,size_t *a_links_size, size_t ** a_lasts_size_ptr ); // Get list of linked blocks //Get list of hashes -static dap_chain_hash_fast_t **s_block_parse_str_list(const char * a_hash_str, size_t * a_hash_size); +static dap_list_t *s_block_parse_str_list(const char * a_hash_str,size_t * a_hash_size, dap_chain_t * l_chain); // Delete iterator static void s_callback_atom_iter_delete(dap_chain_atom_iter_t * a_atom_iter ); // Get the fisrt block @@ -602,12 +602,10 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply) const char * l_addr_str = NULL; const char * l_hash_out_type = NULL; const char * l_hash_str = NULL; - //const char * l_hash_mas_str = NULL; - uint256_t l_fee_value = {}; - size_t l_hashes_count = 0; - dap_chain_hash_fast_t **l_block_hashes = NULL; - dap_chain_block_t *l_block; + uint256_t l_fee_value = {}; + size_t l_hashes_count = 0; + dap_list_t *l_block_list = NULL; dap_chain_addr_t *l_addr = NULL; //arg_index++; @@ -670,25 +668,34 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply) dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block fee collect' requires parameter '-hashes'"); return -21; } - l_block_hashes = s_block_parse_str_list(l_hash_str, &l_hashes_count); + l_block_list = s_block_parse_str_list(l_hash_str, &l_hashes_count,l_chain); + if(!l_hashes_count){ dap_cli_server_cmd_set_reply_text(a_str_reply, "Block fee collection requires at least one hash to create a transaction"); return -22; } - //TODO compuound all blocks into a single collect tx - size_t l_block_size = 0; - l_block = (dap_chain_block_t*) dap_chain_get_atom_by_hash( l_chain, l_block_hashes[0], &l_block_size); - if(l_block){ - dap_chain_block_cache_t *l_block_cache = dap_chain_block_cs_cache_get_by_hash(l_blocks, l_block_hashes[0]); - if(l_block_cache) - { - dap_sign_t * 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)){ - dap_chain_mempool_tx_coll_fee_create(l_cert->enc_key,l_addr,l_block_cache,l_fee_value,l_hash_out_type); - } + //verification of signatures of all blocks + for (dap_list_t *bl = l_block_list; bl; bl = bl->next) { + dap_chain_block_cache_t *l_block_cache = (dap_chain_block_cache_t *)bl->data; + dap_sign_t * 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)){ + dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block fee collect' requires parameter '-hashes'"); + dap_list_free(l_block_list); + return -23; } } + char * l_hash_tx = dap_chain_mempool_tx_coll_fee_create(l_cert->enc_key,l_addr,l_block_list,l_fee_value,l_hash_out_type); + if (l_hash_tx) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Fee collect TX created succefully, hash=%s\n", l_hash_tx); + ret = 0; + } + else + dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't create fee collect TX\n"); + ret = -24; + + DAP_DELETE(l_hash_tx); + dap_list_free(l_block_list); }break; case SUBCMD_UNDEFINED: { dap_cli_server_cmd_set_reply_text(a_str_reply, @@ -700,40 +707,49 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply) return ret; } -static dap_chain_hash_fast_t **s_block_parse_str_list(const char * a_hash_str, size_t * a_hash_size) +static dap_list_t * s_block_parse_str_list(const char * a_hash_str,size_t * a_hash_size, dap_chain_t * l_chain) { + dap_list_t *l_block_list = NULL; char * l_hashes_tmp_ptrs = NULL; char * l_hashes_str_dup = dap_strdup(a_hash_str); char *l_hashes_str = strtok_r(l_hashes_str_dup, ",", &l_hashes_tmp_ptrs); + dap_chain_hash_fast_t l_hash_block; + dap_chain_block_t *l_block; + dap_chain_cs_blocks_t * l_blocks = DAP_CHAIN_CS_BLOCKS(l_chain); // First we just calc items while(l_hashes_str) { l_hashes_str = strtok_r(NULL, ",", &l_hashes_tmp_ptrs); (*a_hash_size)++; - } - dap_chain_hash_fast_t **l_hashes = DAP_NEW_Z_SIZE(dap_chain_hash_fast_t*, (*a_hash_size) * sizeof(dap_chain_hash_fast_t*) ); - + } strcpy(l_hashes_str_dup, a_hash_str); l_hashes_str = strtok_r(l_hashes_str_dup, ",", &l_hashes_tmp_ptrs); size_t l_hashes_pos = 0; - while(l_hashes_str) { l_hashes_str = dap_strstrip(l_hashes_str); - - dap_chain_hash_fast_from_hex_str(l_hashes_str, l_hashes[l_hashes_pos]); - - if(!l_hashes[l_hashes_pos]) { + if(dap_chain_hash_fast_from_hex_str(l_hashes_str, &l_hash_block)!=0) { log_it(L_WARNING,"Can't load hash %s",l_hashes_str); - DAP_DELETE(*l_hashes); - *l_hashes = NULL; *a_hash_size = 0; - break; + DAP_FREE(l_hashes_str_dup); + return NULL; + } + size_t l_block_size = 0; + l_block = (dap_chain_block_t*) dap_chain_get_atom_by_hash( l_chain, &l_hash_block, &l_block_size); + if(!l_block) + { + log_it(L_WARNING,"There aren't any block by this hash"); + *a_hash_size = 0; + DAP_FREE(l_hashes_str_dup); + return NULL; } + dap_chain_block_cache_t *l_block_cache = dap_chain_block_cs_cache_get_by_hash(l_blocks, &l_hash_block); + l_block_list = dap_list_append(l_block_list, l_block_cache); l_hashes_str = strtok_r(NULL, ",", &l_hashes_tmp_ptrs); + l_hashes_pos++; } DAP_FREE(l_hashes_str_dup); - return l_hashes; + return l_block_list; } /**