From a4e50a1da0f2937751e0cb65b7c5efcc11f540b0 Mon Sep 17 00:00:00 2001 From: "daniil.frolov" <daniil.frolov@demlabs.net> Date: Tue, 31 Dec 2024 03:59:34 +0000 Subject: [PATCH 1/3] port hotfix-14918 --- modules/wallet/dap_chain_wallet_cache.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/modules/wallet/dap_chain_wallet_cache.c b/modules/wallet/dap_chain_wallet_cache.c index 6f69cba636..48ab1057ce 100644 --- a/modules/wallet/dap_chain_wallet_cache.c +++ b/modules/wallet/dap_chain_wallet_cache.c @@ -685,12 +685,16 @@ static int s_save_tx_into_wallet_cache(dap_chain_t *a_chain, dap_chain_datum_tx_ dap_hash_fast_t l_prev_tx_hash = ((dap_chain_tx_in_t*)it->data)->header.tx_prev_hash; int l_prev_idx = ((dap_chain_tx_in_t*)it->data)->header.tx_out_prev_idx; if (dap_hash_fast_is_blank(&l_prev_tx_hash)) + continue; + dap_chain_datum_t *l_prev_datum = a_chain->callback_datum_find_by_hash(a_chain, &l_prev_tx_hash, NULL, NULL); + dap_chain_datum_tx_t *l_tx_prev = l_prev_datum ? (dap_chain_datum_tx_t *)(l_prev_datum->data) : NULL; + if (!l_tx_prev){ + log_it(L_ERROR, "Can't find previous transactions (hash=%s)", dap_hash_fast_to_str_static(&l_prev_tx_hash)); continue; - dap_chain_datum_tx_t *l_tx_prev = (dap_chain_datum_tx_t *)(a_chain->callback_datum_find_by_hash(a_chain, &l_prev_tx_hash, NULL, NULL)->data); - if (!l_tx_prev) - continue; - uint8_t* l_prev_item = dap_chain_datum_tx_item_get_nth(l_tx_prev, TX_ITEM_TYPE_OUT, l_prev_idx); - if (!l_prev_item) + } + uint8_t* l_prev_item = dap_chain_datum_tx_item_get_nth(l_tx_prev, TX_ITEM_TYPE_OUT_ALL, l_prev_idx); + if (!l_prev_item){ + log_it(L_ERROR, "Can't find out with index %d in transaction %s", l_prev_idx, dap_hash_fast_to_str_static(&l_prev_tx_hash)); continue; uint8_t l_out_type = *(uint8_t *)l_prev_item; switch(l_out_type){ @@ -928,8 +932,9 @@ static int s_save_tx_cache_for_addr(dap_chain_t *a_chain, dap_chain_addr_t *a_ad dap_chain_datum_tx_t *l_tx_prev = (dap_chain_datum_tx_t *)(a_chain->callback_datum_find_by_hash(a_chain, &l_prev_tx_hash, NULL, NULL)->data); if (!l_tx_prev) continue; - uint8_t* l_prev_item = dap_chain_datum_tx_item_get_nth(l_tx_prev, TX_ITEM_TYPE_OUT, l_prev_idx); - if (!l_prev_item) + uint8_t* l_prev_item = dap_chain_datum_tx_item_get_nth(l_tx_prev, TX_ITEM_TYPE_OUT_ALL, l_prev_idx); + if (!l_prev_item){ + log_it(L_ERROR, "Can't find out with index %d in transaction %s", l_prev_idx, dap_hash_fast_to_str_static(&l_prev_tx_hash)); continue; uint8_t l_out_type = *(uint8_t *)l_prev_item; switch(l_out_type){ -- GitLab From e047088beed3a6bb9bbfef8007434df6872f41bc Mon Sep 17 00:00:00 2001 From: "daniil.frolov" <daniil.frolov@demlabs.net> Date: Fri, 10 Jan 2025 15:45:26 +0300 Subject: [PATCH 2/3] Port hotfix-15003 --- modules/node-cli/dap_chain_node_cli_cmd_tx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/node-cli/dap_chain_node_cli_cmd_tx.c b/modules/node-cli/dap_chain_node_cli_cmd_tx.c index 7a00029d9d..b7edae2d56 100644 --- a/modules/node-cli/dap_chain_node_cli_cmd_tx.c +++ b/modules/node-cli/dap_chain_node_cli_cmd_tx.c @@ -1520,7 +1520,7 @@ int s_json_rpc_tx_parse_json(dap_chain_net_t *a_net, dap_chain_t *a_chain, json_ switch (l_item_type) { case TX_ITEM_TYPE_IN: { const char *l_json_item_token = s_json_get_text(l_json_item_obj, "token"); - if (dap_strcmp(l_json_item_token, l_native_token)){ + if (l_json_item_token && dap_strcmp(l_json_item_token, l_native_token)){ l_multichanel = true; l_main_token = l_json_item_token; } @@ -1634,7 +1634,7 @@ int s_json_rpc_tx_parse_json(dap_chain_net_t *a_net, dap_chain_t *a_chain, json_ } l_item = (const uint8_t*) l_out_item; if (l_item){ - if (!dap_strcmp(l_token, l_native_token)) + if (l_multichanel && !dap_strcmp(l_token, l_native_token)) SUM_256_256(l_value_need_fee, l_value, &l_value_need_fee); else SUM_256_256(l_value_need, l_value, &l_value_need); -- GitLab From a841d16a884b4eb07393069b1df80d21f48a8265 Mon Sep 17 00:00:00 2001 From: "daniil.frolov" <daniil.frolov@demlabs.net> Date: Fri, 10 Jan 2025 17:23:19 +0300 Subject: [PATCH 3/3] [+] Port 14958 --- modules/ledger/dap_chain_ledger_tx.c | 4 +- modules/ledger/include/dap_chain_ledger.h | 2 +- modules/mempool/dap_chain_mempool.c | 2 +- modules/node-cli/dap_chain_node_cli_cmd_tx.c | 2 +- .../dap_chain_net_srv_emit_delegate.c | 2 +- .../xchange/dap_chain_net_srv_xchange.c | 278 +++++++++++++----- modules/wallet/dap_chain_wallet_cache.c | 2 + 7 files changed, 217 insertions(+), 75 deletions(-) diff --git a/modules/ledger/dap_chain_ledger_tx.c b/modules/ledger/dap_chain_ledger_tx.c index 5a199adf42..b60246d71d 100644 --- a/modules/ledger/dap_chain_ledger_tx.c +++ b/modules/ledger/dap_chain_ledger_tx.c @@ -2190,7 +2190,7 @@ dap_hash_fast_t dap_ledger_get_first_chain_tx_hash(dap_ledger_t *a_ledger, dap_c return l_hash; } -dap_hash_fast_t dap_ledger_get_final_chain_tx_hash(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_subtype_t a_cond_type, dap_chain_hash_fast_t *a_tx_hash) +dap_hash_fast_t dap_ledger_get_final_chain_tx_hash(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_subtype_t a_cond_type, dap_chain_hash_fast_t *a_tx_hash, bool a_unspent_only) { dap_return_val_if_fail(a_ledger && a_tx_hash, (dap_hash_fast_t) {}); dap_chain_datum_tx_t *l_tx = NULL; @@ -2199,7 +2199,7 @@ dap_hash_fast_t dap_ledger_get_final_chain_tx_hash(dap_ledger_t *a_ledger, dap_c while (( l_tx = s_tx_find_by_hash(a_ledger, &l_hash, &l_item, false) )) { int l_out_num = 0; if (!dap_chain_datum_tx_out_cond_get(l_tx, a_cond_type, &l_out_num)) - return (dap_hash_fast_t) {}; + return a_unspent_only ? (dap_hash_fast_t){} : l_hash; else if (dap_hash_fast_is_blank(&l_item->out_metadata[l_out_num].tx_spent_hash_fast)) break; l_hash = l_item->out_metadata[l_out_num].tx_spent_hash_fast; diff --git a/modules/ledger/include/dap_chain_ledger.h b/modules/ledger/include/dap_chain_ledger.h index e68e2e8395..0814bb0318 100644 --- a/modules/ledger/include/dap_chain_ledger.h +++ b/modules/ledger/include/dap_chain_ledger.h @@ -426,7 +426,7 @@ uint256_t dap_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_chain_a dap_chain_datum_tx_t *dap_ledger_tx_find_by_hash(dap_ledger_t *a_ledger, const dap_chain_hash_fast_t *a_tx_hash); dap_chain_datum_tx_t *dap_ledger_tx_unspent_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash); -dap_hash_fast_t dap_ledger_get_final_chain_tx_hash(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_subtype_t a_cond_type, dap_chain_hash_fast_t *a_tx_hash); +dap_hash_fast_t dap_ledger_get_final_chain_tx_hash(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_subtype_t a_cond_type, dap_chain_hash_fast_t *a_tx_hash, bool a_unspent_only); dap_hash_fast_t dap_ledger_get_first_chain_tx_hash(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_subtype_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/mempool/dap_chain_mempool.c b/modules/mempool/dap_chain_mempool.c index 8555094d68..020fbf15e0 100644 --- a/modules/mempool/dap_chain_mempool.c +++ b/modules/mempool/dap_chain_mempool.c @@ -803,7 +803,7 @@ char* dap_chain_mempool_tx_create_cond_input(dap_chain_net_t *a_net, dap_chain_h *a_ret_status = DAP_CHAIN_MEMPOOL_RET_STATUS_WRONG_ADDR; return NULL; } - dap_chain_hash_fast_t l_tx_final_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, a_tx_prev_hash); + dap_chain_hash_fast_t l_tx_final_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, a_tx_prev_hash, true); if ( dap_hash_fast_is_blank(&l_tx_final_hash) ) { log_it(L_WARNING, "Requested conditional transaction is already used out"); if (a_ret_status) diff --git a/modules/node-cli/dap_chain_node_cli_cmd_tx.c b/modules/node-cli/dap_chain_node_cli_cmd_tx.c index b7edae2d56..e29ef0d277 100644 --- a/modules/node-cli/dap_chain_node_cli_cmd_tx.c +++ b/modules/node-cli/dap_chain_node_cli_cmd_tx.c @@ -3440,7 +3440,7 @@ int com_tx_cond_remove(int a_argc, char ** a_argv, void **a_json_arr_reply) } // get final tx - dap_hash_fast_t l_final_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, l_hash); + dap_hash_fast_t l_final_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, l_hash, true); dap_chain_datum_tx_t *l_final_tx = dap_ledger_tx_find_by_hash(l_ledger, &l_final_hash); if (!l_final_tx) { log_it(L_WARNING, "Only get final tx hash or tx is already used out."); diff --git a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c index 7046bcfb1b..0c3e66e756 100644 --- a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c +++ b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c @@ -316,7 +316,7 @@ static dap_chain_datum_tx_t *s_taking_tx_create(json_object *a_json_arr_reply, d if (!EQUAL_256(l_value_fee_items, l_fee_transfer)) m_tx_fail(ERROR_COMPOSE, "Can't compose the fee transaction input"); - dap_hash_fast_t l_final_tx_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_EMIT_DELEGATE, a_tx_in_hash); + dap_hash_fast_t l_final_tx_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_EMIT_DELEGATE, a_tx_in_hash, true); if (dap_hash_fast_is_blank(&l_final_tx_hash)) m_tx_fail(ERROR_FUNDS, "Nothing to emit (not enough funds)"); diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c index 78d77d04f2..d1dd081769 100644 --- a/modules/service/xchange/dap_chain_net_srv_xchange.c +++ b/modules/service/xchange/dap_chain_net_srv_xchange.c @@ -66,6 +66,7 @@ typedef struct xchange_tx_cache { dap_chain_hash_fast_t hash; dap_chain_datum_tx_t *tx; xchange_tx_type_t tx_type; + dap_chain_addr_t seller_addr; char buy_token[DAP_CHAIN_TICKER_SIZE_MAX]; char sell_token[DAP_CHAIN_TICKER_SIZE_MAX]; uint256_t rate; @@ -74,7 +75,6 @@ typedef struct xchange_tx_cache { dap_chain_net_srv_xchange_order_status_t order_status; uint256_t value; uint256_t value_ammount; - dap_chain_addr_t seller_addr; dap_hash_fast_t next_hash; } order_info; struct { @@ -111,7 +111,8 @@ const dap_chain_srv_uid_t c_dap_chain_net_srv_xchange_uid = { .uint64= DAP_CHAIN json_object *s_print_fee_json(dap_chain_net_id_t a_net_id); static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply); static dap_chain_net_srv_xchange_order_status_t s_tx_check_for_open_close(dap_chain_net_t * a_net, dap_chain_datum_tx_t * a_tx); -static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str, dap_chain_net_t * a_net, dap_chain_datum_tx_t * a_tx, +static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str, dap_chain_net_t * a_net, + dap_chain_addr_t *a_owner_addr, dap_chain_addr_t *a_buyer_addr, dap_chain_datum_tx_t * a_tx, dap_hash_fast_t *a_tx_hash, tx_opt_status_t a_filter_by_status, bool a_append_prev_hash, bool a_print_status,bool a_print_ts); dap_chain_net_srv_xchange_price_t *s_xchange_price_from_order(dap_chain_net_t *a_net, dap_chain_datum_tx_t *a_order, @@ -221,7 +222,7 @@ int dap_chain_net_srv_xchange_init() "\tShows transaction history for the selected order\n" "srv_xchange order status -net <net_name> -order <order_hash>\n" "\tShows current amount of unselled coins from the selected order and percentage of its completion\n" - "srv_xchange orders -net <net_name> [-status {opened|closed|all}] [-token_from <token_ticker>] [-token_to <token_ticker>] [-limit <limit>] [-offset <offset>]\n" + "srv_xchange orders -net <net_name> [-status {opened|closed|all}] [-token_from <token_ticker>] [-token_to <token_ticker>] [-addr <wallet_addr>] [-limit <limit>] [-offset <offset>]\n" "\tGet the exchange orders list within specified net name\n" "srv_xchange purchase -order <order hash> -net <net_name> -w <wallet_name> -value <value> -fee <value>\n" @@ -238,7 +239,7 @@ int dap_chain_net_srv_xchange_init() "\tGet average rate for token pair <token from>:<token to> from <From time> to <To time> \n" "srv_xchange token_pair -net <net_name> rate history -token_from <token_ticker> -token_to <token_ticker> [-time_from <From_time>] [-time_to <To_time>] [-limit <limit>] [-offset <offset>]\n" "\tPrint rate history for token pair <token from>:<token to> from <From time> to <To time>\n" - "\tAll times are in RFC822. For example: \"T7 Dec 2023 21:18:04\"\n" + "\tAll times are in RFC822. For example: \"7 Dec 2023 21:18:04\"\n" "srv_xchange enable\n" "\tEnable eXchange service\n" @@ -945,7 +946,7 @@ uint64_t dap_chain_net_srv_xchange_get_order_completion_rate(dap_chain_net_t *a_ return 0; } - dap_hash_fast_t l_last_tx_hash = dap_ledger_get_final_chain_tx_hash(a_net->pub.ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_price->tx_hash); + dap_hash_fast_t l_last_tx_hash = dap_ledger_get_final_chain_tx_hash(a_net->pub.ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_price->tx_hash, false); if ( dap_hash_fast_is_blank(&l_last_tx_hash) ){ log_it(L_ERROR, " Can't get last tx cond hash from order"); return 0; @@ -992,7 +993,7 @@ dap_chain_net_srv_xchange_order_status_t dap_chain_net_srv_xchange_get_order_sta return XCHANGE_ORDER_STATUS_UNKNOWN; } - dap_hash_fast_t l_last_tx_hash = dap_ledger_get_final_chain_tx_hash(a_net->pub.ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_price->tx_hash); + dap_hash_fast_t l_last_tx_hash = dap_ledger_get_final_chain_tx_hash(a_net->pub.ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_price->tx_hash, false); if ( dap_hash_fast_is_blank(&l_last_tx_hash) ) { log_it(L_ERROR, " Can't get last tx cond hash from order"); return XCHANGE_ORDER_STATUS_UNKNOWN; @@ -1212,7 +1213,7 @@ dap_chain_net_srv_xchange_price_t *s_xchange_price_from_order(dap_chain_net_t *a l_price->creator_addr = l_out_cond->subtype.srv_xchange.seller_addr; l_price->rate = l_out_cond->subtype.srv_xchange.rate; dap_hash_fast_t l_final_hash = dap_ledger_get_final_chain_tx_hash(a_net->pub.ledger, - DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_price->order_hash); + DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_price->order_hash, false); if ( !dap_hash_fast_is_blank(&l_final_hash) ) { l_price->tx_hash = l_final_hash; return l_price; @@ -1434,7 +1435,6 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v if(l_from_wallet_cache){ dap_string_t * l_str_reply = dap_string_new(""); - dap_chain_datum_tx_t *l_datum_tx = NULL; xchange_orders_cache_net_t* l_cache = NULL; if(s_xchange_cache_state == XCHANGE_CACHE_ENABLED){ l_cache = s_get_xchange_cache_by_net_id(l_net->pub.id); @@ -1444,8 +1444,8 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v } } dap_chain_wallet_cache_iter_t *l_iter = dap_chain_wallet_cache_iter_create(*l_addr); - l_datum_tx = dap_chain_wallet_cache_iter_get(l_iter, DAP_CHAIN_WALLET_CACHE_GET_FIRST); - while((l_datum_tx = dap_chain_wallet_cache_iter_get(l_iter, DAP_CHAIN_WALLET_CACHE_GET_NEXT)) != NULL) + for(dap_chain_datum_tx_t *l_datum_tx = dap_chain_wallet_cache_iter_get(l_iter, DAP_CHAIN_WALLET_CACHE_GET_FIRST); + l_datum_tx; l_datum_tx = dap_chain_wallet_cache_iter_get(l_iter, DAP_CHAIN_WALLET_CACHE_GET_NEXT)) { if (l_iter->ret_code != 0) continue; @@ -1455,10 +1455,16 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v HASH_FIND(hh, l_cache->cache, l_iter->cur_hash, sizeof(dap_hash_fast_t), l_item); if (!l_item) continue; + + if (s_string_append_tx_cond_info(l_str_reply, l_net, &l_item->seller_addr, + l_item->tx_type == TX_TYPE_EXCHANGE ? &l_item->tx_info.exchange_info.buyer_addr : NULL, + l_datum_tx, l_iter->cur_hash, TX_STATUS_ALL, true, true, false)) + + l_total++; + } else { + if (s_string_append_tx_cond_info(l_str_reply, l_net, NULL, NULL, l_datum_tx, l_iter->cur_hash, TX_STATUS_ALL, true, true, false)) + l_total++; } - - if (s_string_append_tx_cond_info(l_str_reply, l_net, l_datum_tx, l_iter->cur_hash, TX_STATUS_ALL, true, true, false)) - l_total++; } dap_chain_wallet_cache_iter_delete(l_iter); @@ -1479,7 +1485,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v dap_chain_datum_tx_t * l_tx_cur = (dap_chain_datum_tx_t*) l_tx_list_temp->data; dap_hash_fast_t l_hash = {}; dap_hash_fast(l_tx_cur, dap_chain_datum_tx_get_size(l_tx_cur), &l_hash); - if (s_string_append_tx_cond_info(l_str_reply, l_net, l_tx_cur, &l_hash, TX_STATUS_ALL, true, true, false)) + if (s_string_append_tx_cond_info(l_str_reply, l_net, NULL, NULL, l_tx_cur, &l_hash, TX_STATUS_ALL, true, true, false)) l_total++; l_tx_list_temp = l_tx_list_temp->next; } @@ -1517,7 +1523,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v dap_chain_datum_tx_t * l_tx_cur = (dap_chain_datum_tx_t*) l_tx_list_temp->data; dap_hash_fast_t l_hash = {}; dap_hash_fast(l_tx_cur, dap_chain_datum_tx_get_size(l_tx_cur), &l_hash); - s_string_append_tx_cond_info(l_str_reply, l_net, l_tx_cur, &l_hash, TX_STATUS_ALL, true, true, false); + s_string_append_tx_cond_info(l_str_reply, l_net, NULL, NULL, l_tx_cur, &l_hash, TX_STATUS_ALL, true, true, false); l_tx_list_temp = l_tx_list_temp->next; } dap_list_free(l_tx_list); @@ -1539,7 +1545,9 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v return -18; } while(l_item){ - s_string_append_tx_cond_info(l_str_reply, l_net, l_item->tx, &l_item->hash, TX_STATUS_ALL, true, true, false); + s_string_append_tx_cond_info(l_str_reply, l_net, &l_item->seller_addr, + l_item->tx_type == TX_TYPE_EXCHANGE ? &l_item->tx_info.exchange_info.buyer_addr : NULL, + l_item->tx, &l_item->hash, TX_STATUS_ALL, true, true, false); switch(l_item->tx_type){ case TX_TYPE_ORDER:{ l_cur_hash = l_item->tx_info.order_info.next_hash; @@ -1658,10 +1666,12 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v char* l_status_order = NULL; const char *l_token_buy = NULL; const char *l_token_sell = NULL; - const char *l_amount_coins_str = NULL, *l_amount_datoshi_str = NULL; + const char *l_owner_addr = NULL; + const char *l_amount_coins_str = NULL, *l_amount_datoshi_str = NULL, + *l_proposed_coins_str = NULL, *l_proposed_datoshi_str = NULL; uint64_t l_percent_completed = 0; dap_chain_datum_tx_t *l_tx = NULL; - uint256_t l_amount, l_rate; + uint256_t l_amount, l_rate, l_proposed; if (s_xchange_cache_state == XCHANGE_CACHE_ENABLED){ xchange_orders_cache_net_t* l_cache = NULL; @@ -1675,8 +1685,6 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v return -18; } - - switch (l_item->tx_info.order_info.order_status) { case XCHANGE_ORDER_STATUS_OPENED: @@ -1695,7 +1703,8 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v l_token_sell = l_item->sell_token; l_token_buy = l_item->buy_token; - + l_proposed = l_item->tx_info.order_info.value; + uint256_t l_completed = {}; SUBTRACT_256_256(l_item->tx_info.order_info.value, l_item->tx_info.order_info.value_ammount, &l_completed); DIV_256_COIN(l_completed, l_item->tx_info.order_info.value, &l_completed); @@ -1704,6 +1713,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v l_percent_completed = dap_chain_balance_to_coins_uint64(l_completed); l_amount_datoshi_str = dap_uint256_to_char(l_item->tx_info.order_info.value_ammount, &l_amount_coins_str); + l_owner_addr = dap_chain_addr_to_str_static(&l_item->seller_addr); } else { l_tx = dap_ledger_tx_find_by_hash(l_net->pub.ledger, &l_order_tx_hash); if (!l_tx){ @@ -1711,6 +1721,20 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v return -18; } + // Find SRV_XCHANGE in_cond item + int l_item_idx = 0; + byte_t *l_tx_item = dap_chain_datum_tx_item_get(l_tx, &l_item_idx, NULL, TX_ITEM_TYPE_IN_COND , NULL); + dap_chain_tx_in_cond_t * l_in_cond = l_tx_item ? (dap_chain_tx_in_cond_t *) l_tx_item : NULL; + int l_prev_cond_idx = 0; + dap_chain_datum_tx_t * l_prev_tx = l_in_cond ? dap_ledger_tx_find_by_hash(l_net->pub.ledger, &l_in_cond->header.tx_prev_hash) : NULL; + dap_chain_tx_out_cond_t *l_out_prev_cond_item = l_prev_tx ? dap_chain_datum_tx_out_cond_get(l_prev_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, + &l_prev_cond_idx) : NULL; + if(l_out_prev_cond_item){ + dap_cli_server_cmd_set_reply_text(a_str_reply, "It's not an order"); + return -18; + } + + dap_chain_tx_out_cond_t *l_out_cond = dap_chain_datum_tx_out_cond_get(l_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE , NULL); if (!l_out_cond || l_out_cond->header.srv_uid.uint64 != DAP_CHAIN_NET_SRV_XCHANGE_ID){ dap_cli_server_cmd_set_reply_text(a_str_reply, "It's not an order"); @@ -1726,7 +1750,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v dap_ledger_t * l_ledger = dap_ledger_by_net_name(l_net->pub.name); - dap_hash_fast_t l_last_tx_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_price->tx_hash); + dap_hash_fast_t l_last_tx_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_price->tx_hash, false); if( dap_hash_fast_is_blank(&l_last_tx_hash) ){ dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't get last tx cond hash from order"); return -18; @@ -1743,9 +1767,10 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v l_percent_completed = dap_chain_net_srv_xchange_get_order_completion_rate(l_net, l_order_tx_hash); - l_token_sell = l_price->token_sell; - l_token_buy = l_price->token_buy; - + l_token_sell = dap_strdup(l_price->token_sell); + l_token_buy = dap_strdup(l_price->token_buy); + + l_proposed = l_price->datoshi_sell; l_amount = l_out_cond_last_tx ? l_out_cond_last_tx->header.value : uint256_0; l_rate = l_price->rate; @@ -1761,6 +1786,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v l_status_order = "UNKNOWN"; break; }; + l_owner_addr = dap_chain_addr_to_str_static(&l_price->creator_addr); DAP_DEL_Z(l_price); } @@ -1769,22 +1795,29 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v l_amount_datoshi_str = dap_uint256_uninteger_to_char(l_amount); l_amount_coins_str = dap_uint256_decimal_to_char(l_amount); + l_proposed_coins_str = dap_uint256_decimal_to_char(l_proposed); + l_proposed_datoshi_str = dap_uint256_uninteger_to_char(l_proposed); l_cp_rate = dap_chain_balance_coins_print(l_rate); - dap_cli_server_cmd_set_reply_text(a_str_reply, "orderHash: %s\n ts_created: %s\n Status: %s, amount: %s (%s) %s, filled: %lu%%, rate (%s/%s): %s, net: %s\n\n", - l_order_hash_str, - l_tmp_buf, l_status_order, + dap_cli_server_cmd_set_reply_text(a_str_reply, "orderHash: %s\n ts_created: %s\n Status: %s, proposed: %s(%s) %s, amount: %s (%s) %s, filled: %lu%%, rate (%s/%s): %s, net: %s\n\n" + "owner addr: %s\n\n", l_order_hash_str, + l_tmp_buf, l_status_order, + l_proposed_coins_str ? l_proposed_coins_str : "0.0", + l_proposed_datoshi_str ? l_proposed_datoshi_str : "0.0", + l_token_sell, l_amount_coins_str ? l_amount_coins_str : "0.0", l_amount_datoshi_str ? l_amount_datoshi_str : "0", l_token_sell, l_percent_completed, l_token_buy, l_token_sell, l_cp_rate, - l_net->pub.name); + l_net->pub.name, l_owner_addr ? l_owner_addr : "unknown" ); DAP_DEL_Z(l_cp_rate); DAP_DEL_Z(l_amount_coins_str); DAP_DEL_Z(l_amount_datoshi_str); + DAP_DEL_Z(l_proposed_coins_str); + DAP_DEL_Z(l_proposed_datoshi_str); } break; default: { @@ -1905,7 +1938,7 @@ static dap_chain_net_srv_xchange_order_status_t s_tx_check_for_open_close(dap_ch dap_hash_fast_t l_tx_hash = {}; dap_hash_fast(a_tx, dap_chain_datum_tx_get_size(a_tx), &l_tx_hash); - dap_hash_fast_t l_last_tx_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_tx_hash); + dap_hash_fast_t l_last_tx_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_tx_hash, false); if ( dap_hash_fast_is_blank(&l_last_tx_hash) ) { log_it(L_WARNING,"Can't get last tx cond hash from order"); return XCHANGE_ORDER_STATUS_UNKNOWN; @@ -1932,8 +1965,8 @@ static dap_chain_net_srv_xchange_order_status_t s_tx_check_for_open_close(dap_ch * @param a_net * @param a_tx */ -static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str, - dap_chain_net_t * a_net, +static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str, dap_chain_net_t * a_net, + dap_chain_addr_t *a_owner_addr, dap_chain_addr_t *a_buyer_addr, dap_chain_datum_tx_t * a_tx, dap_hash_fast_t *a_tx_hash, tx_opt_status_t a_filter_by_status, bool a_print_prev_hash, bool a_print_status, bool a_print_ts) @@ -1981,7 +2014,14 @@ static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str, dap_string_append_printf(a_reply_str, " Status: %s,", l_is_closed ? "inactive" : "active"); dap_string_append_printf(a_reply_str, " proposed %s (%s) %s for exchange to %s,", l_amount_str, l_amount_datoshi_str, l_tx_input_ticker, l_out_cond_item->subtype.srv_xchange.buy_token); dap_string_append_printf(a_reply_str, " rate (%s/%s): %s, net: %s", l_out_cond_item->subtype.srv_xchange.buy_token, l_tx_input_ticker, l_rate_str, a_net->pub.name); + dap_chain_addr_t l_owner_addr = {}; + if (!a_owner_addr){ + l_owner_addr = l_out_cond_item ? l_out_cond_item->subtype.srv_xchange.seller_addr : (l_out_prev_cond_item ? l_out_prev_cond_item->subtype.srv_xchange.seller_addr : (dap_chain_addr_t){0}); + } else { + l_owner_addr = *a_owner_addr; + } + dap_string_append_printf(a_reply_str, "\nowner addr %s \n", dap_chain_addr_to_str_static(&l_owner_addr)); DAP_DELETE(l_rate_str); } break; case TX_TYPE_EXCHANGE:{ @@ -2034,6 +2074,34 @@ static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str, l_amount_datoshi_str, l_tx_input_ticker, a_net->pub.name); if (a_print_prev_hash) dap_string_append_printf(a_reply_str, "\n Prev cond: %s", l_tx_prev_cond_hash_str); + + dap_chain_tx_out_cond_subtype_t l_cond_type = l_out_cond_item ? l_out_cond_item->header.subtype : l_out_prev_cond_item->header.subtype; + dap_hash_fast_t l_order_hash = dap_ledger_get_first_chain_tx_hash(a_net->pub.ledger, l_cond_type, a_tx_hash); + if ( dap_hash_fast_is_blank(&l_order_hash) ) + l_order_hash = l_in_cond->header.tx_prev_hash; + char l_order_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; + dap_hash_fast_to_str(&l_order_hash, l_order_hash_str, sizeof(l_order_hash_str)); + dap_string_append_printf(a_reply_str, "\norder hash: %s\n", l_order_hash_str); + + dap_chain_addr_t l_owner_addr = {}; + if (!a_owner_addr){ + l_owner_addr = l_out_cond_item ? l_out_cond_item->subtype.srv_xchange.seller_addr : (l_out_prev_cond_item ? l_out_prev_cond_item->subtype.srv_xchange.seller_addr : (dap_chain_addr_t){0}); + } else { + l_owner_addr = *a_owner_addr; + } + dap_string_append_printf(a_reply_str, "owner addr: %s \n", dap_chain_addr_to_str_static(&l_owner_addr)); + + dap_chain_addr_t l_buyer_addr = {}; + if(!a_buyer_addr){ + dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(a_tx, NULL, NULL, TX_ITEM_TYPE_SIG, NULL); + dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_sig); + dap_enc_key_t *l_key_buyer = dap_sign_to_enc_key(l_sign); + dap_chain_addr_fill_from_key(&l_buyer_addr, l_key_buyer, a_net->pub.id); + dap_enc_key_delete(l_key_buyer); + } else + l_buyer_addr = *a_buyer_addr; + dap_string_append_printf(a_reply_str, "buyer addr: %s \n", dap_chain_addr_to_str_static(&l_buyer_addr)); + } break; case TX_TYPE_INVALIDATE:{ dap_chain_tx_in_cond_t * l_in_cond = (dap_chain_tx_in_cond_t *)dap_chain_datum_tx_item_get(a_tx, NULL, NULL, TX_ITEM_TYPE_IN_COND , NULL); @@ -2073,10 +2141,18 @@ static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str, char l_order_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; dap_hash_fast_to_str(&l_order_hash, l_order_hash_str, sizeof(l_order_hash_str)); - dap_string_append_printf(a_reply_str, " returned %s(%s) %s to owner from order %s", l_value_from_str, l_value_from_datoshi_str, l_tx_input_ticker, l_order_hash_str); + dap_string_append_printf(a_reply_str, " returned %s(%s) %s to owner from order %s\n", l_value_from_str, l_value_from_datoshi_str, l_tx_input_ticker, l_order_hash_str); if(a_print_prev_hash) dap_string_append_printf(a_reply_str, "\n Prev cond: %s", l_tx_prev_cond_hash_str); + dap_chain_addr_t l_owner_addr = {}; + if (!a_owner_addr){ + l_owner_addr = l_out_cond_item ? l_out_cond_item->subtype.srv_xchange.seller_addr : (l_out_prev_cond_item ? l_out_prev_cond_item->subtype.srv_xchange.seller_addr : (dap_chain_addr_t){0}); + } else { + l_owner_addr = *a_owner_addr; + } + dap_string_append_printf(a_reply_str, "owner addr %s \n", dap_chain_addr_to_str_static(&l_owner_addr)); + DAP_DELETE(l_value_from_str); DAP_DELETE(l_value_from_datoshi_str); } break; @@ -2115,15 +2191,18 @@ static int s_cli_srv_xchange_tx_list_addr(dap_chain_net_t *a_net, dap_time_t a_a if ( a_before && (l_datum_tx->header.ts_created > a_before) ) continue; - if (s_string_append_tx_cond_info(l_reply_str, a_net, l_datum_tx, &l_hash_curr, a_opt_status, false, true, true)) + if (s_string_append_tx_cond_info(l_reply_str, a_net, NULL, NULL, l_datum_tx, &l_hash_curr, a_opt_status, false, true, true)) l_tx_count++; } } else { - dap_chain_datum_tx_t *l_datum_tx = NULL; int l_ret_code = 0; - dap_chain_wallet_cache_iter_t *l_iter = dap_chain_wallet_cache_iter_create(*a_addr); - l_datum_tx = dap_chain_wallet_cache_iter_get(l_iter, DAP_CHAIN_WALLET_CACHE_GET_FIRST); - while( (l_datum_tx = dap_chain_wallet_cache_iter_get(l_iter, DAP_CHAIN_WALLET_CACHE_GET_NEXT)) != NULL) + dap_chain_wallet_cache_iter_t *l_iter = dap_chain_wallet_cache_iter_create(*a_addr);// TODO add check l_iter != NULL + if(!l_iter){ + log_it(L_ERROR, "Can't create iterator item for wallet %s", dap_chain_addr_to_str_static(a_addr)); + return -1; + } + for(dap_chain_datum_tx_t *l_datum_tx = dap_chain_wallet_cache_iter_get(l_iter, DAP_CHAIN_WALLET_CACHE_GET_FIRST); + l_datum_tx; l_datum_tx = dap_chain_wallet_cache_iter_get(l_iter, DAP_CHAIN_WALLET_CACHE_GET_NEXT)) { if (l_iter->ret_code != 0) continue; @@ -2134,7 +2213,7 @@ static int s_cli_srv_xchange_tx_list_addr(dap_chain_net_t *a_net, dap_time_t a_a if ( a_before && (l_datum_tx->header.ts_created > a_before) ) continue; - if (s_string_append_tx_cond_info(l_reply_str, a_net, l_datum_tx, &l_hash_curr, a_opt_status, false, true, true)) + if (s_string_append_tx_cond_info(l_reply_str, a_net, NULL, NULL, l_datum_tx, &l_hash_curr, a_opt_status, false, true, true)) l_tx_count++; } dap_chain_wallet_cache_iter_delete(l_iter); @@ -2156,7 +2235,6 @@ void s_tx_is_order_check(UNUSED_ARG dap_chain_net_t* a_net, dap_chain_datum_tx_t l_list_item->tx = a_tx; *l_tx_list_ptr = dap_list_append(*l_tx_list_ptr, l_list_item); } - } static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply) @@ -2247,6 +2325,12 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply) } } + dap_chain_addr_t *l_addr = NULL; + const char *l_addr_str = NULL; + dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-addr", &l_addr_str); + if (l_addr_str) + l_addr = dap_chain_addr_from_str(l_addr_str); + dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-token_to", &l_token_to_str); if(l_token_to_str){ dap_chain_datum_token_t * l_token_to_datum = dap_ledger_token_ticker_check( l_net->pub.ledger, l_token_to_str); @@ -2288,14 +2372,21 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply) dap_chain_net_srv_xchange_order_status_t l_order_status = XCHANGE_ORDER_STATUS_UNKNOWN; dap_hash_fast_t l_tx_hash = {}; uint64_t l_percent_completed = 0; - uint256_t l_amount = {}; - const char *l_amount_coins_str = NULL; - const char *l_amount_datoshi_str = NULL; + const char *l_owner_addr = NULL; + uint256_t l_amount = {}, l_proposed; + const char *l_amount_coins_str = NULL, *l_amount_datoshi_str = NULL, + *l_proposed_coins_str = NULL, *l_proposed_datoshi_str = NULL; if (s_xchange_cache_state == XCHANGE_CACHE_ENABLED){ xchange_tx_cache_t *l_item = (xchange_tx_cache_t*)it->data; if (l_item->tx_type != TX_TYPE_ORDER) continue; + + if (l_addr && dap_chain_addr_compare(&l_item->seller_addr, l_addr) == 0) + continue; + + l_owner_addr = dap_chain_addr_to_str_static(&l_item->seller_addr); + l_tx = l_item->tx; l_tx_hash = l_item->hash; memcpy(l_buy_token, l_item->buy_token, strlen(l_item->buy_token)); @@ -2303,6 +2394,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply) l_order_status = l_item->tx_info.order_info.order_status; l_rate = l_item->rate; l_amount = l_item->tx_info.order_info.value_ammount; + l_proposed = l_item->tx_info.order_info.value; uint256_t l_completed = {}; SUBTRACT_256_256(l_item->tx_info.order_info.value, l_item->tx_info.order_info.value_ammount, &l_completed); @@ -2324,12 +2416,14 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply) log_it(L_WARNING,"Can't create price from order"); continue; } + if(l_addr && dap_chain_addr_compare(&l_price->creator_addr, l_addr) == 0) + continue; memcpy(l_buy_token, l_price->token_buy, strlen(l_price->token_buy)); memcpy(l_sell_token, l_price->token_sell, strlen(l_price->token_sell)); dap_ledger_t * l_ledger = dap_ledger_by_net_name(l_net->pub.name); - dap_hash_fast_t l_last_tx_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_price->tx_hash); + dap_hash_fast_t l_last_tx_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_price->tx_hash, false); if ( dap_hash_fast_is_blank(&l_last_tx_hash) ) { log_it(L_WARNING,"Can't get last tx cond hash from order"); continue; @@ -2355,6 +2449,8 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply) l_rate = l_price->rate; l_percent_completed = dap_chain_net_srv_xchange_get_order_completion_rate(l_net, l_tx_hash); l_amount = l_out_cond_last_tx ? l_out_cond_last_tx->header.value : uint256_0; + l_owner_addr = dap_chain_addr_to_str_static(&l_price->creator_addr); + l_proposed = l_price->datoshi_sell; DAP_DEL_Z(l_price); } @@ -2389,19 +2485,27 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply) l_cp_rate = dap_uint256_decimal_to_char(l_rate); l_amount_datoshi_str = dap_uint256_uninteger_to_char(l_amount); l_amount_coins_str = dap_uint256_decimal_to_char(l_amount); - - dap_string_append_printf(l_reply_str, "orderHash: %s\n ts_created: %s\n Status: %s, amount: %s (%s) %s, filled: %lu%%, rate (%s/%s): %s, net: %s\n\n", l_tx_hash_str, + l_proposed_coins_str = dap_uint256_decimal_to_char(l_proposed); + l_proposed_datoshi_str = dap_uint256_uninteger_to_char(l_proposed); + + dap_string_append_printf(l_reply_str, "orderHash: %s\n ts_created: %s\n Status: %s, proposed: %s(%s) %s, amount: %s (%s) %s, filled: %lu%%, rate (%s/%s): %s, net: %s\n\n" + "owner addr: %s\n\n", l_tx_hash_str, l_tmp_buf, l_status_order_str, + l_proposed_coins_str ? l_proposed_coins_str : "0.0", + l_proposed_datoshi_str ? l_proposed_datoshi_str : "0", + l_sell_token, l_amount_coins_str ? l_amount_coins_str : "0.0", l_amount_datoshi_str ? l_amount_datoshi_str : "0", l_sell_token, l_percent_completed, l_buy_token, l_sell_token, l_cp_rate, - l_net->pub.name); + l_net->pub.name, l_owner_addr ? l_owner_addr : "unknown"); l_printed_orders_count++; DAP_DEL_Z(l_cp_rate); DAP_DEL_Z(l_amount_datoshi_str); DAP_DEL_Z(l_amount_coins_str); + DAP_DEL_Z(l_proposed_coins_str); + DAP_DEL_Z(l_proposed_datoshi_str); } if (s_xchange_cache_state == XCHANGE_CACHE_ENABLED){ dap_list_free(l_list); @@ -2563,7 +2667,9 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply) if (l_time[1] && l_item->tx->header.ts_created > l_time[1]) break; - if (s_string_append_tx_cond_info(l_reply_str, l_net, l_item->tx, &l_item->hash, l_opt_status, false, true, true)) + if (s_string_append_tx_cond_info(l_reply_str, l_net, &l_item->seller_addr, + l_item->tx_type == TX_TYPE_EXCHANGE ? &l_item->tx_info.exchange_info.buyer_addr : NULL, + l_item->tx, &l_item->hash, l_opt_status, false, true, true)) l_show_tx_nr++; } } else { @@ -2582,7 +2688,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply) dap_hash_fast_t l_hash = {}; dap_hash_fast(l_datum_tx, dap_chain_datum_tx_get_size(l_datum_tx), &l_hash); - if (s_string_append_tx_cond_info(l_reply_str, l_net, l_datum_tx, &l_hash, l_opt_status, false, true, true)) + if (s_string_append_tx_cond_info(l_reply_str, l_net, NULL, NULL, l_datum_tx, &l_hash, l_opt_status, false, true, true)) l_show_tx_nr++; l_datum_list = dap_list_next(l_datum_list); } @@ -2767,6 +2873,8 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply) size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 1000; size_t l_offset = l_offset_str ? strtoul(l_offset_str, NULL, 10) : 0; + uint256_t l_token_from_value = {}, l_token_to_value = {}; + dap_string_t *l_reply_str = dap_string_new(""); dap_list_t *l_list = NULL; dap_time_t l_time[2]; @@ -2794,11 +2902,6 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply) } size_t l_datum_num = dap_list_length(l_list); - - if (l_datum_num == 0){ - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find transactions"); - return -6; - } size_t l_arr_start = 0; size_t l_arr_end = l_datum_num; if (l_offset > 0) { @@ -2820,12 +2923,18 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply) const char * l_tx_sell_ticker = NULL; const char * l_tx_buy_ticker = NULL; + uint256_t l_token_curr_from_value = {}, l_token_curr_to_value = {}; + if (s_xchange_cache_state == XCHANGE_CACHE_ENABLED){ xchange_tx_cache_t* l_item = (xchange_tx_cache_t*)l_cur->data; l_tx_hash = l_item->hash; l_tx = l_item->tx; l_tx_sell_ticker = l_item->sell_token; l_tx_buy_ticker = l_item->buy_token; + if (l_item->tx_type == TX_TYPE_EXCHANGE){ + l_token_curr_from_value = l_item->tx_info.exchange_info.buy_value; + MULT_256_COIN(l_item->rate, l_item->tx_info.exchange_info.buy_value, &l_token_curr_to_value); + } } else { l_tx = (dap_chain_datum_tx_t*) ((dap_chain_datum_t*) l_cur->data)->data; if(!l_tx){ @@ -2834,19 +2943,26 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply) } dap_hash_fast(l_tx, dap_chain_datum_tx_get_size(l_tx), &l_tx_hash); l_tx_sell_ticker = dap_ledger_tx_get_token_ticker_by_hash(l_net->pub.ledger, &l_tx_hash); - dap_chain_tx_out_cond_t *l_out_cond_item = dap_chain_datum_tx_out_cond_get(l_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, NULL); - if(!l_out_cond_item){ - int l_item_idx = 0; - byte_t *l_tx_item = dap_chain_datum_tx_item_get(l_tx, &l_item_idx, NULL, TX_ITEM_TYPE_IN_COND , NULL); - dap_chain_tx_in_cond_t * l_in_cond = l_tx_item ? (dap_chain_tx_in_cond_t *) l_tx_item : NULL; - int l_prev_cond_idx = 0; - dap_chain_datum_tx_t * l_prev_tx = l_in_cond ? dap_ledger_tx_find_by_hash(l_net->pub.ledger, &l_in_cond->header.tx_prev_hash) : NULL; - dap_chain_tx_out_cond_t *l_out_prev_cond_item = l_prev_tx ? dap_chain_datum_tx_out_cond_get(l_prev_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, - &l_prev_cond_idx) : NULL; + dap_chain_tx_out_cond_t *l_out_cond_item = NULL; + dap_chain_tx_out_cond_t *l_out_prev_cond_item = NULL; + xchange_tx_type_t tx_type = dap_chain_net_srv_xchange_tx_get_type(l_net->pub.ledger, l_tx, &l_out_cond_item, NULL, &l_out_prev_cond_item); + + if(!l_out_cond_item && l_out_prev_cond_item){ l_tx_buy_ticker = l_out_prev_cond_item->subtype.srv_xchange.buy_token; - } else + if (tx_type == TX_TYPE_EXCHANGE){ + l_token_curr_from_value = l_out_prev_cond_item->header.value; + MULT_256_COIN(l_out_prev_cond_item->subtype.srv_xchange.rate, l_out_prev_cond_item->header.value, &l_token_curr_to_value); + } + } else if (l_out_cond_item) { l_tx_buy_ticker = l_out_cond_item->subtype.srv_xchange.buy_token; + if (tx_type == TX_TYPE_EXCHANGE){ + uint256_t l_b_buy_value = {}; + SUBTRACT_256_256(l_out_prev_cond_item->header.value, l_out_cond_item->header.value, &l_b_buy_value); + l_token_curr_from_value = l_b_buy_value; + MULT_256_COIN(l_out_cond_item->subtype.srv_xchange.rate, l_b_buy_value, &l_token_curr_to_value); + } + } } if (!l_tx_sell_ticker || strcmp(l_tx_sell_ticker, l_token_from_str)){ @@ -2868,14 +2984,34 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply) i_tmp++; - if(s_string_append_tx_cond_info(l_reply_str, l_net, l_tx, &l_tx_hash, TX_STATUS_ALL, false, false, true)) + if(s_string_append_tx_cond_info(l_reply_str, l_net, NULL, NULL, l_tx, &l_tx_hash, TX_STATUS_ALL, false, false, true)){ l_total++; + SUM_256_256(l_token_to_value, l_token_curr_to_value, &l_token_to_value); + SUM_256_256(l_token_from_value, l_token_curr_from_value, &l_token_from_value); + } l_cur = dap_list_next(l_cur); } dap_list_free(l_list); - dap_string_append_printf(l_reply_str, "Found %"DAP_UINT64_FORMAT_U" transactions\n", l_total); + dap_string_append_printf(l_reply_str, "Found %"DAP_UINT64_FORMAT_U" transactions\n", l_total); + + const char *l_token_from_value_coins_str = NULL, *l_token_from_value_datoshi_str = NULL, + *l_token_to_value_coins_str = NULL, *l_token_to_value_datoshi_str = NULL; + + l_token_from_value_datoshi_str = dap_chain_balance_datoshi_print(l_token_from_value); + l_token_from_value_coins_str = dap_chain_balance_coins_print(l_token_from_value); + l_token_to_value_datoshi_str = dap_chain_balance_datoshi_print(l_token_to_value); + l_token_to_value_coins_str = dap_chain_balance_coins_print(l_token_to_value); + + dap_string_append_printf(l_reply_str, "Traiding value:\n\t%s (%s) %s\n\t%s (%s) %s\n", l_token_from_value_coins_str, l_token_from_value_datoshi_str, l_token_from_str, + l_token_to_value_coins_str, l_token_to_value_datoshi_str, l_token_to_str); + + DAP_DEL_Z(l_token_from_value_datoshi_str); + DAP_DEL_Z(l_token_from_value_coins_str); + DAP_DEL_Z(l_token_to_value_datoshi_str); + DAP_DEL_Z(l_token_to_value_coins_str); + *a_str_reply = dap_string_free(l_reply_str, false); break; @@ -3200,11 +3336,11 @@ static void s_ledger_tx_add_notify(dap_ledger_t *a_ledger, dap_chain_datum_tx_t l_out_prev_cond_item->subtype.srv_xchange.buy_token, sizeof(l_cache->buy_token)); + l_cache->seller_addr = l_out_cond_item ? l_out_cond_item->subtype.srv_xchange.seller_addr : (l_out_prev_cond_item ? l_out_prev_cond_item->subtype.srv_xchange.seller_addr : (dap_chain_addr_t){0}); + if (l_tx_type == TX_TYPE_ORDER){ l_cache->rate = l_out_cond_item->subtype.srv_xchange.rate; - l_cache->tx_info.order_info.order_status = XCHANGE_ORDER_STATUS_OPENED; - l_cache->tx_info.order_info.seller_addr = l_out_cond_item->subtype.srv_xchange.seller_addr; l_cache->tx_info.order_info.value = l_out_cond_item->header.value; l_cache->tx_info.order_info.value_ammount = l_cache->tx_info.order_info.value; } else if (l_tx_type == TX_TYPE_EXCHANGE){ @@ -3220,7 +3356,11 @@ static void s_ledger_tx_add_notify(dap_ledger_t *a_ledger, dap_chain_datum_tx_t l_cache->tx_info.exchange_info.order_hash = s_get_order_from_cache(l_cache_net->cache, &l_cache->tx_info.exchange_info.prev_hash); dap_hash_fast_is_blank(&l_cache->tx_info.exchange_info.order_hash); - // l_cache->tx_info.exchange_info.buyer_addr = ; + dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(a_tx, NULL, NULL, TX_ITEM_TYPE_SIG, NULL); + dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_sig); + dap_enc_key_t *l_key_buyer = dap_sign_to_enc_key(l_sign); + dap_chain_addr_fill_from_key(&l_cache->tx_info.exchange_info.buyer_addr, l_key_buyer, a_ledger->net->pub.id); + dap_enc_key_delete(l_key_buyer); // find order in cache and change it state xchange_tx_cache_t* l_cache_order = NULL; HASH_FIND(hh, l_cache_net->cache, &l_cache->tx_info.exchange_info.order_hash, sizeof(dap_hash_fast_t), l_cache_order); diff --git a/modules/wallet/dap_chain_wallet_cache.c b/modules/wallet/dap_chain_wallet_cache.c index 48ab1057ce..ed79a7b294 100644 --- a/modules/wallet/dap_chain_wallet_cache.c +++ b/modules/wallet/dap_chain_wallet_cache.c @@ -696,6 +696,7 @@ static int s_save_tx_into_wallet_cache(dap_chain_t *a_chain, dap_chain_datum_tx_ if (!l_prev_item){ log_it(L_ERROR, "Can't find out with index %d in transaction %s", l_prev_idx, dap_hash_fast_to_str_static(&l_prev_tx_hash)); continue; + } uint8_t l_out_type = *(uint8_t *)l_prev_item; switch(l_out_type){ case TX_ITEM_TYPE_OUT_OLD: { @@ -936,6 +937,7 @@ static int s_save_tx_cache_for_addr(dap_chain_t *a_chain, dap_chain_addr_t *a_ad if (!l_prev_item){ log_it(L_ERROR, "Can't find out with index %d in transaction %s", l_prev_idx, dap_hash_fast_to_str_static(&l_prev_tx_hash)); continue; + } uint8_t l_out_type = *(uint8_t *)l_prev_item; switch(l_out_type){ case TX_ITEM_TYPE_OUT_OLD: { -- GitLab