diff --git a/modules/chain/dap_chain_ledger.c b/modules/chain/dap_chain_ledger.c index 9bfd287bca26310bf6a2c346afcfcd9d87cf5316..db38b05ab6b64d751d3bbb0df1033f71b690f3b4 100644 --- a/modules/chain/dap_chain_ledger.c +++ b/modules/chain/dap_chain_ledger.c @@ -50,6 +50,7 @@ #include "dap_strfuncs.h" #include "dap_config.h" #include "dap_cert.h" +#include "dap_timerfd.h" #include "dap_chain_datum_tx_token.h" #include "dap_chain_datum_token.h" #include "dap_chain_mempool.h" @@ -201,17 +202,24 @@ typedef struct dap_ledger_private { dap_chain_cell_id_t local_cell_id; bool load_mode; + // TPS section + dap_timerfd_t *tps_timer; + struct timespec tps_start_time; + struct timespec tps_current_time; + struct timespec tps_end_time; + size_t tps_count; } dap_ledger_private_t; #define PVT(a) ( (dap_ledger_private_t* ) a->_internal ) static dap_chain_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr, const char * a_token, dap_chain_hash_fast_t *a_tx_first_hash); - static void s_treshold_emissions_proc( dap_ledger_t * a_ledger); static void s_treshold_txs_proc( dap_ledger_t * a_ledger); static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_item_t *a_token_item , dap_chain_datum_token_t * a_token, size_t a_token_size); static int s_ledger_permissions_check(dap_chain_ledger_token_item_t * a_token_item, uint16_t a_permission_id, const void * a_data,size_t a_data_size ); +static bool s_ledger_tps_callback(void *a_arg); + static size_t s_treshold_emissions_max = 1000; static size_t s_treshold_txs_max = 10000; static bool s_debug_more = false; @@ -1148,6 +1156,8 @@ dap_ledger_t* dap_chain_ledger_create(uint16_t a_check_flags, char *a_net_name) log_it(L_DEBUG,"Created ledger \"%s\"",a_net_name); l_ledger_priv->load_mode = true; + l_ledger_priv->tps_timer = NULL; + l_ledger_priv->tps_count = 0; if (dap_config_get_item_bool_default(g_config, "ledger", "cached", true)) { // load ledger cache from GDB dap_chain_ledger_load_cache(l_ledger); @@ -2238,6 +2248,13 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_list_t *l_list_tx_out = NULL; dap_chain_ledger_tx_item_t *l_item_tmp = NULL; + if (!l_ledger_priv->tps_timer) { + clock_gettime(CLOCK_REALTIME, &l_ledger_priv->tps_start_time); + l_ledger_priv->tps_current_time.tv_sec = l_ledger_priv->tps_start_time.tv_sec; + l_ledger_priv->tps_current_time.tv_nsec = l_ledger_priv->tps_start_time.tv_nsec; + l_ledger_priv->tps_count = 0; + l_ledger_priv->tps_timer = dap_timerfd_start(500, s_ledger_tps_callback, l_ledger_priv); + } dap_chain_hash_fast_t *l_tx_hash = dap_chain_node_datum_tx_calc_hash(a_tx); char l_tx_hash_str[70]; dap_chain_hash_fast_to_str(l_tx_hash,l_tx_hash_str,sizeof(l_tx_hash_str)); @@ -2540,7 +2557,7 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, l_item_tmp = DAP_NEW_Z(dap_chain_ledger_tx_item_t); memcpy(&l_item_tmp->tx_hash_fast, l_tx_hash, sizeof(dap_chain_hash_fast_t)); l_item_tmp->tx = DAP_NEW_SIZE(dap_chain_datum_tx_t, dap_chain_datum_tx_get_size(a_tx)); - l_item_tmp->cache_data.ts_created = (time_t) a_tx->header.ts_created; + l_item_tmp->cache_data.ts_created = time(NULL); // Time of transasction added to ledger dap_list_t *l_tist_tmp = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_OUT_ALL, &l_item_tmp->cache_data.n_outs); // If debug mode dump the UTXO if (dap_log_level_get() == L_DEBUG && s_debug_more) { @@ -2569,7 +2586,9 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, pthread_rwlock_wrlock(&l_ledger_priv->ledger_rwlock); 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 pthread_rwlock_unlock(&l_ledger_priv->ledger_rwlock); - + // Count TPS + clock_gettime(CLOCK_REALTIME, &l_ledger_priv->tps_end_time); + l_ledger_priv->tps_count++; // Add it to cache uint8_t *l_tx_cache = DAP_NEW_Z_SIZE(uint8_t, l_tx_size + sizeof(l_item_tmp->cache_data)); memcpy(l_tx_cache, &l_item_tmp->cache_data, sizeof(l_item_tmp->cache_data)); @@ -2590,6 +2609,19 @@ FIN: return ret; } +static bool s_ledger_tps_callback(void *a_arg) +{ + dap_ledger_private_t *l_ledger_pvt = (dap_ledger_private_t *)a_arg; + if (l_ledger_pvt->tps_current_time.tv_sec != l_ledger_pvt->tps_end_time.tv_sec || + l_ledger_pvt->tps_current_time.tv_nsec != l_ledger_pvt->tps_end_time.tv_nsec) { + l_ledger_pvt->tps_current_time.tv_sec = l_ledger_pvt->tps_end_time.tv_sec; + l_ledger_pvt->tps_current_time.tv_nsec = l_ledger_pvt->tps_end_time.tv_nsec; + return true; + } + l_ledger_pvt->tps_timer = NULL; + return false; +} + int dap_chain_ledger_tx_load(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx) { if (PVT(a_ledger)->load_mode) { @@ -2672,7 +2704,6 @@ int dap_chain_ledger_tx_remove(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_ void dap_chain_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db) { dap_ledger_private_t *l_ledger_priv = PVT(a_ledger); - const int l_hash_str_size = DAP_CHAIN_HASH_FAST_SIZE * 2 + 2; pthread_rwlock_wrlock(&l_ledger_priv->ledger_rwlock); pthread_rwlock_wrlock(&l_ledger_priv->tokens_rwlock); pthread_rwlock_wrlock(&l_ledger_priv->treshold_emissions_rwlock); @@ -2814,6 +2845,22 @@ uint64_t dap_chain_ledger_count_from_to(dap_ledger_t * a_ledger, time_t a_ts_fro return l_ret; } +size_t dap_chain_ledger_count_tps(dap_ledger_t *a_ledger, struct timespec *a_ts_from, struct timespec *a_ts_to) +{ + if (!a_ledger) + return 0; + dap_ledger_private_t *l_ledger_priv = PVT(a_ledger); + if (a_ts_from) { + a_ts_from->tv_sec = l_ledger_priv->tps_start_time.tv_sec; + a_ts_from->tv_nsec = l_ledger_priv->tps_start_time.tv_nsec; + } + if (a_ts_to) { + a_ts_to->tv_sec = l_ledger_priv->tps_end_time.tv_sec; + a_ts_to->tv_nsec = l_ledger_priv->tps_end_time.tv_nsec; + } + return l_ledger_priv->tps_count; +} + /** * Check whether used 'out' items */ diff --git a/modules/chain/include/dap_chain_ledger.h b/modules/chain/include/dap_chain_ledger.h index cce692b50d1f4f8679ad51373e1236c2195ea6f6..2896e6cd396c433c62a0c21f6bb3fd17d2f236ca 100644 --- a/modules/chain/include/dap_chain_ledger.h +++ b/modules/chain/include/dap_chain_ledger.h @@ -175,6 +175,7 @@ void dap_chain_ledger_load_end(dap_ledger_t *a_ledger); unsigned dap_chain_ledger_count(dap_ledger_t *a_ledger); uint64_t dap_chain_ledger_count_from_to(dap_ledger_t * a_ledger, time_t a_ts_from, time_t a_ts_to ); +size_t dap_chain_ledger_count_tps(dap_ledger_t *a_ledger, struct timespec *a_ts_from, struct timespec *a_ts_to); /** * Check whether used 'out' items diff --git a/modules/global-db/dap_chain_global_db_driver_sqlite.c b/modules/global-db/dap_chain_global_db_driver_sqlite.c index b9060cd5cafd12f93c5ff78426e8b66001076855..334b0d3fd3ecbbb96f48e884a547040374b983f7 100644 --- a/modules/global-db/dap_chain_global_db_driver_sqlite.c +++ b/modules/global-db/dap_chain_global_db_driver_sqlite.c @@ -86,9 +86,9 @@ static int dap_db_driver_sqlite_exec(sqlite3 *l_db, const char *l_query, char ** static sqlite3 *s_sqlite_get_connection(void) { - if (pthread_rwlock_wrlock(&s_db_rwlock) == EDEADLK) { - return NULL; - } + if (pthread_rwlock_wrlock(&s_db_rwlock) == EDEADLK) { + return s_trans; + } sqlite3 *l_ret = NULL; for (int i = 0; i < DAP_SQLITE_POOL_COUNT; i++) { diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c index 4be57955c7b10c687da469d3b7e78ce799b858b9..0581e7e5a59dd0b3b4951a131f1837ef65bcfce6 100644 --- a/modules/net/dap_chain_net.c +++ b/modules/net/dap_chain_net.c @@ -185,6 +185,7 @@ typedef struct dap_chain_net_pvt{ // General rwlock for structure pthread_rwlock_t rwlock; + dap_list_t *notify_callbacks; } dap_chain_net_pvt_t; typedef struct dap_chain_net_item{ @@ -264,8 +265,6 @@ static bool s_seed_mode = false; static uint8_t *dap_chain_net_set_acl(dap_chain_hash_fast_t *a_pkey_hash); -static dap_global_db_obj_callback_notify_t s_srv_callback_notify = NULL; - /** * @brief * init network settings from cellrame-node.cfg file @@ -388,11 +387,12 @@ dap_chain_net_state_t dap_chain_net_get_target_state(dap_chain_net_t *a_net) * * @param a_callback dap_global_db_obj_callback_notify_t callback function */ -void dap_chain_net_set_srv_callback_notify(dap_global_db_obj_callback_notify_t a_callback) +void dap_chain_net_add_notify_callback(dap_chain_net_t *a_net, dap_global_db_obj_callback_notify_t a_callback) { - s_srv_callback_notify = a_callback; + PVT(a_net)->notify_callbacks = dap_list_append(PVT(a_net)->notify_callbacks, a_callback); } + /** * @brief if current network in ONLINE state send to all connected node * executes, when you add data to gdb chain (class=gdb in chain config) @@ -459,16 +459,17 @@ void dap_chain_net_sync_gdb_broadcast(void *a_arg, const char a_op_code, const c * @param a_value buffer with data * @param a_value_len buffer size */ -static void s_gbd_history_callback_notify (void * a_arg, const char a_op_code, const char * a_group, - const char * a_key, const void * a_value, const size_t a_value_len) +static void s_gbd_history_callback_notify(void *a_arg, const char a_op_code, const char *a_group, + const char *a_key, const void *a_value, const size_t a_value_len) { if (!a_arg) { return; } - dap_chain_node_mempool_autoproc_notify(a_arg, a_op_code, a_group, a_key, a_value, a_value_len); - dap_chain_net_sync_gdb_broadcast(a_arg, a_op_code, a_group, a_key, a_value, a_value_len); - if (s_srv_callback_notify) { - s_srv_callback_notify(a_arg, a_op_code, a_group, a_key, a_value, a_value_len); + dap_chain_net_t *l_net = (dap_chain_net_t *)a_arg; + for (dap_list_t *it = PVT(l_net)->notify_callbacks; it; it = PVT(l_net)->notify_callbacks->next) { + dap_global_db_obj_callback_notify_t l_callback = (dap_global_db_obj_callback_notify_t)it->data; + if (l_callback) + l_callback(a_arg, a_op_code, a_group, a_key, a_value, a_value_len); } } @@ -1539,60 +1540,42 @@ static int s_cli_net(int argc, char **argv, char **a_str_reply) if ( !dap_strcmp(l_sync_mode_str,"all") ) dap_chain_net_get_flag_sync_from_zero(l_net); - if ( l_stats_str ){ - if ( strcmp(l_stats_str,"tx") == 0 ) { + if (l_stats_str) { + char l_from_str_new[50], l_to_str_new[50]; + const char c_time_fmt[]="%Y-%m-%d_%H:%M:%S"; + struct tm l_from_tm = {}, l_to_tm = {}; + if (strcmp(l_stats_str,"tx") == 0) { const char *l_to_str = NULL; - struct tm l_to_tm = {0}; - const char *l_from_str = NULL; - struct tm l_from_tm = {0}; - const char *l_prev_sec_str = NULL; - //time_t l_prev_sec_ts; - - const char c_time_fmt[]="%Y-%m-%d_%H:%M:%S"; - // Read from/to time dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-from", &l_from_str); dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-to", &l_to_str); dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-prev_sec", &l_prev_sec_str); - - if (l_from_str ) { + time_t l_ts_now = time(NULL); + if (l_from_str) { strptime( (char *)l_from_str, c_time_fmt, &l_from_tm ); - } - - if (l_to_str) { - strptime( (char *)l_to_str, c_time_fmt, &l_to_tm ); - } - - if ( l_to_str == NULL ){ // If not set '-to' - we set up current time - time_t l_ts_now = time(NULL); - localtime_r(&l_ts_now, &l_to_tm); - } - - if ( l_prev_sec_str ){ - time_t l_ts_now = time(NULL); + if (l_to_str) { + strptime( (char *)l_to_str, c_time_fmt, &l_to_tm ); + } else { // If not set '-to' - we set up current time + localtime_r(&l_ts_now, &l_to_tm); + } + } else if (l_prev_sec_str) { l_ts_now -= strtol( l_prev_sec_str, NULL,10 ); localtime_r(&l_ts_now, &l_from_tm ); - }/*else if ( l_from_str == NULL ){ // If not set '-from' we set up current time minus 10 seconds - time_t l_ts_now = time(NULL); - l_ts_now -= 10; + } else if ( l_from_str == NULL ) { // If not set '-from' we set up current time minus 60 seconds + l_ts_now -= 60; localtime_r(&l_ts_now, &l_from_tm ); - }*/ - + } // Form timestamps from/to time_t l_from_ts = mktime(&l_from_tm); time_t l_to_ts = mktime(&l_to_tm); - // Produce strings char l_from_str_new[50]; char l_to_str_new[50]; strftime(l_from_str_new, sizeof(l_from_str_new), c_time_fmt,&l_from_tm ); strftime(l_to_str_new, sizeof(l_to_str_new), c_time_fmt,&l_to_tm ); - - dap_string_t * l_ret_str = dap_string_new("Transactions statistics:\n"); - dap_string_append_printf( l_ret_str, "\tFrom: %s\tTo: %s\n", l_from_str_new, l_to_str_new); log_it(L_INFO, "Calc TPS from %s to %s", l_from_str_new, l_to_str_new); uint64_t l_tx_count = dap_chain_ledger_count_from_to ( l_net->pub.ledger, l_from_ts, l_to_ts); @@ -1602,6 +1585,27 @@ static int s_cli_net(int argc, char **argv, char **a_str_reply) dap_string_append_printf( l_ret_str, "\tTotal: %"DAP_UINT64_FORMAT_U"\n", l_tx_count ); dap_chain_node_cli_set_reply_text( a_str_reply, l_ret_str->str ); dap_string_free( l_ret_str, false ); + } else if (strcmp(l_stats_str, "tps") == 0) { + struct timespec l_from_time_acc = {}, l_to_time_acc = {}; + dap_string_t * l_ret_str = dap_string_new("Transactions per second peak values:\n"); + size_t l_tx_num = dap_chain_ledger_count_tps(l_net->pub.ledger, &l_from_time_acc, &l_to_time_acc); + if (l_tx_num) { + localtime_r(&l_from_time_acc.tv_sec, &l_from_tm); + strftime(l_from_str_new, sizeof(l_from_str_new), c_time_fmt, &l_from_tm); + localtime_r(&l_to_time_acc.tv_sec, &l_to_tm); + strftime(l_to_str_new, sizeof(l_to_str_new), c_time_fmt, &l_to_tm); + dap_string_append_printf(l_ret_str, "\tFrom: %s\tTo: %s\n", l_from_str_new, l_to_str_new); + uint64_t l_diff_ns = (l_to_time_acc.tv_sec - l_from_time_acc.tv_sec) * 1000000000 + + l_to_time_acc.tv_nsec - l_from_time_acc.tv_nsec; + long double l_tps = (long double)(l_tx_num * 1000000000) / (long double)(l_diff_ns); + dap_string_append_printf(l_ret_str, "\tSpeed: %.3Lf TPS\n", l_tps); + } + dap_string_append_printf(l_ret_str, "\tTotal: %zu\n", l_tx_num); + dap_chain_node_cli_set_reply_text(a_str_reply, l_ret_str->str); + dap_string_free(l_ret_str, false); + } else { + dap_chain_node_cli_set_reply_text(a_str_reply, + "Subcommand 'stats' requires one of parameter: tx, tps\n"); } } else if ( l_go_str){ if ( strcmp(l_go_str,"online") == 0 ) { @@ -1615,16 +1619,17 @@ static int s_cli_net(int argc, char **argv, char **a_str_reply) c_net_states[NET_STATE_OFFLINE]); dap_chain_net_state_go_to(l_net, NET_STATE_OFFLINE); - } - else if(strcmp(l_go_str, "sync") == 0) { + } else if (strcmp(l_go_str, "sync") == 0) { dap_chain_node_cli_set_reply_text(a_str_reply, "Network \"%s\" resynchronizing", l_net->pub.name); if (PVT(l_net)->state_target == NET_STATE_ONLINE) dap_chain_net_state_go_to(l_net, NET_STATE_ONLINE); else dap_chain_net_state_go_to(l_net, NET_STATE_SYNC_CHAINS); + } else { + dap_chain_node_cli_set_reply_text(a_str_reply, + "Subcommand 'go' requires one of parameters: online, offline, sync\n"); } - } else if ( l_get_str){ if ( strcmp(l_get_str,"status") == 0 ) { s_set_reply_text_node_status(a_str_reply, l_net); @@ -1679,7 +1684,7 @@ static int s_cli_net(int argc, char **argv, char **a_str_reply) dap_chain_node_cli_set_reply_text(a_str_reply,"Stopped network\n"); }else { dap_chain_node_cli_set_reply_text(a_str_reply, - "Subcommand \"link\" requires one of parameter: list\n"); + "Subcommand 'link' requires one of parameters: list, add, del, info, disconnect_all\n"); ret = -3; } @@ -1705,7 +1710,7 @@ static int s_cli_net(int argc, char **argv, char **a_str_reply) } else { dap_chain_node_cli_set_reply_text(a_str_reply, - "Subcommand \"sync\" requires one of parameter: all,gdb,chains\n"); + "Subcommand 'sync' requires one of parameters: all, gdb, chains\n"); ret = -2; } } else if (l_ca_str) { @@ -1808,7 +1813,7 @@ static int s_cli_net(int argc, char **argv, char **a_str_reply) return 0; } else { dap_chain_node_cli_set_reply_text(a_str_reply, - "Subcommand \"ca\" requires one of parameter: add, list, del\n"); + "Subcommand 'ca' requires one of parameter: add, list, del\n"); ret = -5; } } else if (l_ledger_str && !strcmp(l_ledger_str, "reload")) { @@ -1837,7 +1842,7 @@ static int s_cli_net(int argc, char **argv, char **a_str_reply) } while (l_processed); } else { dap_chain_node_cli_set_reply_text(a_str_reply, - "Command requires one of subcomand: sync, link, go, get, stats, ca, ledger"); + "Command 'net' requires one of subcomands: sync, link, go, get, stats, ca, ledger"); ret = -1; } @@ -2376,7 +2381,7 @@ int s_net_load(const char * a_net_name, uint16_t a_acl_idx) } l_net_pvt->load_mode = false; dap_chain_ledger_load_end(l_net->pub.ledger); - + dap_chain_net_add_notify_callback(l_net, dap_chain_net_sync_gdb_broadcast); if (l_target_state != l_net_pvt->state_target) dap_chain_net_state_go_to(l_net, l_target_state); diff --git a/modules/net/dap_chain_node.c b/modules/net/dap_chain_node.c index 89717fd4ef0ba0625676ba415370353baca2a0ef..f5e31813c9322d7f554410cae2c1a3bd61c197b7 100644 --- a/modules/net/dap_chain_node.c +++ b/modules/net/dap_chain_node.c @@ -291,6 +291,7 @@ bool dap_chain_node_mempool_autoproc_init() } DAP_DELETE(l_gdb_group_mempool); } + dap_chain_net_add_notify_callback(l_net_list[i], dap_chain_node_mempool_autoproc_notify); } } DAP_DELETE(l_net_list); diff --git a/modules/net/dap_chain_node_client.c b/modules/net/dap_chain_node_client.c index 1c385006668366fb5971a8bc196ccdd5898f3939..f8fae3e93022a16c582dbc182ecc405396291cc4 100644 --- a/modules/net/dap_chain_node_client.c +++ b/modules/net/dap_chain_node_client.c @@ -978,7 +978,8 @@ int dap_chain_node_client_set_callbacks(dap_client_t *a_client, uint8_t a_ch_id) if(a_ch_id == dap_stream_ch_chain_net_srv_get_id()) { dap_stream_ch_chain_net_srv_t *l_ch_chain = DAP_STREAM_CH_CHAIN_NET_SRV(l_ch); if (l_node_client->callbacks.srv_pkt_in) { - l_ch_chain->notify_callback = l_node_client->callbacks.srv_pkt_in; + l_ch_chain->notify_callback = (dap_stream_ch_chain_net_srv_callback_packet_t) + l_node_client->callbacks.srv_pkt_in; l_ch_chain->notify_callback_arg = l_node_client->callbacks_arg; } else { l_ch_chain->notify_callback = s_ch_chain_callback_notify_packet_R; diff --git a/modules/net/include/dap_chain_net.h b/modules/net/include/dap_chain_net.h index 59fcfd8b83a3deb9871544e844af55ebe58ec2e6..a9701a173791a6313f2c3404764e50bf1fd6aa2f 100644 --- a/modules/net/include/dap_chain_net.h +++ b/modules/net/include/dap_chain_net.h @@ -176,7 +176,7 @@ bool dap_chain_net_get_add_gdb_group(dap_chain_net_t *a_net, dap_chain_node_addr int dap_chain_net_verify_datum_for_add(dap_chain_net_t *a_net, dap_chain_datum_t * a_datum ); void dap_chain_net_dump_datum(dap_string_t *a_str_out, dap_chain_datum_t *a_datum, const char *a_hash_out_type); -void dap_chain_net_set_srv_callback_notify(dap_global_db_obj_callback_notify_t a_callback); +void dap_chain_net_add_notify_callback(dap_chain_net_t *a_net, dap_global_db_obj_callback_notify_t a_callback); void dap_chain_net_sync_gdb_broadcast(void *a_arg, const char a_op_code, const char *a_group, const char *a_key, const void *a_value, const size_t a_value_len); diff --git a/modules/net/srv/dap_chain_net_srv_order.c b/modules/net/srv/dap_chain_net_srv_order.c index 361a275c2eca7c8912d63c76e93a16bdc8630582..8ba00122c61ca1682b4708ca0fa531d113da87a1 100644 --- a/modules/net/srv/dap_chain_net_srv_order.c +++ b/modules/net/srv/dap_chain_net_srv_order.c @@ -56,6 +56,11 @@ char *s_server_continents[]={ "Antarctica" }; +struct dap_order_notify { + dap_chain_net_t *net; + dap_global_db_obj_callback_notify_t callback; +}; +static dap_list_t *s_order_notify_callbacks = NULL; static void s_srv_order_callback_notify(void *a_arg, const char a_op_code, const char *a_group, const char *a_key, const void *a_value, const size_t a_value_len); @@ -65,7 +70,11 @@ static void s_srv_order_callback_notify(void *a_arg, const char a_op_code, const */ int dap_chain_net_srv_order_init(void) { - dap_chain_net_set_srv_callback_notify(s_srv_order_callback_notify); + uint16_t l_net_count; + dap_chain_net_t **l_net_list = dap_chain_net_list(&l_net_count); + for (uint16_t i = 0; i < l_net_count; i++) { + dap_chain_net_add_notify_callback(l_net_list[i], s_srv_order_callback_notify); + } //geoip_info_t *l_ipinfo = chain_net_geoip_get_ip_info("8.8.8.8"); return 0; } @@ -75,7 +84,7 @@ int dap_chain_net_srv_order_init(void) */ void dap_chain_net_srv_order_deinit() { - + dap_list_free_full(s_order_notify_callbacks, free); } size_t dap_chain_net_srv_order_get_size(dap_chain_net_srv_order_t *a_order) @@ -521,37 +530,54 @@ static void s_srv_order_callback_notify(void *a_arg, const char a_op_code, const const char *a_key, const void *a_value, const size_t a_value_len) { UNUSED(a_value_len); - if (!a_arg || !a_value || a_op_code != 'a' || !dap_config_get_item_bool_default(g_config, "srv", "order_signed_only", false)) { + if (!a_arg || !a_key) { return; } dap_chain_net_t *l_net = (dap_chain_net_t *)a_arg; char *l_gdb_group_str = dap_chain_net_srv_order_get_gdb_group(l_net); if (!strcmp(a_group, l_gdb_group_str)) { - dap_chain_net_srv_order_t *l_order = (dap_chain_net_srv_order_t *)a_value; - if (l_order->version != 2) { - dap_chain_global_db_gr_del(dap_strdup(a_key), a_group); - } else { - dap_sign_t *l_sign = (dap_sign_t *)&l_order->ext_n_sign[l_order->ext_size]; - if (!dap_sign_verify_size(l_sign, a_value_len) || - dap_sign_verify(l_sign, l_order, sizeof(dap_chain_net_srv_order_t) + l_order->ext_size) != 1) { - dap_chain_global_db_gr_del(dap_strdup(a_key), a_group); - DAP_DELETE(l_gdb_group_str); - return; + for (dap_list_t *it = s_order_notify_callbacks; it; it = s_order_notify_callbacks->next) { + struct dap_order_notify *l_notifier = (struct dap_order_notify *)it->data; + if ((l_notifier->net == NULL || l_notifier->net == l_net) && + l_notifier->callback) { + l_notifier->callback(a_arg, a_op_code, a_group, a_key, a_value, a_value_len); } - /*dap_chain_hash_fast_t l_pkey_hash; - if (!dap_sign_get_pkey_hash(l_sign, &l_pkey_hash)) { + } + if (a_value && a_op_code != 'a' && dap_config_get_item_bool_default(g_config, "srv", "order_signed_only", false)) { + dap_chain_net_srv_order_t *l_order = (dap_chain_net_srv_order_t *)a_value; + if (l_order->version != 2) { dap_chain_global_db_gr_del(dap_strdup(a_key), a_group); - DAP_DELETE(l_gdb_group_str); - return; + } else { + dap_sign_t *l_sign = (dap_sign_t *)&l_order->ext_n_sign[l_order->ext_size]; + if (!dap_sign_verify_size(l_sign, a_value_len) || + dap_sign_verify(l_sign, l_order, sizeof(dap_chain_net_srv_order_t) + l_order->ext_size) != 1) { + dap_chain_global_db_gr_del(dap_strdup(a_key), a_group); + DAP_DELETE(l_gdb_group_str); + return; + } + /*dap_chain_hash_fast_t l_pkey_hash; + if (!dap_sign_get_pkey_hash(l_sign, &l_pkey_hash)) { + dap_chain_global_db_gr_del(dap_strdup(a_key), a_group); + DAP_DELETE(l_gdb_group_str); + return; + } + dap_chain_addr_t l_addr = {}; + dap_chain_addr_fill(&l_addr, l_sign->header.type, &l_pkey_hash, l_net->pub.id); + uint128_t l_balance = dap_chain_ledger_calc_balance(l_net->pub.ledger, &l_addr, l_order->price_ticker); + uint64_t l_solvency = dap_chain_uint128_to(l_balance); + if (l_solvency < l_order->price && !dap_chain_net_srv_stake_key_delegated(&l_addr)) { + dap_chain_global_db_gr_del(dap_strdup(a_key), a_group); + }*/ } - dap_chain_addr_t l_addr = {}; - dap_chain_addr_fill(&l_addr, l_sign->header.type, &l_pkey_hash, l_net->pub.id); - uint128_t l_balance = dap_chain_ledger_calc_balance(l_net->pub.ledger, &l_addr, l_order->price_ticker); - uint64_t l_solvency = dap_chain_uint128_to(l_balance); - if (l_solvency < l_order->price && !dap_chain_net_srv_stake_key_delegated(&l_addr)) { - dap_chain_global_db_gr_del(dap_strdup(a_key), a_group); - }*/ } - DAP_DELETE(l_gdb_group_str); } + DAP_DELETE(l_gdb_group_str); +} + +void dap_chain_net_srv_order_add_notify_callback(dap_chain_net_t *a_net, dap_global_db_obj_callback_notify_t a_callback) +{ + struct dap_order_notify *l_notifier = DAP_NEW(struct dap_order_notify); + l_notifier->net = a_net; + l_notifier->callback = a_callback; + s_order_notify_callbacks = dap_list_append(s_order_notify_callbacks, l_notifier); } diff --git a/modules/net/srv/include/dap_chain_net_srv.h b/modules/net/srv/include/dap_chain_net_srv.h index a66087bb616ca905887e0cca20e0f4eec0abe70c..decccd52e1260d1b7f69895167254010630fbf9a 100755 --- a/modules/net/srv/include/dap_chain_net_srv.h +++ b/modules/net/srv/include/dap_chain_net_srv.h @@ -93,8 +93,8 @@ typedef struct dap_chain_net_srv_client_remote dap_chain_net_remote_t *net_remote; // For remotes uint64_t bytes_received; uint64_t bytes_sent; - struct dap_chain_net_srv_client *prev; - struct dap_chain_net_srv_client *next; + struct dap_chain_net_srv_client_remote *prev; + struct dap_chain_net_srv_client_remote *next; } dap_chain_net_srv_client_remote_t; diff --git a/modules/net/srv/include/dap_chain_net_srv_order.h b/modules/net/srv/include/dap_chain_net_srv_order.h index 5a4d496e0071aa9726dbb2eab5e41b00f13a52a5..bc705106249c6a3920db35ab2e4e89e9a718244c 100644 --- a/modules/net/srv/include/dap_chain_net_srv_order.h +++ b/modules/net/srv/include/dap_chain_net_srv_order.h @@ -128,7 +128,7 @@ char *dap_chain_net_srv_order_create(dap_chain_net_t * a_net, int dap_chain_net_srv_order_save(dap_chain_net_t * a_net, dap_chain_net_srv_order_t *a_order); void dap_chain_net_srv_order_dump_to_string(dap_chain_net_srv_order_t *a_order,dap_string_t * a_str_out, const char *a_hash_out_type); - +void dap_chain_net_srv_order_add_notify_callback(dap_chain_net_t *a_net, dap_global_db_obj_callback_notify_t a_callback); /** * @brief dap_chain_net_srv_order_get_gdb_group_mempool * @param l_chain diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c index 09d11c478ff77fe1badae42dcbebe2f910beab00..3ea4342528cd4cd52f28a931afdf9de514f37aa9 100644 --- a/modules/type/dag/dap_chain_cs_dag.c +++ b/modules/type/dag/dap_chain_cs_dag.c @@ -306,6 +306,10 @@ static void s_dap_chain_cs_dag_purge(dap_chain_t *a_chain) DAP_DELETE(l_event_current); } pthread_rwlock_unlock(&l_dag_pvt->events_rwlock); + dap_chain_cell_t *l_cell_cur, *l_cell_tmp; + HASH_ITER(hh, a_chain->cells, l_cell_cur, l_cell_tmp) { + dap_chain_cell_close(l_cell_cur); + } } /**