diff --git a/modules/chain/dap_chain_ledger.c b/modules/chain/dap_chain_ledger.c index 984441e3bb77402f6925be4f394fb86c0310df55..b5d60c54813907f913f15a1b99eaf05a86dd377c 100644 --- a/modules/chain/dap_chain_ledger.c +++ b/modules/chain/dap_chain_ledger.c @@ -3320,7 +3320,7 @@ dap_chain_datum_tx_t* dap_chain_ledger_tx_find_by_hash(dap_ledger_t *a_ledger, d return s_find_datum_tx_by_hash(a_ledger, a_tx_hash, NULL); } -bool dap_chain_ledger_tx_spent_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash) +void *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); @@ -3805,7 +3805,13 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t // 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); - if (!l_tx_prev) { // Unchained transaction + 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; @@ -3822,7 +3828,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_OUT_ITEM_ALREADY_USED; char l_hash[DAP_CHAIN_HASH_FAST_STR_SIZE]; dap_chain_hash_fast_to_str(&l_spender, l_hash, sizeof(l_hash)); - debug_if(s_debug_more, L_INFO, "'Out' item of previous tx %s already spent by %s", l_tx_prev_hash_str, l_hash); + debug_if(s_debug_more, L_INFO, "'Out' item of previous tx %s already spent by %s", l_tx_prev_hash_str, l_hash); break; } diff --git a/modules/chain/include/dap_chain_ledger.h b/modules/chain/include/dap_chain_ledger.h index 1237447ab25ea09d679a8c8c259d77e73dd82842..304d8523d306676355eb25534afe0b5e857c6713 100644 --- a/modules/chain/include/dap_chain_ledger.h +++ b/modules/chain/include/dap_chain_ledger.h @@ -307,8 +307,8 @@ uint256_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_c * * return transaction, or NULL if transaction not found in the cache */ - dap_chain_datum_tx_t* dap_chain_ledger_tx_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash); -bool dap_chain_ledger_tx_spent_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash); +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_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 diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c index db58e64ee0867d74341dad443673cf7d19ee2efb..fc679140dda0ce37200515b8d74c79d70d7f46a4 100644 --- a/modules/net/dap_chain_node_cli_cmd_tx.c +++ b/modules/net/dap_chain_node_cli_cmd_tx.c @@ -162,8 +162,8 @@ char* dap_db_history_tx(dap_chain_hash_fast_t* a_tx_hash, dap_chain_t * a_chain, : dap_chain_hash_fast_to_str_new(&l_atom_hash); dap_ledger_t *l_ledger = dap_chain_net_by_id(a_chain->net_id)->pub.ledger; const char *l_tx_token_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, a_tx_hash); - dap_string_append_printf(l_str_out, "%s TX with atom %s (ret_code %d)\n", l_tx_token_ticker ? "ACCEPTED" : "DECLINED", - l_atom_hash_str, l_ret_code); + dap_string_append_printf(l_str_out, "%s TX with atom %s (ret_code %d - %s)\n", l_tx_token_ticker ? "ACCEPTED" : "DECLINED", + l_atom_hash_str, l_ret_code, dap_chain_ledger_tx_check_err_str(l_ret_code)); DAP_DELETE(l_atom_hash_str); dap_chain_datum_dump_tx(l_tx, l_tx_token_ticker, l_str_out, a_hash_out_type, a_tx_hash, a_chain->net_id); } else { @@ -212,8 +212,9 @@ static void s_tx_header_print(dap_string_t *a_str_out, dap_chain_tx_hash_process l_tx_hash_str = dap_enc_base58_encode_hash_to_str(a_tx_hash); l_atom_hash_str = dap_enc_base58_encode_hash_to_str(a_atom_hash); } - dap_string_append_printf(a_str_out, "%s TX hash %s with atom %s (ret code %d) \n\t%s", l_declined ? "DECLINED" : "ACCEPTED", - l_tx_hash_str, l_atom_hash_str, a_ret_code, l_time_str); + dap_string_append_printf(a_str_out, "%s TX hash %s with atom %s (ret code %d - %s) \n\t%s", l_declined ? "DECLINED" : "ACCEPTED", + l_tx_hash_str, l_atom_hash_str, a_ret_code, + dap_chain_ledger_tx_check_err_str(a_ret_code), l_time_str); DAP_DELETE(l_tx_hash_str); DAP_DELETE(l_atom_hash_str); } diff --git a/modules/service/vpn/dap_chain_net_srv_vpn.c b/modules/service/vpn/dap_chain_net_srv_vpn.c index 3fb1d659d608f75afc7a2f6be2b580bf85353ff8..8655a35d3e36396659d70ba51ede713500abf077 100644 --- a/modules/service/vpn/dap_chain_net_srv_vpn.c +++ b/modules/service/vpn/dap_chain_net_srv_vpn.c @@ -1592,9 +1592,9 @@ void s_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) return; } // check role - if (dap_chain_net_get_role(l_usage->net).enums < NODE_ROLE_MASTER) { + if (dap_chain_net_get_role(l_usage->net).enums > NODE_ROLE_MASTER) { log_it(L_ERROR, - "You can't provide service with ID %X in net %s. Node role should be not lower than master\n", + "You can't provide service with ID %"DAP_UINT64_FORMAT_X" in net %s. Node role should be not lower than master\n", l_usage->service->uid.uint64, l_usage->net->pub.name ); if (l_usage->client)