From 82f90a5bfea6d1f7d473b6197ba08e6cdb8bbfd0 Mon Sep 17 00:00:00 2001 From: "Constantin P." <papizh.konstantin@demlabs.net> Date: Wed, 12 Feb 2025 18:47:04 +0700 Subject: [PATCH 1/3] First attempt --- modules/net/dap_chain_ledger.c | 86 +++++++++++++++++----------------- 1 file changed, 42 insertions(+), 44 deletions(-) diff --git a/modules/net/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c index bff172b625..44707ef44e 100644 --- a/modules/net/dap_chain_ledger.c +++ b/modules/net/dap_chain_ledger.c @@ -3977,34 +3977,42 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger, return l_err_num; } - // 6. Compare sum of values in 'out' items in the current transaction and in the previous transa // Calculate the sum of values in 'out' items from the current transaction - bool l_multichannel = false; - if (HASH_COUNT(l_values_from_prev_tx) > 1) { - l_multichannel = true; - if (HASH_COUNT(l_values_from_prev_tx) == 2 && !l_main_ticker) { - HASH_FIND_STR(l_values_from_prev_tx, a_ledger->net->pub.native_ticker, l_value_cur); - if (l_value_cur) { - l_value_cur = l_value_cur->hh.next ? l_value_cur->hh.next : l_value_cur->hh.prev; - l_main_ticker = l_value_cur->token_ticker; - } - } - } else { + // 6. Compare sum of values in 'out' items + + switch ( HASH_COUNT(l_values_from_prev_tx) ) { + case 1: l_value_cur = DAP_NEW_Z(dap_ledger_tokenizer_t); if ( !l_value_cur ) { log_it(L_CRITICAL, "%s", c_error_memory_alloc); - l_err_num = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; if ( l_list_bound_items ) dap_list_free_full(l_list_bound_items, NULL); HASH_ITER(hh, l_values_from_prev_tx, l_value_cur, l_tmp) { HASH_DEL(l_values_from_prev_tx, l_value_cur); DAP_DELETE(l_value_cur); } - return l_err_num; + return DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; } dap_stpcpy(l_value_cur->token_ticker, l_token); + HASH_ADD_STR(l_values_from_cur_tx, token_ticker, l_value_cur); if (!l_main_ticker) l_main_ticker = l_value_cur->token_ticker; - HASH_ADD_STR(l_values_from_cur_tx, token_ticker, l_value_cur); + break; + case 2: + if (l_main_ticker) + break; + HASH_FIND_STR(l_values_from_prev_tx, a_ledger->net->pub.native_ticker, l_value_cur); + if (l_value_cur) { + l_value_cur = l_value_cur->hh.next ? l_value_cur->hh.next : l_value_cur->hh.prev; + l_main_ticker = l_value_cur->token_ticker; + } + break; + default: + dap_list_free_full(l_list_bound_items, NULL); + HASH_ITER(hh, l_values_from_prev_tx, l_value_cur, l_tmp) { + HASH_DEL(l_values_from_prev_tx, l_value_cur); + DAP_DELETE(l_value_cur); + } + return DAP_LEDGER_TX_CHECK_NO_MAIN_TICKER; } dap_chain_net_srv_stake_item_t *l_key_item = NULL; @@ -4025,7 +4033,8 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger, switch ( *it ) { case TX_ITEM_TYPE_OUT_OLD: { dap_chain_tx_out_old_t *l_tx_out = (dap_chain_tx_out_old_t*)it; - if (l_multichannel) { // token ticker is mandatory for multichannel transactions + l_token = l_main_ticker; + if (!l_token) { l_err_num = DAP_LEDGER_TX_CHECK_NO_MAIN_TICKER; break; } @@ -4035,13 +4044,10 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger, } break; case TX_ITEM_TYPE_OUT: { // 256 dap_chain_tx_out_t *l_tx_out = (dap_chain_tx_out_t *)it; - if (l_multichannel) { // token ticker is mandatory for multichannel transactions - if (l_main_ticker) - l_token = l_main_ticker; - else { - l_err_num = DAP_LEDGER_TX_CHECK_NO_MAIN_TICKER; - break; - } + l_token = l_main_ticker; + if (!l_token) { + l_err_num = DAP_LEDGER_TX_CHECK_NO_MAIN_TICKER; + break; } l_value = l_tx_out->header.value; l_tx_out_to = l_tx_out->addr; @@ -4056,16 +4062,10 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger, } break; case TX_ITEM_TYPE_OUT_COND: { dap_chain_tx_out_cond_t *l_tx_out = (dap_chain_tx_out_cond_t *)it; - if (l_multichannel) { - if (l_tx_out->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE) - l_token = (char *)a_ledger->net->pub.native_ticker; - else if (l_main_ticker) - l_token = l_main_ticker; - else { - log_it(L_WARNING, "No conditional output support for multichannel transaction"); - l_err_num = DAP_LEDGER_TX_CHECK_NO_MAIN_TICKER; - break; - } + l_token = l_tx_out->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE ? a_ledger->net->pub.native_ticker : l_main_ticker; + if (!l_token) { + l_err_num = DAP_LEDGER_TX_CHECK_NO_MAIN_TICKER; + break; } l_value = l_tx_out->header.value; l_list_tx_out = dap_list_append(l_list_tx_out, l_tx_out); @@ -4093,18 +4093,16 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger, if (l_err_num) break; - if (l_multichannel) { - HASH_FIND_STR(l_values_from_cur_tx, l_token, l_value_cur); - if (!l_value_cur) { - l_value_cur = DAP_NEW_Z(dap_ledger_tokenizer_t); - if ( !l_value_cur ) { - log_it(L_CRITICAL, "%s", c_error_memory_alloc); - l_err_num = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; - break; - } - strcpy(l_value_cur->token_ticker, l_token); - HASH_ADD_STR(l_values_from_cur_tx, token_ticker, l_value_cur); + HASH_FIND_STR(l_values_from_cur_tx, l_token, l_value_cur); + if (!l_value_cur) { + l_value_cur = DAP_NEW_Z(dap_ledger_tokenizer_t); + if ( !l_value_cur ) { + log_it(L_CRITICAL, "%s", c_error_memory_alloc); + l_err_num = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY; + break; } + strcpy(l_value_cur->token_ticker, l_token); + HASH_ADD_STR(l_values_from_cur_tx, token_ticker, l_value_cur); } if (SUM_256_256(l_value_cur->sum, l_value, &l_value_cur->sum)) { debug_if(s_debug_more, L_WARNING, "Sum result overflow for tx_add_check with ticker %s", -- GitLab From 2b8bd108e3125e761f76d23df942bc36dd483f9b Mon Sep 17 00:00:00 2001 From: "Constantin P." <papizh.konstantin@demlabs.net> Date: Thu, 13 Feb 2025 20:49:59 +0700 Subject: [PATCH 2/3] Multichannel ajustments --- modules/net/dap_chain_ledger.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/net/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c index 44707ef44e..6a6e0da932 100644 --- a/modules/net/dap_chain_ledger.c +++ b/modules/net/dap_chain_ledger.c @@ -3998,6 +3998,7 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger, l_main_ticker = l_value_cur->token_ticker; break; case 2: + case 3: if (l_main_ticker) break; HASH_FIND_STR(l_values_from_prev_tx, a_ledger->net->pub.native_ticker, l_value_cur); @@ -4134,7 +4135,7 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger, } // Check for transaction consistency (sum(ins) == sum(outs)) - if (!l_err_num) { + if ( !l_err_num && !s_check_hal(a_ledger, a_tx_hash) ) { HASH_ITER(hh, l_values_from_prev_tx, l_value_cur, l_tmp) { HASH_FIND_STR(l_values_from_cur_tx, l_value_cur->token_ticker, l_res); if (!l_res || !EQUAL_256(l_res->sum, l_value_cur->sum) ) { -- GitLab From 8486bb0efd169c5b256f94fd072eb151e2859f6c Mon Sep 17 00:00:00 2001 From: "Constantin P." <papizh.konstantin@demlabs.net> Date: Fri, 14 Feb 2025 02:08:48 +0700 Subject: [PATCH 3/3] Ledger test fix --- modules/chain/tests/dap_chain_ledger_tests.c | 29 ++++++++------------ 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/modules/chain/tests/dap_chain_ledger_tests.c b/modules/chain/tests/dap_chain_ledger_tests.c index 0a2bd59726..292d0dc33c 100644 --- a/modules/chain/tests/dap_chain_ledger_tests.c +++ b/modules/chain/tests/dap_chain_ledger_tests.c @@ -102,22 +102,17 @@ dap_chain_datum_tx_t *dap_ledger_test_create_datum_base_tx( uint256_t l_value_need = a_emi->hdr.value; dap_chain_datum_tx_t *l_tx = DAP_NEW_Z_SIZE(dap_chain_datum_tx_t, sizeof(dap_chain_datum_tx_t)); l_tx->header.ts_created = time(NULL); - dap_chain_tx_in_ems_t *l_in_ems = DAP_NEW_Z(dap_chain_tx_in_ems_t); - l_in_ems->header.type = TX_ITEM_TYPE_IN_EMS; - l_in_ems->header.token_emission_chain_id.uint64 = 0; - l_in_ems->header.token_emission_hash = *l_emi_hash; - strcpy(l_in_ems->header.ticker, a_emi->hdr.ticker); - SUBTRACT_256_256(l_value_need, l_value_fee, &l_value_need); - dap_chain_tx_out_t *l_out = dap_chain_datum_tx_item_out_create(&a_addr_to, l_value_need); - dap_chain_tx_out_cond_t *l_tx_out_fee = dap_chain_datum_tx_item_out_cond_create_fee(l_value_fee); - dap_chain_datum_tx_add_item(&l_tx, (const uint8_t*) l_in_ems); - dap_chain_datum_tx_add_item(&l_tx, (const uint8_t*) l_out); - dap_chain_datum_tx_add_item(&l_tx, (const uint8_t*) l_tx_out_fee); + dap_chain_tx_in_ems_t l_in_ems = { .header.type = TX_ITEM_TYPE_IN_EMS, .header.token_emission_chain_id.uint64 = 0, .header.token_emission_hash = *l_emi_hash}; + strcpy(l_in_ems.header.ticker, a_emi->hdr.ticker); + dap_chain_datum_tx_add_item(&l_tx, (const uint8_t*) &l_in_ems); + if ( !strcmp(l_in_ems.header.ticker, s_token_ticker) ) { + SUBTRACT_256_256(l_value_need, l_value_fee, &l_value_need); + dap_chain_datum_tx_add_out_item(&l_tx, &a_addr_to, l_value_need); + dap_chain_datum_tx_add_fee_item(&l_tx, l_value_fee); + } else { + dap_chain_datum_tx_add_out_ext_item(&l_tx, &a_addr_to, l_value_need, l_in_ems.header.ticker); + } dap_chain_datum_tx_add_sign_item(&l_tx, a_cert->enc_key); - DAP_DEL_Z(l_in_ems); - DAP_DEL_Z(l_out); - DAP_DEL_Z(l_tx_out_fee); - return l_tx; } @@ -871,12 +866,12 @@ void dap_ledger_test_write_back_list(dap_ledger_t *a_ledger, dap_cert_t *a_cert, DAP_DELETE(l_ledger_tx_add_str); dap_hash_fast_t l_tx_addr4_hash = {0}; dap_chain_datum_tx_t *l_tx_to_addr4 = dap_ledger_test_create_tx(l_addr_1->enc_key, &l_btx_addr1_hash, - l_addr_4->addr, dap_chain_uint256_from(s_total_supply-s_fee)); + l_addr_4->addr, dap_chain_uint256_from(s_total_supply/*-s_fee*/)); dap_hash_fast(l_tx_to_addr4, dap_chain_datum_tx_get_size(l_tx_to_addr4), &l_tx_addr4_hash); dap_assert_PIF(!dap_ledger_tx_add(a_ledger, l_tx_to_addr4, &l_tx_addr4_hash, false, NULL), "Can't add transaction to address from white list in ledger"); dap_chain_datum_tx_t *l_tx_to_addr3 = dap_ledger_test_create_tx(l_addr_4->enc_key, &l_tx_addr4_hash, - l_addr_3->addr, dap_chain_uint256_from(s_total_supply-s_fee)); + l_addr_3->addr, dap_chain_uint256_from(s_total_supply/*-s_fee*/)); dap_hash_fast_t l_tx_addr3_hash = {0}; dap_hash_fast(l_tx_to_addr3, dap_chain_datum_tx_get_size(l_tx_to_addr3), &l_tx_addr3_hash); int res_add_tx = dap_ledger_tx_add(a_ledger, l_tx_to_addr3, &l_tx_addr3_hash, false, NULL); -- GitLab