Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • cellframe/libdap-chain-net-srv-vpn
1 result
Show changes
Commits on Source (10)
......@@ -147,7 +147,6 @@ static void s_ch_packet_out(dap_stream_ch_t* ch, void* arg);
static char *s_srv_vpn_addr = NULL, *s_srv_vpn_mask = NULL;
static void s_update_limits(dap_stream_ch_t * a_ch ,
dap_chain_net_srv_stream_session_t * a_srv_session,
dap_chain_net_srv_usage_t * a_usage, size_t a_bytes);
......@@ -158,8 +157,7 @@ static void s_update_limits(dap_stream_ch_t * a_ch ,
* @param vpn_mask Zero if only client mode. Mask if the node shares its local VPN
* @return 0 if everything is okay, lesser then zero if errors
*/
int dap_chain_net_srv_vpn_init(dap_config_t * g_config)
{
int dap_chain_net_srv_vpn_init(dap_config_t * g_config) {
const char *c_addr = dap_config_get_item_str(g_config, "srv_vpn", "network_address");
const char *c_mask = dap_config_get_item_str(g_config, "srv_vpn", "network_mask");
if(c_addr && c_mask) {
......@@ -184,101 +182,80 @@ int dap_chain_net_srv_vpn_init(dap_config_t * g_config)
l_srv_vpn->parent = l_srv;
uint16_t l_pricelist_count = 0;
char ** l_pricelist = dap_config_get_array_str(g_config,"srv_vpn","pricelist", &l_pricelist_count );
for ( uint16_t i = 0; i < l_pricelist_count; i++ ){
char * l_price_str = l_pricelist[i];
size_t l_price_length = strlen(l_price_str);
size_t l_iter = 0;
char * l_pos_old = l_price_str;
dap_chain_net_srv_price_t *l_price = DAP_NEW_Z(dap_chain_net_srv_price_t);
for (char * l_pos = index(l_price_str,':'); ; l_pos = index(l_pos+1,':') ){
if( l_iter == 0)
break;
size_t l_parse_token_size = l_pos?(size_t) (l_pos - l_pos_old)-1: l_price_length- (size_t)(l_pos_old - l_pricelist[i]) ;
char * l_parse_token = strndup(l_pos_old, l_parse_token_size);
if( l_parse_token_size ==0 ){
log_it(L_ERROR, "Wrong price element size nil");
DAP_DELETE(l_parse_token);
break;
}
if ( l_iter == 0){
l_price->net_name = strdup(l_parse_token);
l_price->net = dap_chain_net_by_name( l_price->net_name);
if( ! l_price->net ){
log_it(L_ERROR, "Error parse pricelist: can't find network \"%s\"", l_price->net_name);
DAP_DELETE( l_price->net);
/* ! IMPORTANT ! This fetch is single-action and cannot be further reused, since it modifies the stored config data
* ! it also must NOT be freed within this module !
*/
char **l_pricelist = dap_config_get_array_str(g_config, "srv_vpn", "pricelist", &l_pricelist_count); // must not be freed!
for (uint16_t i = 0; i < l_pricelist_count; i++) {
dap_chain_net_srv_price_t *l_price = DAP_NEW_Z(dap_chain_net_srv_price_t);
short l_iter = 0;
char *l_ctx;
for (char *l_price_token = strtok_r(l_pricelist[i], ":", &l_ctx); l_price_token || l_iter == 6; l_price_token = strtok_r(NULL, ":", &l_ctx), ++l_iter) {
//log_it(L_DEBUG, "Tokenizer: %s", l_price_token);
switch (l_iter) {
case 0:
l_price->net_name = l_price_token;
if (!(l_price->net = dap_chain_net_by_name(l_price->net_name))) {
log_it(L_ERROR, "Error parsing pricelist: can't find network \"%s\"", l_price_token);
DAP_DELETE(l_price);
DAP_DELETE(l_parse_token);
break;
}
}else if (l_iter == 1){
l_price->value_coins = atof( l_parse_token);
l_price->value_datoshi =(uint64_t) dap_chain_coins_to_balance((long double)l_price->value_coins);
if ( ! l_price->value_datoshi ){
log_it(L_ERROR, "Error parse pricelist: text on 2nd position \"%s\" is not floating number", l_parse_token);
DAP_DELETE( l_price->net);
continue;
case 1:
l_price->value_coins = atof(l_price_token);
if (!(l_price->value_datoshi = (uint64_t)dap_chain_coins_to_balance((long double)l_price->value_coins))) {
log_it(L_ERROR, "Error parsing pricelist: text on 2nd position \"%s\" is not floating number", l_price_token);
l_iter = 0;
DAP_DELETE(l_price);
DAP_DELETE(l_parse_token);
break;
}
}else if (l_iter == 2){
strncpy( l_price->token, l_parse_token, sizeof (l_price->token)-1);
}else if (l_iter == 3){
l_price->units = strtoul( l_parse_token,NULL,10);
if ( !l_price->units ){
log_it(L_ERROR, "Error parse pricelist: text on 4th position \"%s\" is not unsigned integer", l_parse_token);
DAP_DELETE( l_price->net);
continue;
case 2:
dap_stpcpy(l_price->token, l_price_token);
continue;
case 3:
l_price->units = strtoul(l_price_token, NULL, 10);
if (!l_price->units) {
log_it(L_ERROR, "Error parsing pricelist: text on 4th position \"%s\" is not unsigned integer", l_price_token);
l_iter = 0;
DAP_DELETE(l_price);
DAP_DELETE(l_parse_token);
break;
}
}else if (l_iter == 4){
if ( strcmp(l_parse_token,"SEC") == 0 ){
continue;
case 4:
if (!strcmp(l_price_token, "SEC"))
l_price->units_uid.enm = SERV_UNIT_SEC;
}else if ( strcmp(l_parse_token,"DAY") == 0 ){
else if (!strcmp(l_price_token, "DAY"))
l_price->units_uid.enm = SERV_UNIT_DAY;
}else if ( strcmp(l_parse_token,"MB") == 0 ){
else if (!strcmp(l_price_token, "MB"))
l_price->units_uid.enm = SERV_UNIT_MB;
}else {
log_it(L_ERROR, "Error parse pricelist: wrong unit type \"%s\"", l_parse_token);
DAP_DELETE( l_price->net);
else {
log_it(L_ERROR, "Error parsing pricelist: wrong unit type \"%s\"", l_price_token);
l_iter = 0;
DAP_DELETE(l_price);
DAP_DELETE(l_parse_token);
break;
}
}else if (l_iter == 5){
l_price->wallet = dap_chain_wallet_open( l_parse_token, dap_config_get_item_str_default(g_config,"resources","wallets_path",NULL) );
if (! l_price->wallet ){
log_it(L_ERROR, "Error parse pricelist: can't open wallet \"%s\"", l_parse_token);
DAP_DELETE( l_price->net);
continue;
case 5:
if (!(l_price->wallet = dap_chain_wallet_open(l_price_token, dap_config_get_item_str_default(g_config, "resources", "wallets_path", NULL)))) {
log_it(L_ERROR, "Error parsing pricelist: can't open wallet \"%s\"", l_price_token);
l_iter = 0;
DAP_DELETE(l_price);
DAP_DELETE(l_parse_token);
break;
}
}else{
DAP_DELETE(l_parse_token);
continue;
case 6:
log_it(L_INFO, "Price item correct, added to service");
DL_APPEND(l_srv->pricelist, l_price);
break;
}
l_iter++;
l_pos_old = l_pos;
if (! l_pos ){
DAP_DELETE(l_parse_token);
default:
break;
}
log_it(L_DEBUG, "Done with price item %d", i);
break; // double break exits tokenizer loop and steps to next price item
}
if( l_iter == 6){
log_it(L_NOTICE, "All price parsed well, added to service %s", l_price_str);
if (l_srv->pricelist)
l_srv->pricelist->prev = l_price;
l_price->next = l_srv->pricelist;
l_srv->pricelist = l_price;
}
}
return 0;
}
return -1;
......@@ -291,10 +268,10 @@ void dap_chain_net_srv_vpn_deinit(void)
{
pthread_mutex_destroy(&s_sf_socks_mutex);
pthread_cond_destroy(&s_sf_socks_cond);
free((char*) s_srv_vpn_addr);
free((char*) s_srv_vpn_mask);
DAP_DELETE(s_srv_vpn_addr);
DAP_DELETE(s_srv_vpn_mask);
if(s_raw_server)
free(s_raw_server);
DAP_DELETE(s_raw_server);
}
/**
......@@ -325,7 +302,7 @@ static int s_callback_response_success(dap_chain_net_srv_t * a_srv, uint32_t a_u
// dap_stream_ch_chain_net_srv_pkt_request_t * l_request = (dap_stream_ch_chain_net_srv_pkt_request_t *) a_request;
// dap_chain_net_srv_stream_session_t * l_srv_session = (dap_chain_net_srv_stream_session_t *) a_srv_client->ch->stream->session->_inheritor;
dap_chain_net_srv_stream_session_t * l_srv_session = (dap_chain_net_srv_stream_session_t *) a_srv_client->ch->stream->session->_inheritor;
dap_chain_net_srv_usage_t * l_usage_active= dap_chain_net_srv_usage_find(l_srv_session->usages,a_usage_id);
dap_chain_net_srv_usage_t * l_usage_active= dap_chain_net_srv_usage_find(l_srv_session,a_usage_id);
dap_chain_net_srv_ch_vpn_t * l_srv_ch_vpn =(dap_chain_net_srv_ch_vpn_t*) a_srv_client->ch->stream->channel[DAP_CHAIN_NET_SRV_VPN_ID] ?
a_srv_client->ch->stream->channel[DAP_CHAIN_NET_SRV_VPN_ID]->internal : NULL;
......@@ -484,6 +461,7 @@ void s_new(dap_stream_ch_t* a_stream_ch, void* a_arg)
dap_chain_net_srv_stream_session_create(a_stream_ch->stream->session);
dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_VPN_ID };
l_srv_vpn->net_srv = dap_chain_net_srv_get(l_uid);
l_srv_vpn->ch = a_stream_ch;
dap_chain_net_srv_stream_session_t * l_srv_session = (dap_chain_net_srv_stream_session_t *) a_stream_ch->stream->session->_inheritor;
pthread_mutex_init(&l_srv_vpn->mutex, NULL);
......
......@@ -71,17 +71,15 @@ typedef struct tx_cond_template{
long double value_coins;
uint128_t value_datoshi;
char * token_ticker;
char token_ticker[DAP_CHAIN_TICKER_SIZE_MAX];
char * net_name;
dap_chain_net_t * net;
dap_ledger_t * ledger;
time_t min_time; // Minimum time between transactions
struct tx_cond_template * prev;
struct tx_cond_template * next;
struct tx_cond_template *prev, *next;
} tx_cond_template_t;
static tx_cond_template_t * s_tx_cond_templates = NULL;
static tx_cond_template_t *s_tx_cond_templates = NULL;
const char *c_wallets_path = NULL;
static void s_auth_callback(enc_http_delegate_t* a_delegate, void * a_arg);
......@@ -124,108 +122,92 @@ int dap_chain_net_srv_vpn_cdb_init(dap_http_t * a_http)
false)) {
dap_chain_net_srv_vpn_cdb_server_list_add_proc ( a_http, SLIST_URL);
}
if( dap_config_get_item_bool_default( g_config,"cdb_auth","enabled",false) ){
if (dap_config_get_item_bool_default( g_config,"cdb_auth","enabled",false) ){
db_auth_init( dap_config_get_item_str_default(g_config,"cdb_auth","collection_name","cdb") );
// Produce transaction for authorized users
if (dap_config_get_item_bool_default( g_config,
"cdb_auth",
"tx_cond_create",
false)) {
// Parse tx cond templates
size_t l_tx_cond_tpls_count=0;
char ** l_tx_cond_tpls =dap_config_get_array_str( g_config,"cdb_auth", "tx_cond_templates",&l_tx_cond_tpls_count);
for ( size_t i = 0 ; i< l_tx_cond_tpls_count; i++){
char * l_wallet_name = NULL;
long double l_value = 0.0L;
char * l_token_ticker = NULL;
char * l_net_name = NULL;
int l_step = 0;
time_t l_min_time = 0;
char * l_tpl_parse_old = l_tx_cond_tpls[i];
size_t l_tx_cond_tpls_count = 0;
/* ! IMPORTANT ! This fetch is single-action and cannot be further reused, since it modifies the stored config data
* ! it also must NOT be freed within this module !
*/
char **l_tx_cond_tpls = dap_config_get_array_str(g_config, "cdb_auth", "tx_cond_templates", &l_tx_cond_tpls_count);
if (l_tx_cond_tpls_count == 0) {
log_it( L_ERROR, "No condition tpl, can't setup auth callback");
return -5;
}
db_auth_set_callbacks(s_auth_callback);
for (size_t i = 0 ; i < l_tx_cond_tpls_count; i++) {
tx_cond_template_t *l_tx_cond_template = DAP_NEW_Z(tx_cond_template_t);
// Parse template entries
for(char * l_tpl_parse = index(l_tx_cond_tpls[i],':'); l_tpl_parse ;l_tpl_parse = index(l_tpl_parse,':') ){
size_t l_tpl_entry_size = l_tpl_parse - l_tpl_parse_old;
if (l_tpl_entry_size){ // if not empty entry
char *l_tpl_entry = DAP_NEW_Z_SIZE(char,l_tpl_entry_size);
strncpy(l_tpl_entry,l_tpl_parse_old,l_tpl_entry_size-1);
switch ( l_step) { // Parse entries by order
case 0: l_wallet_name = l_tpl_entry; break;
case 1: l_value = strtold( l_tpl_entry, NULL); DAP_DELETE( l_tpl_entry); break;
case 2: l_min_time =(time_t) atoll(l_tpl_entry); DAP_DELETE( l_tpl_entry); break;
case 3: l_token_ticker = l_tpl_entry; break;
case 4: l_net_name = l_tpl_entry; break;
default: log_it( L_WARNING, "Too many ':' (%d) characters in condition template", l_step);
short l_step = 0;
char *ctx;
for (char *l_tpl_token = strtok_r(l_tx_cond_tpls[i], ":", &ctx); l_tpl_token || l_step == 5; l_tpl_token = strtok_r(NULL, ":", &ctx), ++l_step) {
switch (l_step) {
case 0:
if(!(l_tx_cond_template->wallet = dap_chain_wallet_open(l_tpl_token, c_wallets_path))) {
log_it(L_ERROR, "Can't open wallet \"%s\"", l_tpl_token);
DAP_DELETE(l_tx_cond_template);
break;
}
l_step++;
if( l_step > 4)
l_tx_cond_template->wallet_name = l_tpl_token;
continue;
case 1:
if (!(l_tx_cond_template->value_coins = strtold(l_tpl_token, NULL))) {
log_it(L_ERROR, "Error parsing tpl: text on 2nd position \"%s\" is not a number", l_tpl_token);
DAP_DELETE(l_tx_cond_template->wallet);
DAP_DELETE(l_tx_cond_template);
l_step = 0;
break;
}
l_tx_cond_template->value_datoshi = dap_chain_coins_to_balance(l_tx_cond_template->value_coins);
continue;
case 2:
if (!(l_tx_cond_template->min_time = (time_t)atoll(l_tpl_token))) {
log_it(L_ERROR, "Error parsing tpl: text on 3d position \"%s\" is not a number", l_tpl_token);
DAP_DELETE(l_tx_cond_template->wallet);
DAP_DELETE(l_tx_cond_template);
l_step = 0;
break;
}
continue;
case 3:
dap_stpcpy(l_tx_cond_template->token_ticker, l_tpl_token);
continue;
case 4:
if (!(l_tx_cond_template->net = dap_chain_net_by_name(l_tpl_token))
|| !(l_tx_cond_template->ledger = dap_chain_ledger_by_net_name(l_tpl_token)))
{
log_it(L_ERROR, "Can't open network \"%s\" or ledger in it", l_tpl_token);
DAP_DELETE(l_tx_cond_template->wallet);
DAP_DELETE(l_tx_cond_template);
l_step = 0;
break;
}
l_tpl_parse_old = l_tpl_parse;
}
// If all what we need is present
if ( l_step >4 ) {
if ( l_wallet_name && l_value > 0.0L && l_token_ticker && l_net_name && l_min_time){
// we create condition template
tx_cond_template_t * l_tx_cond_template = DAP_NEW_Z(tx_cond_template_t);
l_tx_cond_template->wallet = dap_chain_wallet_open( l_wallet_name,c_wallets_path );
if( l_tx_cond_template->wallet){
l_tx_cond_template->wallet_name = l_wallet_name;
l_tx_cond_template->net = dap_chain_net_by_name( l_net_name );
if ( l_tx_cond_template->net){
l_tx_cond_template->net_name = l_net_name;
l_tx_cond_template->ledger = dap_chain_ledger_by_net_name( l_net_name );
if ( l_tx_cond_template->ledger ){
l_tx_cond_template->min_time = l_min_time;
l_tx_cond_template->value_coins = l_value;
l_tx_cond_template->value_datoshi = dap_chain_coins_to_balance ( l_value );
l_tx_cond_template->token_ticker = l_token_ticker;
// and put it in list
l_tx_cond_template->prev = s_tx_cond_templates;
if ( s_tx_cond_templates)
s_tx_cond_templates->next = l_tx_cond_template;
s_tx_cond_templates = l_tx_cond_template;
}else{
log_it(L_ERROR, "Can't open ledger in network \"%s\" for condition transaction template \"%s\"", l_net_name, l_tx_cond_tpls[i]);
DAP_DELETE( l_wallet_name );
DAP_DELETE( l_net_name);
DAP_DELETE( l_token_ticker);
DAP_DELETE( l_tx_cond_template);
l_tx_cond_template = NULL;
ret = -4;
}
}else{
log_it(L_ERROR, "Can't open network \"%s\" for condition transaction template \"%s\"", l_net_name, l_tx_cond_tpls[i]);
DAP_DELETE( l_wallet_name );
DAP_DELETE( l_net_name);
DAP_DELETE( l_token_ticker);
DAP_DELETE( l_tx_cond_template);
l_tx_cond_template = NULL;
ret = -2;
}
}else{
log_it(L_ERROR, "Can't open wallet \"%s\" for condition transaction template \"%s\"", l_wallet_name, l_tx_cond_tpls[i]);
DAP_DELETE( l_wallet_name );
DAP_DELETE( l_net_name);
DAP_DELETE( l_token_ticker);
DAP_DELETE( l_tx_cond_template);
l_tx_cond_template = NULL;
ret = -3;
}
l_tx_cond_template->net_name = l_tpl_token;
continue;
case 5:
log_it(L_INFO, "Condition template correct, added to list");
DL_APPEND(s_tx_cond_templates, l_tx_cond_template);
break;
default:
break;
}
log_it(L_DEBUG, "Done with tpl item %d", i);
break; // double break exits tokenizer loop and steps to next tpl item
}
}
if ( l_tx_cond_tpls_count )
db_auth_set_callbacks( s_auth_callback );
else{
log_it( L_ERROR, "No condition tpl, can't setup auth callback");
ret=-1;
}
if (!s_tx_cond_templates) ret = -1;
} else {
log_it(L_INFO, "No conditional transactions, provide VPN service for free");
}
}
return ret;
}
......@@ -248,68 +230,78 @@ static void s_auth_callback(enc_http_delegate_t* a_delegate, void * a_arg)
{
#ifndef __ANDROID__
db_auth_info_t *l_auth_info = (db_auth_info_t *) a_arg;
dap_enc_key_t *l_client_key;
log_it( L_DEBUG, "Authorized, now need to create conditioned transaction if not present");
{
size_t l_pkey_b64_length = strlen(l_auth_info->pkey);
byte_t l_pkey_raw[l_pkey_b64_length];
memset(l_pkey_raw, 0, l_pkey_b64_length);
size_t l_pkey_raw_size =
dap_enc_base64_decode(l_auth_info->pkey, l_pkey_b64_length, l_pkey_raw, DAP_ENC_DATA_TYPE_B64_URLSAFE);
char l_pkey_gdb_group[sizeof(DAP_CHAIN_NET_SRV_VPN_CDB_GDB_PREFIX) + 8] = { '\0' };
dap_snprintf(l_pkey_gdb_group, "%s.pkey", DAP_CHAIN_NET_SRV_VPN_CDB_GDB_PREFIX);
log_it(L_DEBUG, "2791: pkey group %s", l_pkey_gdb_group);
dap_chain_global_db_gr_set(l_auth_info->user, l_pkey_raw, l_pkey_raw_size, l_pkey_gdb_group);
l_client_key = dap_enc_key_deserealize(l_pkey_raw, l_pkey_raw_size);
}
size_t l_pkey_b64_length = strlen(l_auth_info->pkey);
byte_t * l_pkey_raw = DAP_NEW_Z_SIZE(byte_t,l_pkey_b64_length );
size_t l_pkey_raw_size = dap_enc_base64_decode(l_auth_info->pkey,l_pkey_b64_length,l_pkey_raw, DAP_ENC_DATA_TYPE_B64_URLSAFE );
char * l_pkey_gdb_group = dap_strdup_printf("%s.pkey", DAP_CHAIN_NET_SRV_VPN_CDB_GDB_PREFIX );
dap_chain_global_db_gr_set( l_auth_info->user , l_pkey_raw, l_pkey_raw_size,l_pkey_gdb_group);
dap_enc_key_t *l_client_key = dap_enc_key_deserealize(l_pkey_raw, l_pkey_raw_size);
for ( tx_cond_template_t * l_tpl = s_tx_cond_templates; l_tpl; l_tpl=l_tpl->next) {
size_t l_gdb_group_size=0;
tx_cond_template_t *l_tpl;
DL_FOREACH(s_tx_cond_templates, l_tpl) {
size_t l_gdb_group_size = 0;
// Try to load from gdb
char * l_tx_cond_gdb_group = dap_strdup_printf("%s.%s.tx_cond", l_tpl->net->pub.name, DAP_CHAIN_NET_SRV_VPN_CDB_GDB_PREFIX );
dap_chain_hash_fast_t * l_tx_cond_hash = (dap_hash_type_t*) dap_chain_global_db_gr_get(
l_auth_info->user,&l_gdb_group_size, l_tx_cond_gdb_group );
char l_tx_cond_gdb_group[128] = {'\0'};
dap_snprintf(l_tx_cond_gdb_group, "%s.%s.tx_cond", l_tpl->net->pub.name, DAP_CHAIN_NET_SRV_VPN_CDB_GDB_PREFIX);
log_it(L_DEBUG, "2791: Checkout group %s", l_tx_cond_gdb_group);
dap_chain_hash_fast_t *l_tx_cond_hash =
(dap_hash_type_t*)dap_chain_global_db_gr_get(l_auth_info->user, &l_gdb_group_size, l_tx_cond_gdb_group);
// Check for entry size
if (l_gdb_group_size && l_gdb_group_size != sizeof (dap_chain_hash_fast_t) ){
log_it(L_ERROR, "Wrong size of tx condition on database (%zd but expected %zd), may be old entry",
l_gdb_group_size, sizeof (dap_chain_hash_fast_t));
if (l_gdb_group_size && l_gdb_group_size != sizeof(dap_chain_hash_fast_t)) {
log_it(L_ERROR, "Wrong size of tx condition on database (%zd but expected %zd), may be old entry",
l_gdb_group_size, sizeof(dap_chain_hash_fast_t));
}
time_t l_tx_cond_ts = 0;
// If loaded lets check is it spent or not
if ( l_tx_cond_hash ){
dap_chain_datum_tx_t * l_tx = dap_chain_net_get_tx_by_hash( l_tpl->net, l_tx_cond_hash, TX_SEARCH_TYPE_NET_UNSPENT );
if ( ! l_tx ){ // If not found - all outs are used. Create new one
log_it(L_DEBUG, "2791: Search for unspent tx, net %s", l_tpl->net_name);
dap_chain_datum_tx_t *l_tx = dap_chain_net_get_tx_by_hash(l_tpl->net, l_tx_cond_hash, TX_SEARCH_TYPE_NET_UNSPENT);
if ( !l_tx ){ // If not found - all outs are used. Create new one
// pass all chains
l_tx = dap_chain_net_get_tx_by_hash( l_tpl->net, l_tx_cond_hash, TX_SEARCH_TYPE_NET );
l_tx = dap_chain_net_get_tx_by_hash(l_tpl->net, l_tx_cond_hash, TX_SEARCH_TYPE_NET);
DAP_DELETE(l_tx_cond_hash);
l_tx_cond_hash = NULL;
if ( l_tx ){
l_tx_cond_ts =(time_t) l_tx->header.ts_created;
log_it(L_DEBUG, "2791: got some tx, created %d", l_tx->header.ts_created);
}
}
}
// Try to create condition
if (! l_tx_cond_hash ) {
// test
log_it(L_DEBUG, "2791: Create a tx");
dap_chain_wallet_t *l_wallet_from = l_tpl->wallet;
log_it(L_DEBUG, "2791: From wallet %s", l_wallet_from->name);
dap_enc_key_t *l_key_from = dap_chain_wallet_get_key(l_wallet_from, 0);
// where to take coins for service
dap_chain_addr_t *l_addr_from = dap_chain_wallet_get_addr(l_wallet_from, l_tpl->net->pub.id );
dap_chain_addr_t *l_addr_from = dap_chain_wallet_get_addr(l_wallet_from, l_tpl->net->pub.id);
dap_chain_net_srv_price_unit_uid_t l_price_unit = { .enm = SERV_UNIT_SEC };
dap_chain_net_srv_uid_t l_srv_uid = { .uint64 = DAP_CHAIN_NET_SRV_VPN_ID };
l_tx_cond_hash= dap_chain_mempool_tx_create_cond( l_tpl->net, l_key_from,l_client_key, l_addr_from,l_tpl->token_ticker,
(uint64_t) l_tpl->value_datoshi , 0,l_price_unit,l_srv_uid, 0,NULL, 0);
char * l_addr_from_str =dap_chain_addr_to_str( l_addr_from );
l_tx_cond_hash = dap_chain_mempool_tx_create_cond(l_tpl->net, l_key_from, l_client_key, l_addr_from, l_tpl->token_ticker,
(uint64_t) l_tpl->value_datoshi, 0, l_price_unit, l_srv_uid, 0, NULL, 0);
char *l_addr_from_str = dap_chain_addr_to_str( l_addr_from );
DAP_DELETE( l_addr_from);
if ( l_tx_cond_hash == NULL ){
log_it( L_ERROR, "Can't create condiftion for user");
}else
log_it( L_NOTICE, "User \"%s\": created conditioned transaction from %s(%s) on "
, l_auth_info->user, l_tpl->wallet_name, l_addr_from_str
);
if (!l_tx_cond_hash) {
log_it(L_ERROR, "Can't create condiftion for user");
} else {
log_it(L_NOTICE, "User \"%s\": created conditioned transaction from %s(%s) on "
, l_auth_info->user, l_tpl->wallet_name, l_addr_from_str);
}
DAP_DELETE( l_addr_from_str );
}
// If we loaded or created hash
......@@ -323,9 +315,9 @@ static void s_auth_callback(enc_http_delegate_t* a_delegate, void * a_arg)
DAP_DELETE(l_tx_cond_hash_str);
}
enc_http_reply_f(a_delegate,"\t</tx_cond_tpl>\n");
}
}
if (l_client_key)
DAP_DELETE( l_client_key);
DAP_DELETE(l_client_key);
#endif
}