Skip to content
Snippets Groups Projects
Commit 5475ce38 authored by Dmitriy A. Gerasimov's avatar Dmitriy A. Gerasimov
Browse files

[+] Check and prepare for conditioned transactions for authorized users

parent 5d22d624
No related branches found
No related tags found
No related merge requests found
......@@ -22,10 +22,9 @@
You should have received a copy of the GNU General Public License
along with any CellFrame SDK based project. If not, see <http://www.gnu.org/licenses/>.
*/
#include "utlist.h"
#include "dap_common.h"
#include "dap_config.h"
#include "dap_chain.h"
#include "dap_enc_http.h"
#include "dap_http.h"
......@@ -34,6 +33,21 @@
#include "db_http.h"
#include "db_http_file.h"
#include "dap_chain.h"
#include "dap_chain_net.h"
#include "dap_chain_ledger.h"
#include "dap_chain_wallet.h"
#include "dap_chain_datum_tx.h"
#include "dap_chain_datum_tx_in.h"
#include "dap_chain_datum_tx_in_cond.h"
#include "dap_chain_datum_tx_out_cond.h"
#include "dap_chain_datum_tx_out.h"
#include "dap_chain_datum_tx_pkey.h"
#include "dap_chain_datum_tx_receipt.h"
#include "dap_chain_datum_tx_sig.h"
#include "dap_chain_global_db.h"
#include "dap_pkey.h"
#include "dap_chain_net_srv_vpn_cdb.h"
#include "dap_chain_net_srv_vpn_cdb_server_list.h"
......@@ -44,6 +58,26 @@
#define DB_FILE_URL "/db_file"
#define SLIST_URL "/nodelist"
typedef struct tx_cond_template{
char * wallet_name;
dap_chain_wallet_t * wallet;
long double value_coins;
uint128_t value_datoshi;
char * token_ticker;
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;
} tx_cond_template_t;
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);
/**
......@@ -53,6 +87,8 @@ static void s_auth_callback(enc_http_delegate_t* a_delegate, void * a_arg);
int dap_chain_net_srv_vpn_cdb_init(dap_http_t * a_http)
{
int rc;
int ret=0;
c_wallets_path = dap_chain_wallet_get_path(g_config);
if (dap_config_get_item_bool_default( g_config,
"cdb",
"servers_list_enabled",
......@@ -72,9 +108,6 @@ int dap_chain_net_srv_vpn_cdb_init(dap_http_t * a_http)
log_it(L_CRITICAL,"Can't init CDB module, return code %d",rc);
return -3;
}
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") );
}
db_http_add_proc( a_http , DB_URL );
db_http_file_proc_add( a_http , DB_FILE_URL );
......@@ -85,15 +118,109 @@ 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) ){
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)) {
// Produce transaction for authorized users
if (dap_config_get_item_bool_default( g_config,
"cdb",
"tx_cond_create",
false)) {
db_auth_set_callbacks( s_auth_callback );
// 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];
// 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);
}
l_step++;
if( l_step > 4)
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;
}
}
}
}
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;
}
}
}
return 0;
return ret;
}
/**
......@@ -113,5 +240,55 @@ void dap_chain_net_srv_vpn_cdb_deinit()
*/
static void s_auth_callback(enc_http_delegate_t* a_delegate, void * a_arg)
{
db_auth_info_t *l_auth_info = (db_auth_info_t *) a_arg;
log_it( L_DEBUG, "Authorized, now need to create conditioned transaction if not present");
for ( tx_cond_template_t * l_tpl = s_tx_cond_templates; l_tpl; l_tpl=l_tpl->next) {
enc_http_reply_f(a_delegate,"\t<tx_cond_tpl>\n");
enc_http_reply_f(a_delegate,"\t\t<net>%s</net>\n",l_tpl->net_name);
enc_http_reply_f(a_delegate,"\t\t<token>%s</token>\n",l_tpl->token_ticker);
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 );
// 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));
}
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
// pass all chains
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;
}
}
}
// Try to create condition
if (! l_tx_cond_hash ) {
}
// If we loaded or created hash
if( l_tx_cond_hash ){
char * l_tx_cond_hash_str = dap_chain_hash_fast_to_str_new(l_tx_cond_hash);
enc_http_reply_f(a_delegate,"\t\t<tx_cond>%s</tx_cond>\n",l_tx_cond_hash_str);
DAP_DELETE(l_tx_cond_hash);
DAP_DELETE(l_tx_cond_hash_str);
}
enc_http_reply_f(a_delegate,"\t</tx_cond_tpl>\n");
}
}
......@@ -24,5 +24,8 @@
*/
#pragma once
#include "dap_http.h"
#define DAP_CHAIN_NET_SRV_VPN_CDB_GDB_PREFIX "local.srv.vpn"
int dap_chain_net_srv_vpn_cdb_init(dap_http_t * a_http);
void dap_chain_net_srv_vpn_cdb_deinit();
......@@ -61,7 +61,7 @@ int dap_chain_net_srv_vpn_cdb_server_list_init()
char **l_cdb_networks;
uint16_t l_cdb_networks_count = 0;
log_it(L_NOTICE,"Initialized Server List Module");
l_cdb_networks = dap_config_get_array_str( g_config, "cdb", "networks", &l_cdb_networks_count );
l_cdb_networks = dap_config_get_array_str( g_config, "cdb", "servers_list_networks", &l_cdb_networks_count );
if ( l_cdb_networks_count ){
s_cdb_net = DAP_NEW_Z_SIZE(dap_chain_net_t*, sizeof (dap_chain_net_t*)* l_cdb_networks_count );
......@@ -115,6 +115,7 @@ static void s_http_simple_proc(dap_http_simple_t *a_http_simple, void *a_arg)
dap_string_append_printf( l_reply_str, " {\n");
dap_string_append_printf( l_reply_str, " \"Location\":\"NETHERLANDS\",\n");
dap_string_append_printf( l_reply_str, " \"ChainNet\":\"%s\",\n",l_net->pub.name );
dap_string_append_printf( l_reply_str, " \"Name\":\"%s.Cell-%lu.%zd\",\n",l_net->pub.name, l_node_info->hdr.cell_id.uint64, j);
if ( l_node_ext_ipv4_str[0] )
dap_string_append_printf( l_reply_str," \"Address\":\"%s\",\n",l_node_ext_ipv4_str);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment