diff --git a/modules/mempool/dap_chain_mempool.c b/modules/mempool/dap_chain_mempool.c index 4f8528e213e06130a5f563a17be03ee843c87b11..57f1d5602ff6af40756a6c0ef6aae64ef4edebc5 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/net/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c index 0c994335022dd15928cd99ebe6e2ff090c47c661..e3d7e092756367532273ec343c85792f6454e693 100644 --- a/modules/net/dap_chain_ledger.c +++ b/modules/net/dap_chain_ledger.c @@ -3164,7 +3164,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_chain_hash_fast_t l_hash = { }; dap_return_val_if_fail(a_ledger && a_tx_hash && !dap_hash_fast_is_blank(a_tx_hash), l_hash); @@ -3174,7 +3174,7 @@ dap_hash_fast_t dap_ledger_get_final_chain_tx_hash(dap_ledger_t *a_ledger, dap_c while (( l_tx = dap_ledger_tx_find_datum_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->cache_data.tx_hash_spent_fast[l_out_num])) ) break; l_hash = l_item->cache_data.tx_hash_spent_fast[l_out_num]; diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c index aa4c7cc2ebe12b3cc4ccc257f2240befcd2df8bd..1e68cd41bf9150d656a1d1ef39705a3ca2699a0e 100644 --- a/modules/net/dap_chain_node_cli_cmd.c +++ b/modules/net/dap_chain_node_cli_cmd.c @@ -5477,7 +5477,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/net/include/dap_chain_ledger.h b/modules/net/include/dap_chain_ledger.h index b0b3456a2aa0e3cbd696e18bd52a75f7043797ed..b7caf03be81ef1cd73e7dd2679b4b56af1895072 100644 --- a/modules/net/include/dap_chain_ledger.h +++ b/modules/net/include/dap_chain_ledger.h @@ -403,7 +403,7 @@ dap_chain_datum_tx_t *dap_ledger_tx_find_datum_by_hash( dap_ledger_t *a_ledger, #define dap_ledger_tx_unspent_find_by_hash(a_ledger, a_tx_hash) \ dap_ledger_tx_find_datum_by_hash(a_ledger, a_tx_hash, NULL, true) -dap_hash_fast_t dap_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); +dap_hash_fast_t dap_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, bool a_unspent_only); dap_hash_fast_t dap_ledger_get_first_chain_tx_hash(dap_ledger_t *a_ledger, dap_chain_datum_tx_t * a_tx, dap_chain_tx_out_cond_subtype_t a_cond_type); // Get the transaction in the cache by the addr in out item 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 56ee6499627333c9b8311f41cb2a8120121c795e..3df74f13687bcbaa4f17a068c3d1809ae68154db 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 @@ -319,7 +319,7 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_obje 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 4473edadad9b2b265f6ca4afc30dffdb8c516eb2..c38d0f19f14d9484f49af4277c7ae8f38a858f55 100644 --- a/modules/service/xchange/dap_chain_net_srv_xchange.c +++ b/modules/service/xchange/dap_chain_net_srv_xchange.c @@ -69,6 +69,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; @@ -77,7 +78,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 { @@ -119,7 +119,7 @@ static int s_callback_response_success(dap_chain_net_srv_t *a_srv, uint32_t a_us static int s_callback_response_error(dap_chain_net_srv_t *a_srv, uint32_t a_usage_id, dap_chain_net_srv_client_remote_t *a_srv_client, const void *a_data, size_t a_data_size); static int s_callback_receipt_next_success(dap_chain_net_srv_t *a_srv, uint32_t a_usage_id, dap_chain_net_srv_client_remote_t *a_srv_client, const void *a_data, size_t a_data_size); 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, 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); +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, dap_hash_fast_t *a_order_hash, uint256_t *a_fee, bool a_ret_is_invalid); static void s_ledger_tx_add_notify(void *a_arg, dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, dap_chan_ledger_notify_opcodes_t a_opcode); @@ -224,7 +224,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" @@ -241,7 +241,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" @@ -973,7 +973,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,20 +992,8 @@ uint64_t dap_chain_net_srv_xchange_get_order_completion_rate(dap_chain_net_t *a_ SUBTRACT_256_256(l_out_cond->header.value, l_out_cond_last_tx->header.value, &l_percent_completed); DIV_256_COIN(l_percent_completed, l_out_cond->header.value, &l_percent_completed); MULT_256_COIN(l_percent_completed, dap_chain_coins_to_balance("100.0"), &l_percent_completed); - } else { - // 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(a_net->pub.ledger, l_last_tx, NULL, NULL, &l_out_prev_cond_item); - // if (tx_type == TX_TYPE_EXCHANGE){ - // l_percent_completed = l_out_cond->header.value; - // DIV_256_COIN(l_percent_completed, l_out_cond->header.value, &l_percent_completed); - // MULT_256_COIN(l_percent_completed, dap_chain_coins_to_balance("100.0"), &l_percent_completed); - // } else if (tx_type == TX_TYPE_INVALIDATE){ - // SUBTRACT_256_256(l_out_cond->header.value, l_out_prev_cond_item->header.value, &l_percent_completed); - // DIV_256_COIN(l_percent_completed, l_out_cond->header.value, &l_percent_completed); - // MULT_256_COIN(l_percent_completed, dap_chain_coins_to_balance("100.0"), &l_percent_completed); - // } + } else l_percent_completed = dap_chain_coins_to_balance("100.0"); - } return dap_chain_balance_to_coins_uint64(l_percent_completed); } @@ -1030,7 +1018,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; @@ -1251,7 +1239,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; @@ -1470,7 +1458,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); @@ -1480,21 +1467,28 @@ 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; + if(s_xchange_cache_state == XCHANGE_CACHE_ENABLED){ xchange_tx_cache_t* l_item = NULL; 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); @@ -1515,7 +1509,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; } @@ -1553,7 +1547,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); @@ -1577,7 +1571,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; @@ -1696,10 +1692,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; @@ -1713,6 +1711,11 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v return -18; } + if (l_item->tx_type != TX_TYPE_ORDER){ + dap_cli_server_cmd_set_reply_text(a_str_reply, "It's not an order"); + return -18; + } + switch (l_item->tx_info.order_info.order_status) { case XCHANGE_ORDER_STATUS_OPENED: @@ -1731,6 +1734,7 @@ 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); @@ -1740,6 +1744,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){ @@ -1747,6 +1752,19 @@ 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"); @@ -1762,7 +1780,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; @@ -1779,9 +1797,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; @@ -1797,6 +1816,8 @@ 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); } @@ -1805,21 +1826,31 @@ 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_to_coins(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" ); + if (s_xchange_cache_state != XCHANGE_CACHE_ENABLED){ + DAP_DEL_Z(l_token_sell); + DAP_DEL_Z(l_token_buy); + } 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: { @@ -1940,7 +1971,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; @@ -1967,8 +1998,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) @@ -2015,6 +2046,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; @@ -2068,6 +2107,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, a_tx, l_cond_type); + 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); @@ -2107,10 +2174,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; @@ -2149,15 +2224,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) + 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; @@ -2168,7 +2246,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_iter->cur_hash, a_opt_status, false, true, true)) l_tx_count++; } dap_chain_wallet_cache_iter_delete(l_iter); @@ -2189,7 +2267,7 @@ void s_tx_is_order_check(UNUSED_ARG dap_chain_net_t* a_net, dap_chain_datum_tx_t l_list_item->hash = *a_tx_hash; l_list_item->tx = a_tx; *l_tx_list_ptr = dap_list_append(*l_tx_list_ptr, l_list_item); - } + } } @@ -2297,6 +2375,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); + uint64_t l_printed_orders_count = 0; const char *l_limit_str = NULL; const char *l_offset_str = NULL; @@ -2329,14 +2413,20 @@ 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)); @@ -2344,7 +2434,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); DIV_256_COIN(l_completed, l_item->tx_info.order_info.value, &l_completed); @@ -2365,12 +2455,16 @@ 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; @@ -2396,6 +2490,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); } @@ -2431,19 +2527,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); + 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, amount: %s (%s) %s, filled: %lu%%, rate (%s/%s): %s, net: %s\n\n", l_tx_hash_str, + 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); @@ -2611,11 +2715,13 @@ 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 { - dap_list_t *l_datum_list0 = dap_chain_datum_list(l_net, NULL, s_filter_tx_list, l_time); + dap_list_t *l_datum_list0 = dap_chain_datum_list(l_net, NULL, s_filter_tx_list, l_time); size_t l_datum_num = dap_list_length(l_datum_list0); if (l_datum_num > 0) { @@ -2630,7 +2736,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); } @@ -2815,6 +2921,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]; @@ -2843,10 +2951,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) { @@ -2867,12 +2971,19 @@ 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){ @@ -2881,21 +2992,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); + } + } } @@ -2919,13 +3035,36 @@ 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); + + 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_print(l_token_from_value); + l_token_from_value_coins_str = dap_chain_balance_to_coins(l_token_from_value); + l_token_to_value_datoshi_str = dap_chain_balance_print(l_token_to_value); + l_token_to_value_coins_str = dap_chain_balance_to_coins(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; @@ -3267,12 +3406,11 @@ static void s_ledger_tx_add_notify(void *a_arg, dap_ledger_t *a_ledger, dap_chai 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){ @@ -3288,7 +3426,12 @@ static void s_ledger_tx_add_notify(void *a_arg, dap_ledger_t *a_ledger, dap_chai 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 3b3f7ea6c07f0c22f54b27aae065251cb2eff6af..79d8b3725ef3998e78ee9197ed242412237b940b 100644 --- a/modules/wallet/dap_chain_wallet_cache.c +++ b/modules/wallet/dap_chain_wallet_cache.c @@ -946,7 +946,7 @@ static int s_save_tx_cache_for_addr(dap_chain_t *a_chain, dap_chain_addr_t *a_ad log_it(L_ERROR, "Can't find previous transactions (hash=%s)", dap_hash_fast_to_str_static(&l_prev_tx_hash)); continue; } - uint8_t* l_prev_item = dap_chain_datum_tx_item_get_nth(l_tx_prev, TX_ITEM_TYPE_OUT, l_prev_idx); + 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;