diff --git a/modules/chain/dap_chain_ledger.c b/modules/chain/dap_chain_ledger.c index 5e4bf00af40c6583e30940e9bb6d9472bdd95ad3..43d957e886d7635883459e8a2dc91479492c7e74 100644 --- a/modules/chain/dap_chain_ledger.c +++ b/modules/chain/dap_chain_ledger.c @@ -646,7 +646,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t && 5. tx1.dap_chain_datum_tx_out.condition == verify_svc_type(tx2) for conditional ouput && - 6. sum( find (tx2.input.tx_prev_hash).output[tx2.input_tx_prev_idx].value ) == sum (tx2.outputs.value) + 6. sum( find (tx2.input.tx_prev_hash).output[tx2.input_tx_prev_idx].value ) == sum (tx2.outputs.value) per token */ dap_ledger_private_t *l_ledger_priv = PVT(a_ledger); @@ -682,7 +682,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t &l_prev_tx_count); if (l_list_tmp) { // add conditional input to common list - dap_list_append(l_list_in, l_list_tmp->data); + l_list_in = dap_list_append(l_list_in, l_list_tmp->data); dap_list_free(l_list_tmp); } l_list_tmp = l_list_in; @@ -841,7 +841,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t // find 'out' items dap_list_t *l_list_out = dap_chain_datum_tx_items_get((dap_chain_datum_tx_t*) a_tx, TX_ITEM_TYPE_OUT, NULL); dap_list_t *l_list_out_cond = dap_chain_datum_tx_items_get((dap_chain_datum_tx_t*) a_tx, TX_ITEM_TYPE_OUT_COND, NULL); - // accumalate value ​from all 'out' transactions + // accumalate value ​from all 'out' items l_list_tmp = l_list_out; while(l_list_tmp) { dap_chain_tx_out_t *l_tx_out = (dap_chain_tx_out_t*) l_list_tmp->data; @@ -851,7 +851,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t l_list_tx_out = dap_list_append(l_list_tx_out, l_tx_out); l_list_tmp = dap_list_next(l_list_tmp); } - // accumalate value ​from all 'ut_cond' transactions + // accumalate value ​from all 'out_cond' items l_list_tmp = l_list_out_cond; while(l_list_tmp) { dap_chain_tx_out_cond_t *l_tx_out = (dap_chain_tx_out_cond_t*) l_list_tmp->data; @@ -977,7 +977,7 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx) //log_it ( L_INFO, "dap_chain_ledger_tx_add() check passed for tx %s",l_tx_hash_str); - char * l_token_ticker = NULL, *l_token_ticker_cond = NULL; + char *l_token_ticker = NULL; dap_chain_ledger_tx_item_t *l_item_tmp = NULL; pthread_rwlock_wrlock(&l_ledger_priv->ledger_rwlock); HASH_FIND(hh, l_ledger_priv->ledger_items, l_tx_hash, sizeof(dap_chain_hash_fast_t), l_item_tmp); // tx_hash already in the hash? @@ -1003,18 +1003,19 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx) while(l_list_tmp) { dap_chain_ledger_tx_bound_t *bound_item = l_list_tmp->data; uint8_t l_cond = *(uint8_t *)bound_item->tx_cur_in; - dap_chain_ledger_tx_item_t *l_prev_item_out = bound_item->item_out;; + dap_chain_ledger_tx_item_t *l_prev_item_out = bound_item->item_out; + if (*l_prev_item_out->token_tiker) { + l_token_ticker = l_prev_item_out->token_tiker; + } else { // Previous multichannel transaction + l_token_ticker = bound_item->tx_prev_out->token; + } dap_chain_hash_fast_t *l_tx_prev_hash; if (l_cond != TX_ITEM_TYPE_IN_COND) { dap_chain_tx_in_t *l_tx_in = bound_item->tx_cur_in; - if (l_token_ticker == NULL) - l_token_ticker = dap_strdup (l_prev_item_out->token_tiker); - // Update balance: deducts dap_ledger_wallet_balance_t *wallet_balance = NULL; char *l_addr_str = dap_chain_addr_to_str(&bound_item->tx_prev_out->addr); - char *l_token_ticker_ex = *bound_item->tx_prev_out->token ? bound_item->tx_prev_out->token : l_token_ticker; - char *l_wallet_balance_key = dap_strjoin(" ", l_addr_str, l_token_ticker_ex, (char*)NULL); + char *l_wallet_balance_key = dap_strjoin(" ", l_addr_str, l_token_ticker, (char*)NULL); HASH_FIND_STR(PVT(a_ledger)->balance_accounts, l_wallet_balance_key, wallet_balance); if (wallet_balance) { //log_it(L_DEBUG,"SPEND %lu from addr: %s", bound_item->tx_prev_out->header.value, l_wallet_balance_key); @@ -1027,8 +1028,6 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx) /// Mark 'out' item in cache because it used l_tx_prev_hash = &(l_prev_item_out->tx_hash_spent_fast[l_tx_in->header.tx_out_prev_idx]); } else { - if (l_token_ticker_cond == NULL) - l_token_ticker_cond = dap_strdup(l_prev_item_out->token_tiker); // all balance deducts performed with previous conditional transaction dap_chain_tx_in_cond_t *l_tx_in_cond = bound_item->tx_cur_in_cond; /// Mark 'out' item in cache because it used @@ -1073,12 +1072,7 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx) } if (l_list_bound_items) dap_list_free_full(l_list_bound_items, free); - if (l_token_ticker_cond) { - if (l_token_ticker) { - DAP_DELETE(l_token_ticker); - } - l_token_ticker = dap_strdup(l_token_ticker_cond); - } + // Try to find token ticker if wasn't if ( l_token_ticker == NULL){ int l_base_tx_count = 0; @@ -1091,6 +1085,7 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx) } //Update balance : raise + bool l_multichannel = false; for (dap_list_t *l_tx_out = l_list_tx_out; l_tx_out; l_tx_out = dap_list_next(l_tx_out)) { if (*(uint8_t *)l_tx_out->data == TX_ITEM_TYPE_OUT_COND) { continue; // balance raise will be with next conditional transaction @@ -1102,8 +1097,11 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx) // (long double) l_out_item->header.value/ 1000000000000.0L, // l_token_ticker, l_addr_str); dap_ledger_wallet_balance_t *wallet_balance = NULL; - char *l_token_ticker_ex = *l_out_item->token ? l_out_item->token : l_token_ticker; - char *l_wallet_balance_key = dap_strjoin(" ", l_addr_str, l_token_ticker_ex, (char*)NULL); + if (*l_out_item->token) { // Multichannel transaction + l_token_ticker = l_out_item->token; + l_multichannel = true; + } + char *l_wallet_balance_key = dap_strjoin(" ", l_addr_str, l_token_ticker, (char*)NULL); //log_it (L_DEBUG,"\t\tAddr: %s token: %s", l_addr_str, l_token_ticker); HASH_FIND_STR(PVT(a_ledger)->balance_accounts, l_wallet_balance_key, wallet_balance); if (wallet_balance) { @@ -1114,7 +1112,7 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx) wallet_balance = DAP_NEW_Z(dap_ledger_wallet_balance_t); wallet_balance->key = l_wallet_balance_key; wallet_balance->balance += l_out_item->header.value; - dap_stpcpy(wallet_balance->token_ticker, l_token_ticker_ex); + dap_stpcpy(wallet_balance->token_ticker, l_token_ticker); //log_it(L_DEBUG,"!!! Create new balance item: %s %s", l_addr_str, l_token_ticker); HASH_ADD_KEYPTR(hh, PVT(a_ledger)->balance_accounts, wallet_balance->key, strlen(l_wallet_balance_key), wallet_balance); @@ -1175,8 +1173,8 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx) dap_list_free(l_tokens_list); } } - if (l_token_ticker) - strncpy(l_item_tmp->token_tiker,l_token_ticker,sizeof (l_item_tmp->token_tiker)); + if (l_token_ticker && !l_multichannel) + strncpy(l_item_tmp->token_tiker, l_token_ticker, sizeof(l_item_tmp->token_tiker) - 1); memcpy(l_item_tmp->tx, a_tx, dap_chain_datum_tx_get_size(a_tx)); HASH_ADD(hh, l_ledger_priv->ledger_items, tx_hash_fast, sizeof(dap_chain_hash_fast_t), l_item_tmp); // tx_hash_fast: name of key field @@ -1185,12 +1183,6 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx) FIN: pthread_rwlock_tryrdlock (&l_ledger_priv->ledger_rwlock); pthread_rwlock_unlock(&l_ledger_priv->ledger_rwlock); - if (l_token_ticker) { - DAP_DELETE(l_token_ticker); - } - if (l_token_ticker_cond) { - DAP_DELETE(l_token_ticker_cond); - } DAP_DELETE(l_tx_hash); return ret; } @@ -1448,6 +1440,10 @@ static dap_chain_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger, pthread_rwlock_wrlock(&l_ledger_priv->ledger_rwlock); HASH_ITER(hh, l_ledger_priv->ledger_items , l_iter_current, l_item_tmp) { + // If a_token is setup we check if its not our token - miss it + if (a_token && *l_iter_current->token_tiker && dap_strcmp(l_iter_current->token_tiker, a_token)) + continue; + // Now work with it dap_chain_datum_tx_t *l_tx = l_iter_current->tx; dap_chain_hash_fast_t *l_tx_hash = &l_iter_current->tx_hash_fast; // start searching from the next hash after a_tx_first_hash @@ -1462,7 +1458,7 @@ static dap_chain_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger, const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t*) l_list_tmp->data; assert(l_tx_out); // If a_token is setup we check if its not our token - miss it - if (a_token && dap_strcmp(l_iter_current->token_tiker, a_token) && dap_strcmp(l_tx_out->token, a_token)) { + if (a_token && !*l_iter_current->token_tiker && dap_strcmp(l_tx_out->token, a_token)) { continue; } // if transaction has the out item with requested addr @@ -1656,7 +1652,6 @@ dap_list_t *dap_chain_ledger_get_list_tx_outs_with_val(dap_ledger_t *a_ledger, c if(out_item && out_item->header.value && !memcmp(a_addr_from, &out_item->addr, sizeof(dap_chain_addr_t))) { // Check whether used 'out' items if(!dap_chain_ledger_tx_hash_is_used_out_item (a_ledger, &l_tx_cur_hash, l_out_idx_tmp)) { - list_used_item_t *item = DAP_NEW(list_used_item_t); memcpy(&item->tx_hash_fast, &l_tx_cur_hash, sizeof(dap_chain_hash_fast_t)); item->num_idx_out = l_out_idx_tmp; diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c index 11932b7ffd308351b11d438ad2f4ecf78b1febac..65c1fa693293e14d22f8b87f01db3f6f1876ce79 100644 --- a/modules/net/dap_chain_net.c +++ b/modules/net/dap_chain_net.c @@ -1879,7 +1879,7 @@ char * dap_chain_net_get_gdb_group_mempool_by_chain_type(dap_chain_net_t * l_net */ dap_chain_node_addr_t * dap_chain_net_get_cur_addr( dap_chain_net_t * l_net) { - return PVT(l_net)->node_info? &PVT(l_net)->node_info->hdr.address: PVT(l_net)->node_addr; + return PVT(l_net)->node_info ? &PVT(l_net)->node_info->hdr.address : PVT(l_net)->node_addr; } uint64_t dap_chain_net_get_cur_addr_int(dap_chain_net_t * l_net) diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c index cce473d3d79cf1348b2b1db2faac927290244381..7d1ad6ca0910e362ad92b9f2754c953c5982c232 100644 --- a/modules/net/dap_chain_node_cli_cmd.c +++ b/modules/net/dap_chain_node_cli_cmd.c @@ -1707,10 +1707,7 @@ int com_tx_wallet(int argc, char ** argv, void *arg_func, char **str_reply) break; } - char *l_str_ret_tmp = dap_string_free(l_string_ret, false); - char *str_ret = dap_strdup(l_str_ret_tmp); - dap_chain_node_cli_set_reply_text(str_reply, str_ret); - DAP_DELETE(l_str_ret_tmp); + *str_reply = dap_string_free(l_string_ret, false); return 0; } diff --git a/modules/net/dap_dns_server.c b/modules/net/dap_dns_server.c index b781f9892fc52a2404acecc367f787bc7c24c813..33e4b54ef1e92c52e58646c4b552fe3189fc6aa7 100644 --- a/modules/net/dap_dns_server.c +++ b/modules/net/dap_dns_server.c @@ -310,7 +310,7 @@ void dap_dns_server_start() { s_dns_server->hash_table = NULL; s_dns_server->instance = dap_udp_server_listen(DNS_LISTEN_PORT); if (!s_dns_server->instance) { - log_it(L_ERROR, "Can't star DNS server"); + log_it(L_ERROR, "Can't start DNS server"); return; } s_dns_server->instance->client_read_callback = dap_dns_client_read; diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c index 32485b1c2996fdd02c57cffea7e241d4f7f4435b..8fab6d39fc1a626c79dafb01b1555d24a071dd9c 100644 --- a/modules/service/xchange/dap_chain_net_srv_xchange.c +++ b/modules/service/xchange/dap_chain_net_srv_xchange.c @@ -36,7 +36,6 @@ static int s_callback_requested(dap_chain_net_srv_t *a_srv, uint32_t a_usage_id, static int s_callback_response_success(dap_chain_net_srv_t *a_srv, uint32_t a_usage_id, dap_chain_net_srv_client_t *a_srv_client, const void *a_data, size_t a_data_size); static int s_callback_response_error(dap_chain_net_srv_t *a_srv, uint32_t a_usage_id, dap_chain_net_srv_client_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_t *a_srv_client, const void *a_data, size_t a_data_size); -static bool dap_chain_net_srv_xchange_verificator(dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx); static dap_chain_net_srv_xchange_t *s_srv_xchange; @@ -72,7 +71,6 @@ int dap_chain_net_srv_xchange_init() s_srv_xchange = DAP_NEW_Z(dap_chain_net_srv_xchange_t); l_srv->_inhertor = s_srv_xchange; s_srv_xchange->enabled = false; - dap_chain_ledger_verificator_add(DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, dap_chain_net_srv_xchange_verificator); return 0; } @@ -88,7 +86,7 @@ void dap_chain_net_srv_xchange_deinit() DAP_DELETE(s_srv_xchange); } -static bool dap_chain_net_srv_xchange_verificator(dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx) +bool dap_chain_net_srv_xchange_verificator(dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx) { /* Check only one of following conditions for verification success * 1. addr(a_cond.params).data.key == a_tx.sign.pkey -- for condition owner @@ -242,6 +240,10 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha // add 'in' item to buy from conditional transaction int l_prev_cond_idx = 0; dap_chain_datum_tx_t *l_cond_tx = dap_chain_ledger_tx_find_by_hash(l_ledger, a_tx_cond_hash); + if (!l_cond_tx) { + log_it(L_WARNING, "Requested conditional transaction not found"); + return NULL; + } dap_chain_tx_out_cond_t *l_tx_out_cond = (dap_chain_tx_out_cond_t *)dap_chain_datum_tx_item_get( l_cond_tx, &l_prev_cond_idx, TX_ITEM_TYPE_OUT_COND, NULL); dap_chain_datum_tx_add_in_cond_item(&l_tx, a_tx_cond_hash, l_prev_cond_idx, 0); @@ -275,7 +277,11 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha } } //transfer buying coins - if (dap_chain_datum_tx_add_out_item(&l_tx, l_seller_addr, a_price->datoshi_buy) != 1) { + l_tx_out = dap_chain_datum_tx_item_out_create(l_seller_addr, a_price->datoshi_buy, a_price->token_buy); + if (l_tx_out) { + dap_chain_datum_tx_add_item(&l_tx, (const uint8_t *)l_tx_out); + DAP_DELETE(l_tx_out); + } else { dap_chain_datum_tx_delete(l_tx); DAP_DELETE(l_seller_addr); log_it(L_ERROR, "Cant add buying coins output"); @@ -286,8 +292,12 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha uint64_t l_buying_value = l_tx_out_cond->header.value; l_value_back = l_buying_value - a_price->datoshi_buy; if (l_value_back) { - //if (dap_chain_datum_tx_add_out_item(&l_tx, l_buyer_addr, l_value_back) != 1) { - //dap_chain_datum_tx_delete(l_tx); + /*l_tx_out = dap_chain_datum_tx_item_out_create(l_buyer_addr, l_value_back, a_price->token_buy); + if (l_tx_out) { + dap_chain_datum_tx_add_item(&l_tx, (const uint8_t *)l_tx_out); + DAP_DELETE(l_tx_out); + } else { + dap_chain_datum_tx_delete(l_tx);*/ log_it(L_WARNING, "Partial exchange not allowed"); return NULL; //} @@ -352,8 +362,16 @@ static bool s_xchage_tx_invalidate(dap_chain_net_srv_xchange_price_t *a_price, d // add 'in' item to buy from conditional transaction int l_prev_cond_idx = 0; dap_chain_datum_tx_t *l_cond_tx = dap_chain_ledger_tx_find_by_hash(l_ledger, &a_price->tx_hash); + if (!l_cond_tx) { + log_it(L_WARNING, "Requested conditional transaction not found"); + return false; + } dap_chain_tx_out_cond_t *l_tx_out_cond = (dap_chain_tx_out_cond_t *)dap_chain_datum_tx_item_get( l_cond_tx, &l_prev_cond_idx, TX_ITEM_TYPE_OUT_COND, NULL); + if (dap_chain_ledger_tx_hash_is_used_out_item(l_ledger, &a_price->tx_hash, l_prev_cond_idx)) { + log_it(L_WARNING, "Requested conditional transaction is already used out"); + return false; + } dap_chain_datum_tx_add_in_cond_item(&l_tx, &a_price->tx_hash, l_prev_cond_idx, 0); // add 'out' item @@ -362,7 +380,7 @@ static bool s_xchage_tx_invalidate(dap_chain_net_srv_xchange_price_t *a_price, d log_it(L_WARNING, "Only owner can invalidate exchange transaction"); return false; } - if (dap_chain_datum_tx_add_out_item(&l_tx, l_seller_addr, l_tx_out_cond->header.value)) { + if (dap_chain_datum_tx_add_out_item(&l_tx, l_seller_addr, l_tx_out_cond->header.value) == -1) { dap_chain_datum_tx_delete(l_tx); DAP_DELETE(l_seller_addr); log_it(L_ERROR, "Cant add returning coins output"); @@ -398,7 +416,6 @@ char *s_xchange_order_create(dap_chain_net_srv_xchange_price_t *a_price, dap_cha char *l_order_hash_str = dap_chain_net_srv_order_create(a_price->net_buy, SERV_DIR_SELL, l_uid, *l_node_addr, l_tx_hash, a_price->datoshi_buy, l_unit, a_price->token_buy, 0, (uint8_t *)&l_ext, l_ext_size, NULL, 0); - DAP_DELETE(l_node_addr); return l_order_hash_str; } @@ -515,7 +532,7 @@ static int s_cli_srv_xchange_price(int a_argc, char **a_argv, int a_arg_index, c return -11; } if (dap_chain_wallet_get_balance(l_wallet, l_net_sell->pub.id, l_token_sell_str) < l_datoshi_sell) { - dap_chain_node_cli_set_reply_text(a_str_reply, "Not anough cash in specified wallet"); + dap_chain_node_cli_set_reply_text(a_str_reply, "Not enough cash in specified wallet"); dap_chain_wallet_close(l_wallet); return -12; } @@ -563,23 +580,28 @@ static int s_cli_srv_xchange_price(int a_argc, char **a_argv, int a_arg_index, c HASH_FIND_STR(s_srv_xchange->pricelist, l_strkey, l_price); if (l_price) { if (l_cmd_num == CMD_REMOVE) { + dap_string_t *l_str_reply = dap_string_new(""); + HASH_DEL(s_srv_xchange->pricelist, l_price); dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_price->wallet_str, dap_chain_wallet_get_path(g_config)); bool l_ret = s_xchage_tx_invalidate(l_price, l_wallet); dap_chain_wallet_close(l_wallet); if (!l_ret) { char *l_tx_hash_str = dap_chain_hash_fast_to_str_new(&l_price->tx_hash); - dap_chain_node_cli_set_reply_text(a_str_reply, "Can't invalidate transaction %s", l_tx_hash_str); + dap_string_append_printf(l_str_reply, "Can't invalidate transaction %s\n", l_tx_hash_str); DAP_DELETE(l_tx_hash_str); - break; } char *l_order_hash_str = dap_chain_hash_fast_to_str_new(&l_price->order_hash); - dap_chain_net_srv_order_delete_by_hash_str(l_price->net_buy, l_order_hash_str); + if (dap_chain_net_srv_order_delete_by_hash_str(l_price->net_buy, l_order_hash_str)) { + dap_string_append_printf(l_str_reply, "Can't remove order %s\n", l_order_hash_str); + } DAP_DELETE(l_order_hash_str); - HASH_DEL(s_srv_xchange->pricelist, l_price); DAP_DELETE(l_price->key_ptr); DAP_DELETE(l_price->wallet_str); DAP_DELETE(l_price); - dap_chain_node_cli_set_reply_text(a_str_reply, "Price successfully removed"); + if (!l_str_reply->len) { + dap_string_append(l_str_reply, "Price successfully removed"); + } + *a_str_reply = dap_string_free(l_str_reply, false); } else { // CMD_UPDATE const char *l_val_sell_str = NULL, *l_val_buy_str = NULL, *l_wallet_str = NULL, *l_new_wallet_str = NULL; uint64_t l_datoshi_sell = 0, l_datoshi_buy = 0; @@ -592,6 +614,7 @@ static int s_cli_srv_xchange_price(int a_argc, char **a_argv, int a_arg_index, c return -9; } } + dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-datoshi_buy", &l_val_buy_str); if (l_val_buy_str) { l_datoshi_buy = strtoull(l_val_buy_str, NULL, 10); if (!l_datoshi_buy) { @@ -611,7 +634,7 @@ static int s_cli_srv_xchange_price(int a_argc, char **a_argv, int a_arg_index, c return -13; } if (l_datoshi_sell && dap_chain_wallet_get_balance(l_wallet, l_net_sell->pub.id, l_token_sell_str) < l_datoshi_sell) { - dap_chain_node_cli_set_reply_text(a_str_reply, "Not anough cash in specified wallet"); + dap_chain_node_cli_set_reply_text(a_str_reply, "Not enough cash in specified wallet"); dap_chain_wallet_close(l_wallet); return -12; } @@ -681,8 +704,10 @@ static int s_cli_srv_xchange_price(int a_argc, char **a_argv, int a_arg_index, c l_price->datoshi_buy, l_price->wallet_str, l_order_hash_str); DAP_DELETE(l_order_hash_str); } - dap_chain_node_cli_set_reply_text(a_str_reply, *l_reply_str->str ? "Pricelist is empty" : l_reply_str->str); - dap_string_free(l_reply_str, true); + if (!l_reply_str->len) { + dap_string_append(l_reply_str, "Pricelist is empty"); + } + *a_str_reply = dap_string_free(l_reply_str, false); } break; default: { dap_chain_node_cli_set_reply_text(a_str_reply, "Subcommand %s not recognized", a_argv[a_arg_index]); diff --git a/modules/service/xchange/include/dap_chain_net_srv_xchange.h b/modules/service/xchange/include/dap_chain_net_srv_xchange.h index 02a2232fcd5091208d7320a89f695595faed03db..0ab6610b71c5dd5e0491d7e8021ec87045090b7d 100644 --- a/modules/service/xchange/include/dap_chain_net_srv_xchange.h +++ b/modules/service/xchange/include/dap_chain_net_srv_xchange.h @@ -57,3 +57,4 @@ typedef struct dap_chain_net_srv_xchange { int dap_chain_net_srv_xchange_init(); void dap_chain_net_srv_xchange_deinit(); +bool dap_chain_net_srv_xchange_verificator(dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx);