From bb80d5fe00f0afb6e02d7107242fbbd2c8950692 Mon Sep 17 00:00:00 2001 From: "daniil.frolov" <daniil.frolov@demlabs.net> Date: Fri, 21 Feb 2025 15:09:40 +0300 Subject: [PATCH] .. --- .../dap_stream_ch_chain_net_srv.c | 157 +++++++++++------- .../dap_chain_net_srv_stream_session.h | 20 ++- modules/service/vpn/dap_chain_net_srv_vpn.c | 2 +- .../service/vpn/dap_chain_net_vpn_client.c | 4 +- 4 files changed, 111 insertions(+), 72 deletions(-) diff --git a/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c index 4d58731978..7441b0d0fd 100644 --- a/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c +++ b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c @@ -50,6 +50,14 @@ typedef struct client_statistic_key{ char key[18 + DAP_CHAIN_HASH_FAST_STR_SIZE]; } client_statistic_key_t; +typedef enum { + PAY_SERVICE_STATUS_SUCCESS = 0, + PAY_SERVICE_STATUS_NOT_ENOUGH, + PAY_SERVICE_STATUS_TX_ERROR, + PAY_SERVICE_STATUS_MEMALLOC_ERROR, +} pay_service_status; + + // client statistic value struct typedef struct client_statistic_value{ struct { @@ -89,6 +97,8 @@ static bool s_stream_ch_packet_out(dap_stream_ch_t* ch , void* arg); static bool s_unban_client(dap_chain_net_srv_banlist_item_t *a_item); +static int s_pay_cervice(dap_chain_net_srv_usage_t *a_usage, dap_chain_datum_tx_receipt_t *a_receipt); + static bool s_service_start(dap_stream_ch_t *a_ch , dap_stream_ch_chain_net_srv_pkt_request_t *a_request, size_t a_request_size); static bool s_grace_period_start(dap_chain_net_srv_grace_t *a_grace); static bool s_grace_period_finish(dap_chain_net_srv_grace_usage_t *a_grace); @@ -126,7 +136,7 @@ static inline void s_grace_error(dap_chain_net_srv_grace_t *a_grace, dap_stream_ } if (a_grace->usage) { // add client pkey hash to banlist - a_grace->usage->is_active = false; + a_grace->usage->is_active = 0; if (a_grace->usage->service) { dap_chain_net_srv_banlist_item_t *l_item = NULL; pthread_mutex_lock(&a_grace->usage->service->banlist_mutex); @@ -969,12 +979,12 @@ static bool s_grace_period_finish(dap_chain_net_srv_grace_usage_t *a_grace_item) if (l_grace->usage->is_waiting_new_tx_cond){ log_it(L_INFO, "No new tx cond!"); - l_grace->usage->is_waiting_new_tx_cond = false; + l_grace->usage->is_waiting_new_tx_cond = 0; RET_WITH_DEL_A_GRACE(DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NO_NEW_COND); } bool l_waiting_new_tx_in_ledger = l_grace->usage->is_waiting_new_tx_cond_in_ledger; - l_grace->usage->is_waiting_new_tx_cond_in_ledger = false; + l_grace->usage->is_waiting_new_tx_cond_in_ledger = 0; dap_chain_net_t * l_net = l_grace->usage->net; @@ -1160,68 +1170,64 @@ static bool s_grace_period_finish(dap_chain_net_srv_grace_usage_t *a_grace_item) } dap_global_db_set(SRV_RECEIPTS_GDB_GROUP, dap_get_data_hash_str(l_receipt, l_receipt_size).s, l_receipt, l_receipt_size, false, NULL, NULL); // Form input transaction - char *l_hash_str = dap_hash_fast_to_str_new(&l_grace->usage->tx_cond_hash); - log_it(L_NOTICE, "Trying create input tx cond from tx %s with active receipt", l_hash_str); - DAP_DEL_Z(l_hash_str); - int ret_status = 0; - char *l_tx_in_hash_str = dap_chain_mempool_tx_create_cond_input(l_grace->usage->net, &l_grace->usage->tx_cond_hash, l_grace->usage->price->wallet_addr, - l_grace->usage->price->receipt_sign_cert->enc_key, - l_receipt, "hex", &ret_status); - if (!ret_status) { - dap_chain_hash_fast_from_str(l_tx_in_hash_str, &l_grace->usage->tx_cond_hash); - log_it(L_NOTICE, "Formed tx %s for input with active receipt", l_tx_in_hash_str); - DAP_DELETE(l_tx_in_hash_str); - } else { - if(ret_status == DAP_CHAIN_MEMPOOl_RET_STATUS_NOT_ENOUGH){ - log_it(L_ERROR, "Tx cond have not enough funds"); + + int l_ret = s_pay_cervice(l_grace->usage, l_receipt); + switch (l_ret){ + case PAY_SERVICE_STATUS_NOT_ENOUGH: if (l_waiting_new_tx_in_ledger){ log_it(L_ERROR, "New tx cond have not enough funds. Waiting for end of service."); RET_WITH_DEL_A_GRACE(DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_NEW_TX_COND_NOT_ENOUGH); - } - - dap_chain_net_srv_grace_t* l_grace_new = DAP_NEW_Z(dap_chain_net_srv_grace_t); - if (!l_grace_new) { - log_it(L_CRITICAL, "%s", c_error_memory_alloc); - RET_WITH_DEL_A_GRACE(0); - } - // Parse the request - l_grace_new->request = DAP_NEW_Z_SIZE(dap_stream_ch_chain_net_srv_pkt_request_t, sizeof(dap_stream_ch_chain_net_srv_pkt_request_t)); - if (!l_grace_new->request) { - log_it(L_CRITICAL, "%s", c_error_memory_alloc); - DAP_DEL_Z(l_grace_new); + } else { + dap_chain_net_srv_grace_t* l_grace_new = DAP_NEW_Z(dap_chain_net_srv_grace_t); + if (!l_grace_new) { + log_it(L_CRITICAL, "%s", c_error_memory_alloc); + RET_WITH_DEL_A_GRACE(0); + } + // Parse the request + l_grace_new->request = DAP_NEW_Z_SIZE(dap_stream_ch_chain_net_srv_pkt_request_t, sizeof(dap_stream_ch_chain_net_srv_pkt_request_t)); + if (!l_grace_new->request) { + log_it(L_CRITICAL, "%s", c_error_memory_alloc); + DAP_DEL_Z(l_grace_new); + RET_WITH_DEL_A_GRACE(0); + } + l_grace_new->request->hdr.net_id = a_grace_item->grace->usage->net->pub.id; + dap_stpcpy(l_grace_new->request->hdr.token, a_grace_item->grace->usage->token_ticker); + l_grace_new->request->hdr.srv_uid = a_grace_item->grace->usage->service->uid; + l_grace_new->request->hdr.tx_cond = a_grace_item->grace->usage->tx_cond_hash; + l_grace_new->request_size = sizeof(dap_stream_ch_chain_net_srv_pkt_request_t); + l_grace_new->ch_uuid = a_grace_item->grace->usage->client->ch->uuid; + l_grace_new->stream_worker = a_grace_item->grace->usage->client->ch->stream_worker; + l_grace_new->usage = a_grace_item->grace->usage; + l_grace_new->usage->is_waiting_new_tx_cond = 1; + + if (s_grace_period_start(l_grace_new)){ + l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NOT_ENOUGH; + dap_stream_ch_pkt_write_unsafe(l_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof (l_err)); + if (l_grace->usage->service->callbacks.response_error) + l_grace->usage->service->callbacks.response_error(l_grace->usage->service,l_grace->usage->id, l_grace->usage->client,&l_err,sizeof (l_err)); + } RET_WITH_DEL_A_GRACE(0); } - l_grace_new->request->hdr.net_id = a_grace_item->grace->usage->net->pub.id; - dap_stpcpy(l_grace_new->request->hdr.token, a_grace_item->grace->usage->token_ticker); - l_grace_new->request->hdr.srv_uid = a_grace_item->grace->usage->service->uid; - l_grace_new->request->hdr.tx_cond = a_grace_item->grace->usage->tx_cond_hash; - l_grace_new->request_size = sizeof(dap_stream_ch_chain_net_srv_pkt_request_t); - l_grace_new->ch_uuid = a_grace_item->grace->usage->client->ch->uuid; - l_grace_new->stream_worker = a_grace_item->grace->usage->client->ch->stream_worker; - l_grace_new->usage = a_grace_item->grace->usage; - l_grace_new->usage->is_waiting_new_tx_cond = true; - - if (s_grace_period_start(l_grace_new)){ - l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NOT_ENOUGH; - dap_stream_ch_pkt_write_unsafe(l_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof (l_err)); - if (l_grace->usage->service->callbacks.response_error) - l_grace->usage->service->callbacks.response_error(l_grace->usage->service,l_grace->usage->id, l_grace->usage->client,&l_err,sizeof (l_err)); - } - DAP_DELETE(l_tx_in_hash_str); - RET_WITH_DEL_A_GRACE(0); - } else { - log_it(L_ERROR, "Can't create input tx cond transaction!"); - memset(&l_grace->usage->tx_cond_hash, 0, sizeof(l_grace->usage->tx_cond_hash)); - if (l_grace->usage->receipt_next){ - DAP_DEL_Z(l_grace->usage->receipt_next); - } else if (l_grace->usage->receipt){ - DAP_DEL_Z(l_grace->usage->receipt); + break; + case PAY_SERVICE_STATUS_SUCCESS: + break; + case PAY_SERVICE_STATUS_MEMALLOC_ERROR: + log_it(L_CRITICAL, "%s", c_error_memory_alloc); + RET_WITH_DEL_A_GRACE(DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_ALLOC_MEMORY_ERROR); + break; + case PAY_SERVICE_STATUS_TX_ERROR: + default: { + memset(&l_grace->usage->tx_cond_hash, 0, sizeof(a_usage->tx_cond_hash)); + if (a_usage->receipt_next){ + DAP_DEL_Z(a_usage->receipt_next); + } else if (a_usage->receipt){ + DAP_DEL_Z(a_usage->receipt); } l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_SERVICE_NOT_FOUND; dap_stream_ch_pkt_write_unsafe(l_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof (l_err)); if (l_grace->usage->service->callbacks.response_error) l_grace->usage->service->callbacks.response_error(l_grace->usage->service,l_grace->usage->id, l_grace->usage->client,&l_err,sizeof (l_err)); - DAP_DELETE(l_tx_in_hash_str); + break; } } } @@ -1505,7 +1511,7 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg) break; case DAP_CHAIN_MEMPOOl_RET_STATUS_NOT_ENOUGH: log_it(L_ERROR, "Tx cond have not enough funds"); - l_usage->is_waiting_new_tx_cond = true; + l_usage->is_waiting_new_tx_cond = 1; l_grace = DAP_NEW_Z(dap_chain_net_srv_grace_t); if (!l_grace) { log_it(L_CRITICAL, "%s", c_error_memory_alloc); @@ -1590,13 +1596,13 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg) if( l_usage->service->callbacks.response_success(l_usage->service,l_usage->id, l_usage->client, l_receipt, l_receipt_size ) !=0 ){ log_it(L_NOTICE, "No success by service success callback, inactivating service usage"); - l_usage->is_active = false; + l_usage->is_active = 0; } } else if (l_usage->service->callbacks.receipt_next_success) { if (l_usage->service->callbacks.receipt_next_success(l_usage->service, l_usage->id, l_usage->client, l_receipt, l_receipt_size ) != 0 ){ log_it(L_NOTICE, "No success by service receipt_next callback, inactivating service usage"); - l_usage->is_active = false; + l_usage->is_active = 0; } } } break; @@ -1667,8 +1673,8 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg) break; } - l_usage->is_waiting_new_tx_cond = false; - l_usage->is_waiting_new_tx_cond_in_ledger = true; + l_usage->is_waiting_new_tx_cond = 0; + l_usage->is_waiting_new_tx_cond_in_ledger = 1; dap_stream_ch_chain_net_srv_pkt_error_t l_err = { }; dap_chain_net_srv_t *l_srv = dap_chain_net_srv_get(l_responce->hdr.srv_uid); dap_chain_net_srv_grace_usage_t *l_curr_grace_item = NULL; @@ -1746,3 +1752,34 @@ static bool s_stream_ch_packet_out(dap_stream_ch_t* a_ch , void* a_arg) dap_chain_net_srv_call_write_all( a_ch); return false; } + + +static int s_pay_cervice(dap_chain_net_srv_usage_t *a_usage, dap_chain_datum_tx_receipt_t *a_receipt) +{ + char *l_hash_str = dap_hash_fast_to_str_new(&a_usage->tx_cond_hash); + log_it(L_NOTICE, "Trying create input tx cond from tx %s with active receipt", l_hash_str); + DAP_DEL_Z(l_hash_str); + int ret_status = 0; + char *l_tx_in_hash_str = dap_chain_mempool_tx_create_cond_input(a_usage->net, &a_usage->tx_cond_hash, a_usage->price->wallet_addr, + a_usage->price->receipt_sign_cert->enc_key, a_receipt, "hex", &ret_status); + + // PAY_SERVICE_STATUS_NOT_ENOUGH, + // PAY_SERVICE_STATUS_TX_ERROR, + // PAY_SERVICE_STATUS_MEMALLOC_ERROR, + + if (!ret_status) { + dap_chain_hash_fast_from_str(l_tx_in_hash_str, &a_usage->tx_cond_hash); + log_it(L_NOTICE, "Formed tx %s for input with active receipt", l_tx_in_hash_str); + DAP_DEL_Z(l_tx_in_hash_str); + return PAY_SERVICE_STATUS_SUCCESS; + } else { + if(ret_status == DAP_CHAIN_MEMPOOl_RET_STATUS_NOT_ENOUGH){ + log_it(L_ERROR, "Tx cond have not enough funds"); + return PAY_SERVICE_STATUS_NOT_ENOUGH; + } else { + log_it(L_ERROR, "Can't create input tx cond transaction!"); + DAP_DEL_Z(l_tx_in_hash_str); + return PAY_SERVICE_STATUS_TX_ERROR; + } + } +} \ No newline at end of file diff --git a/modules/net/srv/include/dap_chain_net_srv_stream_session.h b/modules/net/srv/include/dap_chain_net_srv_stream_session.h index 7df15d24be..424ca17934 100644 --- a/modules/net/srv/include/dap_chain_net_srv_stream_session.h +++ b/modules/net/srv/include/dap_chain_net_srv_stream_session.h @@ -59,15 +59,17 @@ typedef struct dap_chain_net_srv_usage{ void (*receipt_timeout_timer_start_callback)(struct dap_chain_net_srv_usage *a_usage); int receipt_sign_req_cnt; char token_ticker[DAP_CHAIN_TICKER_SIZE_MAX]; - bool is_active; - bool is_free; - bool is_grace; - bool is_waiting_new_tx_cond; - bool is_waiting_new_tx_cond_in_ledger; - bool is_waiting_first_receipt_sign; - bool is_waiting_next_receipt_sign; - bool is_limits_changed; -// UT_hash_handle hh; // + + uint16_t is_active : 1; + uint16_t is_free : 1; + uint16_t is_grace : 1; + uint16_t is_waiting_new_tx_cond : 1; + uint16_t is_waiting_new_tx_cond_in_ledger : 1; + uint16_t is_waiting_first_receipt_sign : 1; + uint16_t is_waiting_next_receipt_sign : 1; + uint16_t is_limits_changed : 1; + uint16_t reserved : 8; + } dap_chain_net_srv_usage_t; typedef struct dap_net_stats{ diff --git a/modules/service/vpn/dap_chain_net_srv_vpn.c b/modules/service/vpn/dap_chain_net_srv_vpn.c index 2eb22a5d7a..b1ea1c1f70 100644 --- a/modules/service/vpn/dap_chain_net_srv_vpn.c +++ b/modules/service/vpn/dap_chain_net_srv_vpn.c @@ -1897,7 +1897,7 @@ static bool s_ch_packet_out(dap_stream_ch_t* a_ch, void* a_arg) } if ( (!l_usage->is_free) && (! l_usage->receipt && !l_usage->is_grace) ){ log_it(L_WARNING, "No active receipt, switching off"); - l_usage->is_active = false; + l_usage->is_active = 0; if (l_usage->client) dap_stream_ch_pkt_write_unsafe( l_usage->client->ch , DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_NOTIFY_STOPPED , NULL, 0 ); dap_stream_ch_set_ready_to_write_unsafe(a_ch,false); diff --git a/modules/service/vpn/dap_chain_net_vpn_client.c b/modules/service/vpn/dap_chain_net_vpn_client.c index 753da5a726..6d4ce0b7ee 100644 --- a/modules/service/vpn/dap_chain_net_vpn_client.c +++ b/modules/service/vpn/dap_chain_net_vpn_client.c @@ -173,8 +173,8 @@ static int s_callback_client_success(dap_chain_net_srv_t * a_srv, uint32_t a_usa return -3; } l_srv_ch_vpn->usage_id = l_usage->id; - l_usage->is_active = true; - l_usage->is_free = true; + l_usage->is_active = 1; + // l_usage->is_free = 1; dap_stream_ch_t *l_ch = dap_chain_net_vpn_client_get_stream_ch(); -- GitLab