diff --git a/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c b/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c index 766da49dfccff3b1fd6ba6c1139aa13e35b3c334..c763ede3377e296c9e3b2692285a56d1f438da8b 100644 --- a/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c +++ b/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c @@ -34,6 +34,7 @@ #endif #include "dap_common.h" +#include "dap_timerfd.h" #include "dap_strfuncs.h" #include "dap_enc_base58.h" #include "dap_chain_pvt.h" @@ -46,6 +47,7 @@ #include "dap_chain_cs_dag_event.h" #include "dap_chain_cs_dag_poa.h" #include "dap_chain_net_srv_stake.h" +#include "dap_chain_cell.h" #include "dap_cert.h" @@ -58,18 +60,39 @@ typedef struct dap_chain_cs_dag_poa_pvt char * auth_certs_prefix; uint16_t auth_certs_count; uint16_t auth_certs_count_verify; // Number of signatures, needed for event verification + uint32_t confirmations_timeout; // wait signs over min value (auth_certs_count_verify) + bool auto_confirmation; + bool auto_round_complete; + uint32_t wait_sync_before_complete; uint8_t padding[4]; dap_chain_callback_new_cfg_t prev_callback_created; // global network config init } dap_chain_cs_dag_poa_pvt_t; #define PVT(a) ((dap_chain_cs_dag_poa_pvt_t *) a->_pvt ) +typedef struct dap_chain_cs_dag_poa_callback_timer_arg { + dap_chain_cs_dag_t * dag; + char * l_event_hash_hex_str; + dap_chain_cs_dag_event_round_cfg_t event_round_cfg; +} dap_chain_cs_dag_poa_callback_timer_arg_t; + +static void s_callback_get_round_cfg(dap_chain_cs_dag_t * a_dag, dap_chain_cs_dag_event_round_cfg_t * a_event_round_cfg); static void s_callback_delete(dap_chain_cs_dag_t * a_dag); static int s_callback_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg); static int s_callback_created(dap_chain_t * a_chain, dap_config_t *a_chain_cfg); static int s_callback_event_verify(dap_chain_cs_dag_t * a_dag, dap_chain_cs_dag_event_t * a_dag_event, size_t a_dag_event_size); static dap_chain_cs_dag_event_t * s_callback_event_create(dap_chain_cs_dag_t * a_dag, dap_chain_datum_t * a_datum, dap_chain_hash_fast_t * a_hashes, size_t a_hashes_count, size_t* a_event_size); +static bool s_callback_round_event_to_chain(dap_chain_cs_dag_poa_callback_timer_arg_t * a_callback_arg); +static int s_callback_event_round_sync(dap_chain_cs_dag_t * a_dag, const char a_op_code, const char *a_group, + const char *a_key, const void *a_value, const size_t a_value_size); +static bool s_round_event_ready_minimum_check(dap_chain_cs_dag_t * a_dag, dap_chain_cs_dag_event_t * a_event, + size_t a_event_size, char * a_event_hash_hex_str, + dap_chain_cs_dag_event_round_cfg_t * a_event_round_cfg); +static void s_round_event_cs_done(dap_chain_cs_dag_t * a_dag, dap_chain_cs_dag_event_t * a_event, + char * a_event_hash_hex_str, dap_chain_cs_dag_event_round_cfg_t * a_event_round_cfg); +static void s_round_event_clean_dup(dap_chain_cs_dag_t * a_dag, char * a_event_hash_hex_str); + // CLI commands static int s_cli_dag_poa(int argc, char ** argv, char **str_reply); @@ -177,22 +200,37 @@ static int s_cli_dag_poa(int argc, char ** argv, char **a_str_reply) char * l_gdb_group_events = l_dag->gdb_group_events_round_new; size_t l_event_size = 0; dap_chain_cs_dag_event_t * l_event; - if ( (l_event = (dap_chain_cs_dag_event_t*) dap_chain_global_db_gr_get( dap_strdup(l_event_hash_hex_str), - &l_event_size, l_gdb_group_events )) == NULL ){ + dap_chain_cs_dag_event_round_cfg_t l_event_round_cfg; + + if ( (l_event = dap_chain_cs_dag_event_gdb_get( l_event_hash_hex_str, &l_event_size, + l_gdb_group_events, &l_event_round_cfg )) == NULL ){ dap_chain_node_cli_set_reply_text(a_str_reply, "Can't find event in round.new - only place where could be signed the new event\n", l_event_hash_str); ret = -30; }else { - dap_chain_cs_dag_event_t *l_event_new = dap_chain_cs_dag_event_copy_with_sign_add(l_event, l_event_size,l_poa_pvt->events_sign_cert->enc_key ); - dap_chain_hash_fast_t l_event_new_hash; - dap_chain_cs_dag_event_calc_hash(l_event_new, l_event_size,&l_event_new_hash); - //size_t l_event_new_size = dap_chain_cs_dag_event_calc_size(l_event_new); - char * l_event_new_hash_hex_str = dap_chain_hash_fast_to_str_new(&l_event_new_hash); - char * l_event_new_hash_base58_str = dap_enc_base58_encode_hash_to_str(&l_event_new_hash); - //char * l_event_new_hash_base58_str = dap_enc_base58_from_hex_str_to_str(l_event_new_hash_hex_str); - if (dap_chain_global_db_gr_set( dap_strdup(l_event_new_hash_hex_str),(uint8_t*) l_event,l_event_size,l_gdb_group_events) ){ - if ( dap_chain_global_db_gr_del(dap_strdup(l_event_hash_hex_str),l_gdb_group_events) ) { // Delete old event + size_t l_event_size_new = 0; + dap_chain_cs_dag_event_t *l_event_new = dap_chain_cs_dag_event_copy_with_sign_add(l_event, l_event_size, + &l_event_size_new, + l_chain_net, l_poa_pvt->events_sign_cert->enc_key); + if ( l_event_new ) { + dap_chain_hash_fast_t l_event_new_hash; + dap_chain_cs_dag_event_calc_hash(l_event_new, l_event_size_new, &l_event_new_hash); + //size_t l_event_new_size = dap_chain_cs_dag_event_calc_size(l_event_new); + char * l_event_new_hash_hex_str = dap_chain_hash_fast_to_str_new(&l_event_new_hash); + char * l_event_new_hash_base58_str = dap_enc_base58_encode_hash_to_str(&l_event_new_hash); + //char * l_event_new_hash_base58_str = dap_enc_base58_from_hex_str_to_str(l_event_new_hash_hex_str); + bool l_event_is_ready = s_round_event_ready_minimum_check(l_dag, l_event_new, l_event_size_new, + l_event_new_hash_hex_str, &l_event_round_cfg); + if (dap_chain_cs_dag_event_gdb_set(l_event_new_hash_hex_str, l_event_new, + l_event_size_new, l_gdb_group_events, &l_event_round_cfg) ){ + if ( !dap_chain_global_db_gr_del(dap_strdup(l_event_hash_hex_str), l_gdb_group_events) ) { // Delete old event + ret = 1; + dap_chain_node_cli_set_reply_text(a_str_reply, "Added new sign with cert \"%s\", event %s placed back in round.new\n" + "WARNING! Old event %s with same datum is still in round.new, produced DUP!\n", + l_poa_pvt->events_sign_cert->name ,l_event_new_hash_hex_str, l_event_hash_str); + } + if(!dap_strcmp(l_hash_out_type, "hex")) { dap_chain_node_cli_set_reply_text(a_str_reply, "Added new sign with cert \"%s\", event %s placed back in round.new\n", @@ -204,31 +242,37 @@ static int s_cli_dag_poa(int argc, char ** argv, char **a_str_reply) l_poa_pvt->events_sign_cert->name, l_event_new_hash_base58_str); } ret = 0; - dap_chain_net_sync_gdb(l_chain_net); // Propagate changes in pool + // dap_chain_net_sync_gdb(l_chain_net); // Propagate changes in pool + if (l_event_is_ready && l_poa_pvt->auto_round_complete) { // cs done (minimum signs & verify passed) + s_round_event_cs_done(l_dag, l_event_new, l_event_new_hash_hex_str, &l_event_round_cfg); + } + }else { - ret = 1; - dap_chain_node_cli_set_reply_text(a_str_reply, "Added new sign with cert \"%s\", event %s placed back in round.new\n" - "WARNING! Old event %s with same datum is still in round.new, produced DUP!\n", - l_poa_pvt->events_sign_cert->name ,l_event_new_hash_hex_str, l_event_hash_str); - } - }else { - if(!dap_strcmp(l_hash_out_type, "hex")) { - dap_chain_node_cli_set_reply_text(a_str_reply, - "GDB Error: Can't place event %s with new sign back in round.new\n", - l_event_new_hash_hex_str); - } - else { - dap_chain_node_cli_set_reply_text(a_str_reply, - "GDB Error: Can't place event %s with new sign back in round.new\n", - l_event_new_hash_base58_str); - } - ret=-31; + if(!dap_strcmp(l_hash_out_type, "hex")) { + dap_chain_node_cli_set_reply_text(a_str_reply, + "GDB Error: Can't place event %s with new sign back in round.new\n", + l_event_new_hash_hex_str); + } + else { + dap_chain_node_cli_set_reply_text(a_str_reply, + "GDB Error: Can't place event %s with new sign back in round.new\n", + l_event_new_hash_base58_str); + } + ret=-31; + } + DAP_DELETE(l_event_new); + DAP_DELETE(l_event_new_hash_hex_str); + DAP_DELETE(l_event_new_hash_base58_str); + } else { + dap_chain_node_cli_set_reply_text(a_str_reply, + "Can't sign event in round.new\n", + l_event_hash_str); + ret=-1; } - DAP_DELETE(l_event_new_hash_hex_str); - DAP_DELETE(l_event_new_hash_base58_str); } - DAP_DELETE( l_gdb_group_events ); + // DAP_DELETE( l_gdb_group_events ); + // DAP_DELETE(l_event_round_cfg); DAP_DELETE(l_event); } else { dap_chain_node_cli_set_reply_text(a_str_reply, "Command dag_poa requires subcommand 'sign'"); @@ -256,12 +300,18 @@ static int s_callback_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg) l_dag->callback_delete = s_callback_delete; l_dag->callback_cs_verify = s_callback_event_verify; l_dag->callback_cs_event_create = s_callback_event_create; + l_dag->callback_cs_get_round_cfg = s_callback_get_round_cfg; + l_dag->callback_cs_event_round_sync = s_callback_event_round_sync; l_poa->_pvt = DAP_NEW_Z ( dap_chain_cs_dag_poa_pvt_t ); dap_chain_cs_dag_poa_pvt_t * l_poa_pvt = PVT ( l_poa ); if (dap_config_get_item_str(a_chain_cfg,"dag-poa","auth_certs_prefix") ) { l_poa_pvt->auth_certs_count = dap_config_get_item_uint16_default(a_chain_cfg,"dag-poa","auth_certs_number",0); l_poa_pvt->auth_certs_count_verify = dap_config_get_item_uint16_default(a_chain_cfg,"dag-poa","auth_certs_number_verify",0); + l_poa_pvt->confirmations_timeout = dap_config_get_item_uint32_default(a_chain_cfg,"dag-poa","confirmations_timeout",600); + l_poa_pvt->auto_confirmation = dap_config_get_item_bool_default(a_chain_cfg,"dag-poa","auto_confirmation",true); + l_poa_pvt->auto_round_complete = dap_config_get_item_bool_default(a_chain_cfg,"dag-poa","auto_round_complete",true); + l_poa_pvt->wait_sync_before_complete = dap_config_get_item_uint32_default(a_chain_cfg,"dag-poa","wait_sync_before_complete",180); l_poa_pvt->auth_certs_prefix = strdup ( dap_config_get_item_str(a_chain_cfg,"dag-poa","auth_certs_prefix") ); if (l_poa_pvt->auth_certs_count && l_poa_pvt->auth_certs_count_verify ) { l_poa_pvt->auth_certs = DAP_NEW_Z_SIZE ( dap_cert_t *, l_poa_pvt->auth_certs_count * sizeof(dap_cert_t)); @@ -286,6 +336,197 @@ static int s_callback_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg) return 0; } + +typedef struct event_clean_dup_items { + uint16_t signs_count; + uint64_t ts_update; + char * hash_str; + UT_hash_handle hh; +} event_clean_dup_items_t; + +static event_clean_dup_items_t *s_event_clean_dup_items = NULL; + +static void s_round_event_clean_dup(dap_chain_cs_dag_t * a_dag, char * a_event_hash_hex_str) { + char * l_gdb_group_events = a_dag->gdb_group_events_round_new; + size_t l_event_size = 0; + dap_chain_cs_dag_event_t * l_event; + dap_chain_cs_dag_event_round_cfg_t l_event_round_cfg; + if ( (l_event = dap_chain_cs_dag_event_gdb_get( a_event_hash_hex_str, &l_event_size, + l_gdb_group_events, &l_event_round_cfg )) == NULL ) { + return; + } + + //char * l_event_first_hash_str = dap_chain_hash_fast_to_str_new(&l_event_round_cfg.first_event_hash); + size_t l_events_round_size = 0; + // dap_global_db_obj_t * l_events_round = dap_chain_global_db_gr_load(a_dag->gdb_group_events_round_new, &l_events_round_size ); + dap_store_obj_t *l_events_round = dap_chain_global_db_driver_read(a_dag->gdb_group_events_round_new, NULL, &l_events_round_size); + uint16_t l_max_signs_count = 0; + //char * l_max_signs_hash; + for (size_t l_index = 0; l_index<l_events_round_size; l_index++) { + // dap_chain_cs_dag_event_t * l_event = (dap_chain_cs_dag_event_t *) + // ((dap_chain_cs_dag_event_round_item_t *)l_events_round[l_index].value)->event; + // size_t l_event_size = ((dap_chain_cs_dag_event_round_item_t *)l_events_round[l_index].value)->event_size; + dap_chain_cs_dag_event_round_item_t *l_event_round_item = (dap_chain_cs_dag_event_round_item_t *)l_events_round[l_index].value; + dap_chain_cs_dag_event_t * l_event = (dap_chain_cs_dag_event_t *)l_event_round_item->event; + if ( memcmp(&l_event_round_cfg.first_event_hash, + &l_event_round_item->cfg.first_event_hash, sizeof(dap_chain_hash_fast_t)) == 0 ) { + event_clean_dup_items_t * l_item = DAP_NEW_Z(event_clean_dup_items_t); + l_item->signs_count = l_event->header.signs_count; + // l_item->ts_update = l_events_round[l_index].timestamp; + l_item->ts_update = l_event_round_item->cfg.ts_update; + l_item->hash_str = l_events_round[l_index].key; + HASH_ADD_STR(s_event_clean_dup_items, hash_str, l_item); + if ( l_event->header.signs_count > l_max_signs_count ) { + l_max_signs_count = l_event->header.signs_count; + } + } + } + + uint64_t l_max_ts_update = 0; + char * l_max_ts_update_hash; + event_clean_dup_items_t *l_clean_item=NULL, *l_clean_tmp=NULL; + HASH_ITER(hh, s_event_clean_dup_items, l_clean_item, l_clean_tmp) { + if ( l_clean_item->signs_count < l_max_signs_count ) { + // delete dup by min signatures + dap_chain_global_db_gr_del(dap_strdup(l_clean_item->hash_str), l_gdb_group_events); + HASH_DEL(s_event_clean_dup_items, l_clean_item); + DAP_DELETE(l_clean_item); + } else if ( l_clean_item->ts_update > l_max_ts_update ) { + l_max_ts_update = l_clean_item->ts_update; + l_max_ts_update_hash = l_clean_item->hash_str; + } + } + HASH_ITER(hh, s_event_clean_dup_items, l_clean_item, l_clean_tmp) { + if ( dap_strcmp(l_max_ts_update_hash, l_clean_item->hash_str) != 0 ) { + // delete dup by older + dap_chain_global_db_gr_del(dap_strdup(l_clean_item->hash_str), l_gdb_group_events); + } + HASH_DEL(s_event_clean_dup_items, l_clean_item); + DAP_DELETE(l_clean_item); + } + //HASH_CLEAR(hh, s_event_clean_dup_items); + dap_store_obj_free(l_events_round, l_events_round_size); +} + +static bool s_round_event_ready_minimum_check(dap_chain_cs_dag_t * a_dag, dap_chain_cs_dag_event_t * a_event, + size_t a_event_size, char * a_event_hash_hex_str, + dap_chain_cs_dag_event_round_cfg_t * a_event_round_cfg) { + if ( a_event->header.signs_count < a_event_round_cfg->confirmations_minimum ) { + return false; + } + a_dag->callback_cs_set_event_round_cfg(a_dag, a_event_round_cfg); + int l_ret_event_verify = a_dag->callback_cs_verify(a_dag, a_event, a_event_size); + if ( l_ret_event_verify == 0 ) { + if (a_event_round_cfg->ts_confirmations_minimum_completed == (uint64_t)0) { + a_event_round_cfg->ts_confirmations_minimum_completed = (uint64_t)time(NULL); + } + return true; + } + log_it(L_ERROR,"Round auto-complete error! Event %s is not passing consensus verification, ret code %d\n", + a_event_hash_hex_str, l_ret_event_verify ); + return false; +} + +static void s_round_event_cs_done(dap_chain_cs_dag_t * a_dag, dap_chain_cs_dag_event_t * a_event, + char * a_event_hash_hex_str, dap_chain_cs_dag_event_round_cfg_t * a_event_round_cfg) { + dap_chain_cs_dag_poa_t * l_poa = DAP_CHAIN_CS_DAG_POA( a_dag ); + dap_chain_cs_dag_poa_callback_timer_arg_t * l_callback_arg = DAP_NEW_Z(dap_chain_cs_dag_poa_callback_timer_arg_t); + l_callback_arg->dag = a_dag; + l_callback_arg->l_event_hash_hex_str = dap_strdup(a_event_hash_hex_str); + memcpy(&l_callback_arg->event_round_cfg, a_event_round_cfg, sizeof(dap_chain_cs_dag_event_round_cfg_t)); + uint32_t l_timeout = a_event_round_cfg->confirmations_timeout; + + if (a_event_round_cfg->ts_confirmations_minimum_completed == (uint64_t)0) { + a_event_round_cfg->ts_confirmations_minimum_completed = (uint64_t)time(NULL); + } + + if ( a_event->header.signs_count >= PVT(l_poa)->auth_certs_count) { + // placement in chain now if max signs + if (dap_timerfd_start(PVT(l_poa)->wait_sync_before_complete*1000, + (dap_timerfd_callback_t)s_callback_round_event_to_chain, + l_callback_arg) == NULL) { + log_it(L_ERROR,"Can't run timer for Event %s", a_event_hash_hex_str); + } else { + log_it(L_NOTICE,"Run timer %dsec. for Event %s", PVT(l_poa)->wait_sync_before_complete, a_event_hash_hex_str); + } + } + else if ( l_timeout > ((uint64_t)time(NULL) - a_event_round_cfg->ts_confirmations_minimum_completed) ) { + l_timeout = l_timeout - ((uint64_t)time(NULL) - a_event_round_cfg->ts_confirmations_minimum_completed); + // placement in chain by timer + l_timeout += PVT(l_poa)->wait_sync_before_complete; + if (dap_timerfd_start(l_timeout*1000, + (dap_timerfd_callback_t)s_callback_round_event_to_chain, + l_callback_arg) == NULL) { + log_it(L_ERROR,"Can't run timer for Event %s", a_event_hash_hex_str); + } else { + log_it(L_NOTICE,"Run timer %dsec. for Event %s", l_timeout, a_event_hash_hex_str); + } + } else { // placement in chain now if timer out + if (dap_timerfd_start(PVT(l_poa)->wait_sync_before_complete*1000, + (dap_timerfd_callback_t)s_callback_round_event_to_chain, + l_callback_arg) == NULL) { + log_it(L_ERROR,"Can't run timer for Event %s", a_event_hash_hex_str); + } else { + log_it(L_NOTICE,"Run timer %dsec. for Event %s", PVT(l_poa)->wait_sync_before_complete, a_event_hash_hex_str); + } + } +} + +static void s_callback_get_round_cfg(dap_chain_cs_dag_t * a_dag, dap_chain_cs_dag_event_round_cfg_t * a_event_round_cfg) { + dap_chain_cs_dag_poa_t * l_poa = DAP_CHAIN_CS_DAG_POA(a_dag); + dap_chain_cs_dag_poa_pvt_t * l_poa_pvt = PVT (l_poa); + a_event_round_cfg->confirmations_minimum = l_poa_pvt->auth_certs_count_verify; + a_event_round_cfg->confirmations_timeout = l_poa_pvt->confirmations_timeout; + a_event_round_cfg->ts_confirmations_minimum_completed = 0; +} + +static bool s_callback_round_event_to_chain(dap_chain_cs_dag_poa_callback_timer_arg_t * a_callback_arg) { + dap_chain_cs_dag_t * l_dag = a_callback_arg->dag; + dap_chain_net_t *l_net = dap_chain_net_by_id(l_dag->chain->net_id); + char * l_gdb_group_events = l_dag->gdb_group_events_round_new; + dap_chain_cs_dag_event_t * l_event; + size_t l_event_size = 0; + dap_chain_cs_dag_event_round_cfg_t l_event_round_cfg; + + if ( (l_event = dap_chain_cs_dag_event_gdb_get( a_callback_arg->l_event_hash_hex_str, &l_event_size, + l_gdb_group_events, &l_event_round_cfg )) == NULL ){ + log_it(L_NOTICE,"Can't find event %s in round.new. The hash may have changed by reason the addition of a new signature.", + a_callback_arg->l_event_hash_hex_str); + } + else { + dap_chain_atom_ptr_t l_new_atom = (dap_chain_atom_ptr_t)dap_chain_cs_dag_event_copy(l_event, l_event_size); + memcpy(l_new_atom, l_event, l_event_size); + + if(l_dag->chain->callback_atom_add(l_dag->chain, l_new_atom, l_event_size) < 0) { // Add new atom in chain + DAP_DELETE(l_new_atom); + log_it(L_NOTICE, "Event %s not added in chain", a_callback_arg->l_event_hash_hex_str); + } + else { + log_it(L_NOTICE, "Event %s added in chain successfully", + a_callback_arg->l_event_hash_hex_str); + // event delete from round + dap_chain_cell_id_t l_cell_id = { + .uint64 = l_net ? l_net->pub.cell_id.uint64 : 0 + }; + dap_chain_cell_t *l_cell = dap_chain_cell_find_by_id(l_dag->chain, l_cell_id); + if (!l_cell) + l_cell = dap_chain_cell_create_fill(l_dag->chain, l_cell_id); + if(l_cell) { + if(dap_chain_cell_file_update(l_cell) > 0) { + // delete events from db + dap_chain_global_db_gr_del(dap_strdup(a_callback_arg->l_event_hash_hex_str), l_dag->gdb_group_events_round_new); + } + } + dap_chain_cell_close(l_cell); + // dap_chain_net_sync_all(l_net); + } + } + + DAP_DELETE(a_callback_arg->l_event_hash_hex_str); + DAP_DELETE(a_callback_arg); + return false; +} + /** * @brief create callback load certificate for event signing for specific chain * path to certificate iw written to chain config file in dag_poa section @@ -369,6 +610,57 @@ static dap_chain_cs_dag_event_t * s_callback_event_create(dap_chain_cs_dag_t * a } +static int s_callback_event_round_sync(dap_chain_cs_dag_t * a_dag, const char a_op_code, const char *a_group, + const char *a_key, const void *a_value, const size_t a_value_size) +{ + + dap_chain_net_t *l_net = dap_chain_net_by_id( a_dag->chain->net_id); + + if ( a_value == NULL || a_op_code != 'a' ) { + return 0; + } + + dap_chain_cs_dag_poa_t * l_poa = DAP_CHAIN_CS_DAG_POA(a_dag); + if ( !PVT(l_poa)->auto_confirmation ) { + return 0; + } + dap_chain_cs_dag_event_round_item_t *l_event_round_item = (dap_chain_cs_dag_event_round_item_t *)a_value; + size_t l_event_size = l_event_round_item->event_size; + dap_chain_cs_dag_event_t * l_event = (dap_chain_cs_dag_event_t *)l_event_round_item->event; + // dap_chain_cs_dag_event_t * l_event = (dap_chain_cs_dag_event_t *)DAP_DUP_SIZE(l_event_round_item->event, l_event_size); + size_t l_event_size_new = 0; + dap_chain_cs_dag_event_t *l_event_new = dap_chain_cs_dag_event_copy_with_sign_add(l_event, l_event_size, + &l_event_size_new, l_net, + PVT(l_poa)->events_sign_cert->enc_key); + + if ( l_event_new ) { + char * l_gdb_group_events = a_dag->gdb_group_events_round_new; + dap_chain_hash_fast_t l_event_new_hash; + dap_chain_cs_dag_event_calc_hash(l_event_new, l_event_size_new, &l_event_new_hash); + char * l_event_new_hash_hex_str = dap_chain_hash_fast_to_str_new(&l_event_new_hash); + bool l_event_is_ready = s_round_event_ready_minimum_check(a_dag, l_event_new, l_event_size_new, + l_event_new_hash_hex_str, &l_event_round_item->cfg); + if (dap_chain_cs_dag_event_gdb_set(l_event_new_hash_hex_str, l_event_new, + l_event_size_new, l_gdb_group_events, &l_event_round_item->cfg) ){ + dap_chain_global_db_gr_del(dap_strdup(a_key), l_gdb_group_events); // Delete old event + if (l_event_is_ready && PVT(l_poa)->auto_round_complete) { // cs done (minimum signs & verify passed) + s_round_event_cs_done(a_dag, l_event_new, l_event_new_hash_hex_str, &l_event_round_item->cfg); + } + } + s_round_event_clean_dup(a_dag, l_event_new_hash_hex_str); // Delete dup + DAP_DELETE(l_event_new); + } else { + // if (PVT(l_poa)->auto_round_complete) { + // if (s_round_event_ready_minimum_check(a_dag, l_event, l_event_size, &l_event_round_item->cfg)){ + // s_round_event_cs_done(a_dag, l_event, a_key, &l_event_round_item->cfg); + // } + // } + s_round_event_clean_dup(a_dag, a_key); // Delete dup + } + + return 0; +} + /** * @brief * function makes event singing verification @@ -386,7 +678,12 @@ static int s_callback_event_verify(dap_chain_cs_dag_t * a_dag, dap_chain_cs_dag_ a_dag_event, l_offset_from_beginning, a_dag_event_size); return -7; // Incorrest size } - if ( a_dag_event->header.signs_count >= l_poa_pvt->auth_certs_count_verify ){ + uint16_t l_certs_count_verify = a_dag->use_event_round_cfg ? a_dag->event_round_cfg.confirmations_minimum + : l_poa_pvt->auth_certs_count_verify; + a_dag->use_event_round_cfg = false; + // if ( a_dag_event->header.signs_count >= l_poa_pvt->auth_certs_count_verify ){ + if ( a_dag_event->header.signs_count >= l_certs_count_verify ){ + size_t l_verified = 0; for ( uint16_t i = 0; i < a_dag_event->header.signs_count; i++ ) { if (l_offset_from_beginning == a_dag_event_size) @@ -406,7 +703,8 @@ static int s_callback_event_verify(dap_chain_cs_dag_t * a_dag, dap_chain_cs_dag_ l_verified++; } } - return l_verified >= l_poa_pvt->auth_certs_count_verify ? 0 : -1; + //return l_verified >= l_poa_pvt->auth_certs_count_verify ? 0 : -1; + return l_verified >= l_certs_count_verify ? 0 : -1; }else if (a_dag_event->header.hash_count == 0){ dap_chain_hash_fast_t l_event_hash; dap_chain_cs_dag_event_calc_hash(a_dag_event,a_dag_event_size, &l_event_hash); diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c index faaaab78616b9793212bc740ca0fa078d7bc26fb..dca78a4dda1344b474b223e0a7bc57bc2d297cd7 100644 --- a/modules/type/dag/dap_chain_cs_dag.c +++ b/modules/type/dag/dap_chain_cs_dag.c @@ -122,6 +122,7 @@ static dap_chain_datum_t* s_chain_callback_datum_iter_get_next( dap_chain_datum_ static int s_cli_dag(int argc, char ** argv, char **str_reply); void s_dag_events_lasts_process_new_last_event(dap_chain_cs_dag_t * a_dag, dap_chain_cs_dag_event_item_t * a_event_item); +static void s_dag_chain_cs_set_event_round_cfg(dap_chain_cs_dag_t * a_dag, dap_chain_cs_dag_event_round_cfg_t * a_event_round_cfg); static bool s_seed_mode = false; static bool s_debug_more = false; @@ -163,6 +164,21 @@ void dap_chain_cs_dag_deinit(void) } +static void s_history_callback_round_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_size) +{ + if (a_arg){ + dap_chain_cs_dag_t * l_dag = (dap_chain_cs_dag_t *) a_arg; + dap_chain_net_t *l_net = dap_chain_net_by_id( l_dag->chain->net_id); + log_it(L_DEBUG,"%s.%s: op_code='%c' group=\"%s\" key=\"%s\" value_size=%zu", + l_net->pub.name, l_dag->chain->name, a_op_code, a_group, a_key, a_value_size); + if (l_dag->callback_cs_event_round_sync) { + l_dag->callback_cs_event_round_sync(l_dag, a_op_code, a_group, a_key, a_value, a_value_size); + } + dap_chain_net_sync_gdb_broadcast((void *)l_net, a_op_code, a_group, a_key, a_value, a_value_size); + } +} + /** * @brief dap_chain_cs_dag_new * @param a_chain @@ -232,10 +248,26 @@ int dap_chain_cs_dag_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg) l_dag->is_single_line = dap_config_get_item_bool_default(a_chain_cfg,"dag","is_single_line",false); l_dag->is_celled = dap_config_get_item_bool_default(a_chain_cfg,"dag","is_celled",false); - l_dag->is_add_directy = dap_config_get_item_bool_default(a_chain_cfg,"dag","is_add_directly",false); + l_dag->is_add_directly = dap_config_get_item_bool_default(a_chain_cfg,"dag","is_add_directly",false); l_dag->datum_add_hashes_count = dap_config_get_item_uint16_default(a_chain_cfg,"dag","datum_add_hashes_count",1); - l_dag->gdb_group_events_round_new = dap_strdup( dap_config_get_item_str_default(a_chain_cfg,"dag","gdb_group_events_round_new", - "events.round.new")); + l_dag->use_event_round_cfg = false; + l_dag->callback_cs_set_event_round_cfg = s_dag_chain_cs_set_event_round_cfg; + // l_dag->gdb_group_events_round_new = dap_strdup( dap_config_get_item_str_default(a_chain_cfg,"dag","gdb_group_events_round_new", + // "events.round.new")); + + char * l_round_new_str = dap_strdup( dap_config_get_item_str_default(a_chain_cfg,"dag","gdb_group_events_round_new", "events.round.new")); + dap_chain_net_t *l_net = dap_chain_net_by_id(a_chain->net_id); + if(!l_dag->is_celled){ + l_dag->gdb_group_events_round_new = dap_strdup_printf( "round-gdb.%s.chain-%016llX.%s",l_net->pub.name, + a_chain->id.uint64, l_round_new_str); + }else { + l_dag->gdb_group_events_round_new = dap_strdup_printf( "round-gdb.%s.chain-%016llX.cell-%016llX.%s",l_net->pub.name, + a_chain->id.uint64, l_net->pub.cell_id.uint64, l_round_new_str); + } + DAP_DELETE(l_round_new_str); + + dap_chain_global_db_add_sync_group("round-gdb", s_history_callback_round_notify, l_dag); + if ( l_dag->is_single_line ) { log_it (L_NOTICE, "DAG chain initialized (single line)"); } else { @@ -245,6 +277,13 @@ int dap_chain_cs_dag_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg) return 0; } +static void s_dag_chain_cs_set_event_round_cfg(dap_chain_cs_dag_t * a_dag, dap_chain_cs_dag_event_round_cfg_t * a_event_round_cfg){ + memcpy(&a_dag->event_round_cfg, + a_event_round_cfg, + sizeof(dap_chain_cs_dag_event_round_cfg_t)); + a_dag->use_event_round_cfg = true; +} + static void s_dap_chain_cs_dag_purge(dap_chain_t *a_chain) { dap_chain_cs_dag_pvt_t *l_dag_pvt = PVT(DAP_CHAIN_CS_DAG(a_chain)); @@ -542,8 +581,11 @@ static size_t s_chain_callback_datums_pool_proc(dap_chain_t * a_chain, dap_chain do{ int l_index = rand() % (int) l_events_round_new_size; dap_chain_hash_fast_t l_hash; - dap_chain_cs_dag_event_t * l_event = (dap_chain_cs_dag_event_t *) l_events_round_new[l_index].value; - size_t l_event_size = l_events_round_new[l_index].value_len; + // dap_chain_cs_dag_event_t * l_event = (dap_chain_cs_dag_event_t *) l_events_round_new[l_index].value; + // size_t l_event_size = l_events_round_new[l_index].value_len; + dap_chain_cs_dag_event_t * l_event = (dap_chain_cs_dag_event_t *) + ((dap_chain_cs_dag_event_round_item_t *)l_events_round_new[l_index].value)->event; + size_t l_event_size = ((dap_chain_cs_dag_event_round_item_t *)l_events_round_new[l_index].value)->event_size; dap_hash_fast(l_event, l_event_size,&l_hash); bool l_is_already_in_event = false; @@ -591,7 +633,7 @@ static size_t s_chain_callback_datums_pool_proc(dap_chain_t * a_chain, dap_chain if(l_dag->callback_cs_event_create) l_event = l_dag->callback_cs_event_create(l_dag,l_datum,l_hashes,l_hashes_linked,&l_event_size); if ( l_event&&l_event_size){ // Event is created - if (l_dag->is_add_directy) { + if (l_dag->is_add_directly) { if (s_chain_callback_atom_add(a_chain, l_event, l_event_size) == ATOM_ACCEPT) { // add events to file if (!l_cell) { @@ -631,9 +673,18 @@ static size_t s_chain_callback_datums_pool_proc(dap_chain_t * a_chain, dap_chain dap_chain_hash_fast_t l_event_hash; dap_chain_cs_dag_event_calc_hash(l_event,l_event_size, &l_event_hash); char * l_event_hash_str = dap_chain_hash_fast_to_str_new(&l_event_hash); - if(dap_chain_global_db_gr_set(dap_strdup(l_event_hash_str), (uint8_t *) l_event, - l_event_size, - l_dag->gdb_group_events_round_new)) { + // if(dap_chain_global_db_gr_set(dap_strdup(l_event_hash_str), (uint8_t *)l_event, + // l_event_size, + // l_dag->gdb_group_events_round_new)) { + dap_chain_cs_dag_event_round_cfg_t l_event_round_cfg; + if ( l_dag->callback_cs_get_round_cfg ) { + l_dag->callback_cs_get_round_cfg(l_dag, &l_event_round_cfg); + } + // set first event hash for round + memcpy(&l_event_round_cfg.first_event_hash, &l_event_hash, sizeof(dap_chain_hash_fast_t)); + if(dap_chain_cs_dag_event_gdb_set(l_event_hash_str, l_event, + l_event_size, l_dag->gdb_group_events_round_new, + &l_event_round_cfg)) { log_it(L_INFO, "Event %s placed in the new forming round", l_event_hash_str); DAP_DELETE(l_event_hash_str); l_event_hash_str = NULL; @@ -1318,8 +1369,12 @@ static int s_cli_dag(int argc, char ** argv, char **a_str_reply) // Check if its ready or not for (size_t i = 0; i< l_objs_size; i++ ){ - dap_chain_cs_dag_event_t * l_event = (dap_chain_cs_dag_event_t*) l_objs[i].value; - size_t l_event_size = l_objs[i].value_len; + // dap_chain_cs_dag_event_t * l_event = (dap_chain_cs_dag_event_t*) l_objs[i].value; + // size_t l_event_size = l_objs[i].value_len; + dap_chain_cs_dag_event_t * l_event = (dap_chain_cs_dag_event_t *) + ((dap_chain_cs_dag_event_round_item_t *)l_objs[i].value)->event; + size_t l_event_size = ((dap_chain_cs_dag_event_round_item_t *)l_objs[i].value)->event_size; + l_dag->callback_cs_set_event_round_cfg(l_dag, &((dap_chain_cs_dag_event_round_item_t *)l_objs[i].value)->cfg); int l_ret_event_verify; if ( ( l_ret_event_verify = l_dag->callback_cs_verify (l_dag,l_event,l_event_size) ) !=0 ){// if consensus accept the event dap_string_append_printf( l_str_ret_tmp, @@ -1375,7 +1430,7 @@ static int s_cli_dag(int argc, char ** argv, char **a_str_reply) dap_string_free(l_str_ret_tmp,false); // Spread new mempool changes and dag events in network - going to SYNC_ALL - dap_chain_net_sync_all(l_net); + // dap_chain_net_sync_all(l_net); } }else if ( l_event_cmd_str ) { char *l_datum_hash_hex_str = NULL; @@ -1470,7 +1525,7 @@ static int s_cli_dag(int argc, char ** argv, char **a_str_reply) DAP_DELETE(l_gdb_group_mempool); DAP_DELETE(l_datum_hash_hex_str); DAP_DELETE(l_datum_hash_base58_str); - dap_chain_net_sync_all(l_net); + // dap_chain_net_sync_all(l_net); }break; case SUBCMD_EVENT_CANCEL:{ char * l_gdb_group_events = DAP_CHAIN_CS_DAG(l_chain)->gdb_group_events_round_new; @@ -1526,17 +1581,20 @@ static int s_cli_dag(int argc, char ** argv, char **a_str_reply) } DAP_DELETE(l_event_hash_hex_str); DAP_DELETE(l_event_hash_base58_str); - DAP_DELETE( l_gdb_group_events ); - dap_chain_net_sync_gdb(l_net); + // DAP_DELETE( l_gdb_group_events ); + // dap_chain_net_sync_gdb(l_net); }break; case SUBCMD_EVENT_DUMP:{ dap_chain_cs_dag_event_t * l_event = NULL; + dap_chain_cs_dag_event_round_cfg_t l_event_round_cfg; size_t l_event_size = 0; if ( l_from_events_str ){ if ( strcmp(l_from_events_str,"round.new") == 0 ){ const char * l_gdb_group_events = l_dag->gdb_group_events_round_new; - l_event = (dap_chain_cs_dag_event_t *) dap_chain_global_db_gr_get - ( l_event_hash_str ,&l_event_size,l_gdb_group_events ); + // l_event = (dap_chain_cs_dag_event_t *) dap_chain_global_db_gr_get + // ( l_event_hash_str ,&l_event_size,l_gdb_group_events ); + l_event = dap_chain_cs_dag_event_gdb_get(l_event_hash_str, &l_event_size, + l_gdb_group_events, &l_event_round_cfg); }else if ( strncmp(l_from_events_str,"round.",6) == 0){ }else if ( strcmp(l_from_events_str,"events_lasts") == 0){ @@ -1584,8 +1642,28 @@ static int s_cli_dag(int argc, char ** argv, char **a_str_reply) dap_string_t * l_str_tmp = dap_string_new(NULL); char buf[50]; time_t l_ts_reated = (time_t) l_event->header.ts_created; + dap_string_append_printf(l_str_tmp,"\nEvent %s:\n", l_event_hash_str); + + // Round cfg + if ( strcmp(l_from_events_str,"round.new") == 0 ) { + dap_string_append_printf(l_str_tmp, + "\t\tRound cfg:\n\t\t\t\tconfirmations_minimum: %d\n\t\t\t\tconfirmations_timeout: %d\n", + l_event_round_cfg.confirmations_minimum, + l_event_round_cfg.confirmations_timeout); + char * l_hash_str = dap_chain_hash_fast_to_str_new(&l_event_round_cfg.first_event_hash); + dap_string_append_printf(l_str_tmp, "\t\t\t\tfirst_event_hash: %s\n", l_hash_str); + DAP_DELETE(l_hash_str); + dap_string_append_printf(l_str_tmp, + "\t\t\t\tts_update: %s", + dap_ctime_r(&l_event_round_cfg.ts_update, buf) ); + if (l_event_round_cfg.ts_confirmations_minimum_completed != 0) + dap_string_append_printf(l_str_tmp, + "\t\t\t\tts_confirmations_minimum_completed: %s", + dap_ctime_r(&l_event_round_cfg.ts_confirmations_minimum_completed, buf) ); + } + // Header - dap_string_append_printf(l_str_tmp,"Event %s:\n", l_event_hash_str); + dap_string_append_printf(l_str_tmp,"\t\tHeader:\n"); dap_string_append_printf(l_str_tmp,"\t\t\t\tversion: 0x%02X\n",l_event->header.version); dap_string_append_printf(l_str_tmp,"\t\t\t\tcell_id: 0x%016"DAP_UINT64_FORMAT_x"\n",l_event->header.cell_id.uint64); dap_string_append_printf(l_str_tmp,"\t\t\t\tchain_id: 0x%016"DAP_UINT64_FORMAT_X"\n",l_event->header.chain_id.uint64); @@ -1659,7 +1737,9 @@ static int s_cli_dag(int argc, char ** argv, char **a_str_reply) dap_string_append_printf(l_str_tmp,"%s.%s: Found %zu records :\n",l_net->pub.name,l_chain->name,l_objs_count); for (size_t i = 0; i< l_objs_count; i++){ - dap_chain_cs_dag_event_t * l_event = (dap_chain_cs_dag_event_t *) l_objs[i].value; + // dap_chain_cs_dag_event_t * l_event = (dap_chain_cs_dag_event_t *) l_objs[i].value; + dap_chain_cs_dag_event_t * l_event = (dap_chain_cs_dag_event_t *) + ((dap_chain_cs_dag_event_round_item_t *)l_objs[i].value)->event; char buf[50]; time_t l_ts_create = (time_t) l_event->header.ts_created; dap_string_append_printf(l_str_tmp,"\t%s: ts_create=%s", diff --git a/modules/type/dag/dap_chain_cs_dag_event.c b/modules/type/dag/dap_chain_cs_dag_event.c index c5de53eb92da0d92ca87ebcdc75ab7842d5c850d..d0ba2b1354a3b8ee404dce1e124e6ec738e18894 100644 --- a/modules/type/dag/dap_chain_cs_dag_event.c +++ b/modules/type/dag/dap_chain_cs_dag_event.c @@ -110,16 +110,52 @@ dap_chain_cs_dag_event_t * dap_chain_cs_dag_event_copy(dap_chain_cs_dag_event_t * @param l_key * @return */ -dap_chain_cs_dag_event_t * dap_chain_cs_dag_event_copy_with_sign_add( dap_chain_cs_dag_event_t * a_event, size_t a_event_size, - dap_enc_key_t * l_key) +dap_chain_cs_dag_event_t * dap_chain_cs_dag_event_copy_with_sign_add( dap_chain_cs_dag_event_t * a_event, size_t a_event_size, + size_t * a_event_size_new, + dap_chain_net_t * a_net, dap_enc_key_t * a_key) { - size_t l_event_signing_size = dap_chain_cs_dag_event_calc_size_excl_signs( a_event ,a_event_size); - dap_sign_t * l_sign = dap_sign_create(l_key,a_event,l_event_signing_size,0); + size_t l_hashes_size = a_event->header.hash_count*sizeof(dap_chain_hash_fast_t); + dap_chain_datum_t * l_datum = (dap_chain_datum_t*)(a_event->hashes_n_datum_n_signs + l_hashes_size); + size_t l_datum_size = dap_chain_datum_size(l_datum); + size_t l_event_size_excl_sign = sizeof(a_event->header)+l_hashes_size+l_datum_size; + // size_t l_event_size_excl_sign = dap_chain_cs_dag_event_calc_size_excl_signs(a_event,a_event_size); + size_t l_event_size = a_event_size; + size_t l_event_signs_size = l_event_size - l_event_size_excl_sign; + dap_sign_t * l_sign = dap_sign_create(a_key,a_event,l_event_size_excl_sign,0); + size_t l_sign_size = dap_sign_get_size(l_sign); - dap_chain_cs_dag_event_t *l_event_new = DAP_NEW_Z_SIZE(dap_chain_cs_dag_event_t, a_event_size+l_sign_size); - memcpy(l_event_new, a_event,a_event_size); - memcpy(l_event_new+a_event_size,l_sign,l_sign_size); + dap_chain_addr_t l_addr = {0}; + dap_chain_hash_fast_t l_pkey_hash; + dap_sign_get_pkey_hash(l_sign, &l_pkey_hash); + dap_chain_addr_fill(&l_addr, l_sign->header.type, &l_pkey_hash, a_net->pub.id); + char * l_addr_str = dap_chain_addr_to_str(&l_addr); + + size_t l_offset = l_hashes_size+l_datum_size; + // checking re-sign from one address and calc signs size + while ( l_offset+sizeof(a_event->header) < l_event_size ) { + dap_sign_t * l_item_sign = (dap_sign_t *)(a_event->hashes_n_datum_n_signs +l_offset); + size_t l_sign_size = dap_sign_get_size(l_item_sign); + dap_chain_addr_t l_item_addr = {0}; + dap_chain_hash_fast_t l_item_pkey_hash; + dap_sign_get_pkey_hash(l_item_sign, &l_item_pkey_hash); + dap_chain_addr_fill(&l_item_addr, l_item_sign->header.type, &l_item_pkey_hash, a_net->pub.id); + // checking re-sign from one address + if (memcmp(&l_addr, &l_item_addr, sizeof(l_item_addr)) == 0) { + log_it(L_DEBUG, "Sign from this addr exists: %s", l_addr_str); + DAP_DELETE(l_sign); + DAP_DELETE(l_addr_str); + return NULL; + } + l_offset += l_sign_size; + } + // dap_chain_cs_dag_event_t * l_event_new = DAP_REALLOC(a_event, l_event_size+l_sign_size); + dap_chain_cs_dag_event_t * l_event_new = DAP_NEW_Z_SIZE(dap_chain_cs_dag_event_t, l_event_size+l_sign_size); + memcpy(l_event_new, a_event, l_event_size); + memcpy(l_event_new->hashes_n_datum_n_signs+l_offset, l_sign, l_sign_size); + *a_event_size_new = l_event_size+l_sign_size; l_event_new->header.signs_count++; + DAP_DELETE(l_sign); + DAP_DELETE(l_addr_str); return l_event_new; } @@ -152,4 +188,36 @@ dap_sign_t * dap_chain_cs_dag_event_get_sign( dap_chain_cs_dag_event_t * a_event return NULL; } +bool dap_chain_cs_dag_event_gdb_set(char *a_event_hash_str, dap_chain_cs_dag_event_t * a_event, size_t a_event_size, + const char *a_group, dap_chain_cs_dag_event_round_cfg_t * a_event_round_cfg) { + dap_chain_cs_dag_event_round_item_t * l_event_round_item = DAP_NEW_SIZE(dap_chain_cs_dag_event_round_item_t, + sizeof(dap_chain_cs_dag_event_round_item_t)+a_event_size ); + l_event_round_item->event_size = a_event_size; + a_event_round_cfg->ts_update = (uint64_t)time(NULL); + // l_event_round_item->event = DAP_DUP_SIZE(a_event, a_event_size); + memcpy(&l_event_round_item->cfg, a_event_round_cfg, sizeof(dap_chain_cs_dag_event_round_cfg_t)); + memcpy(l_event_round_item->event, a_event, a_event_size); + bool ret = dap_chain_global_db_gr_set(dap_strdup(a_event_hash_str), (uint8_t *)l_event_round_item, + dap_chain_cs_dag_event_round_item_get_size(l_event_round_item), + a_group); + DAP_DELETE(l_event_round_item); + return ret; +} + +dap_chain_cs_dag_event_t* dap_chain_cs_dag_event_gdb_get(char *a_event_hash_str, size_t * a_event_size, const char *a_group, + dap_chain_cs_dag_event_round_cfg_t * a_event_round_cfg) { + size_t l_event_round_item_size = 0; + dap_chain_cs_dag_event_round_item_t* l_event_round_item = + (dap_chain_cs_dag_event_round_item_t*)dap_chain_global_db_gr_get(a_event_hash_str, &l_event_round_item_size, a_group ); + if ( l_event_round_item == NULL ) + return NULL; + size_t l_event_size = l_event_round_item->event_size; + dap_chain_cs_dag_event_t* l_event = DAP_NEW_SIZE(dap_chain_cs_dag_event_t, l_event_size); + memcpy(a_event_round_cfg, &l_event_round_item->cfg, sizeof(dap_chain_cs_dag_event_round_cfg_t)); + memcpy(l_event, l_event_round_item->event, l_event_size); + DAP_DELETE(l_event_round_item); + *a_event_size = l_event_size; + return l_event; +} + diff --git a/modules/type/dag/include/dap_chain_cs_dag.h b/modules/type/dag/include/dap_chain_cs_dag.h index 43a823579d3504c11474438beef8f99a271333a2..d11ae746d9a78e775bf0b1b91298c56f8a5af28d 100644 --- a/modules/type/dag/include/dap_chain_cs_dag.h +++ b/modules/type/dag/include/dap_chain_cs_dag.h @@ -31,12 +31,17 @@ typedef struct dap_chain_cs_dag dap_chain_cs_dag_t; typedef void (*dap_chain_cs_dag_callback_t)(dap_chain_cs_dag_t *); typedef int (*dap_chain_cs_dag_callback_event_t)(dap_chain_cs_dag_t *, dap_chain_cs_dag_event_t *,size_t); - - typedef dap_chain_cs_dag_event_t * (*dap_chain_cs_dag_callback_event_create_t)(dap_chain_cs_dag_t *, dap_chain_datum_t *, dap_chain_hash_fast_t *, size_t, size_t*); + +typedef int (*dap_chain_cs_dag_callback_get_round_cfg_t)(dap_chain_cs_dag_t *, dap_chain_cs_dag_event_round_cfg_t *); +typedef void (*dap_chain_cs_dag_callback_set_event_round_cfg_t)(dap_chain_cs_dag_t *, dap_chain_cs_dag_event_round_cfg_t *); + +typedef void (*dap_chain_cs_dag_callback_event_round_sync_t)(dap_chain_cs_dag_t * a_dag, const char a_op_code, const char *a_group, + const char *a_key, const void *a_value, const size_t a_value_size); + typedef struct dap_chain_cs_dag_hal_item { dap_chain_hash_fast_t hash; UT_hash_handle hh; @@ -47,17 +52,23 @@ typedef struct dap_chain_cs_dag dap_chain_t * chain; bool is_single_line; bool is_celled; - bool is_add_directy; + bool is_add_directly; bool is_static_genesis_event; dap_chain_hash_fast_t static_genesis_event_hash; dap_chain_cs_dag_hal_item_t *hal; + dap_chain_cs_dag_event_round_cfg_t event_round_cfg; // for verify function + bool use_event_round_cfg; + uint16_t datum_add_hashes_count; char * gdb_group_events_round_new; dap_chain_cs_dag_callback_t callback_delete; dap_chain_cs_dag_callback_event_create_t callback_cs_event_create; dap_chain_cs_dag_callback_event_t callback_cs_verify; + dap_chain_cs_dag_callback_get_round_cfg_t callback_cs_get_round_cfg; + dap_chain_cs_dag_callback_set_event_round_cfg_t callback_cs_set_event_round_cfg; + dap_chain_cs_dag_callback_event_round_sync_t callback_cs_event_round_sync; void * _pvt; void * _inheritor; diff --git a/modules/type/dag/include/dap_chain_cs_dag_event.h b/modules/type/dag/include/dap_chain_cs_dag_event.h index 8065ea0eb34b6f1d3449647a29a8b456dbcc66e8..1847092b25bc8761d4a75f345c7e34634f99447d 100644 --- a/modules/type/dag/include/dap_chain_cs_dag_event.h +++ b/modules/type/dag/include/dap_chain_cs_dag_event.h @@ -26,6 +26,7 @@ #include "dap_enc_key.h" #include "dap_chain_common.h" #include "dap_chain_datum.h" +#include "dap_chain_net.h" #include "dap_sign.h" #include "dap_hash.h" @@ -46,6 +47,19 @@ typedef struct dap_chain_cs_dag_event { uint8_t hashes_n_datum_n_signs[]; // Hashes, signes and datum } DAP_ALIGN_PACKED dap_chain_cs_dag_event_t; +typedef struct dap_chain_cs_dag_event_round_cfg { + uint16_t confirmations_minimum; // param auth_certs_count_verify in PoA + uint32_t confirmations_timeout; // wait confirmations over minimum value (confirmations_minimum) + uint64_t ts_confirmations_minimum_completed; + uint64_t ts_update; + dap_chain_hash_fast_t first_event_hash; // first event hash in round +} DAP_ALIGN_PACKED dap_chain_cs_dag_event_round_cfg_t; + +typedef struct dap_chain_cs_dag_event_round_item { + dap_chain_cs_dag_event_round_cfg_t cfg; + uint32_t event_size; + uint8_t event[]; // event // dap_chain_cs_dag_event_t +} DAP_ALIGN_PACKED dap_chain_cs_dag_event_round_item_t; dap_chain_cs_dag_event_t * dap_chain_cs_dag_event_new(dap_chain_id_t a_chain_id, dap_chain_cell_id_t a_cell_id, dap_chain_datum_t * a_datum, dap_enc_key_t * a_key, @@ -66,7 +80,9 @@ static inline dap_chain_datum_t* dap_chain_cs_dag_event_get_datum(dap_chain_cs_d dap_chain_cs_dag_event_t * dap_chain_cs_dag_event_copy(dap_chain_cs_dag_event_t *a_event_src, size_t a_event_size); // Important: returns new deep copy of event -dap_chain_cs_dag_event_t * dap_chain_cs_dag_event_copy_with_sign_add( dap_chain_cs_dag_event_t * a_event,size_t a_event_size, dap_enc_key_t * l_key); +dap_chain_cs_dag_event_t * dap_chain_cs_dag_event_copy_with_sign_add( dap_chain_cs_dag_event_t * a_event, size_t a_event_size, + size_t * a_event_size_new, + dap_chain_net_t * a_net, dap_enc_key_t * a_key); dap_sign_t * dap_chain_cs_dag_event_get_sign( dap_chain_cs_dag_event_t * a_event, size_t a_event_size, uint16_t a_sign_number); /** @@ -123,3 +139,15 @@ static inline void dap_chain_cs_dag_event_calc_hash(dap_chain_cs_dag_event_t * a { dap_hash_fast(a_event, a_event_size, a_event_hash); } + +static inline size_t dap_chain_cs_dag_event_round_item_get_size(dap_chain_cs_dag_event_round_item_t * a_event_round_item){ + return sizeof(dap_chain_cs_dag_event_round_item_t)+a_event_round_item->event_size; +} + +bool dap_chain_cs_dag_event_gdb_set(char *a_event_hash_str, dap_chain_cs_dag_event_t * a_event, size_t a_event_size, + const char *a_group, dap_chain_cs_dag_event_round_cfg_t * a_event_round_cfg); + +dap_chain_cs_dag_event_t* dap_chain_cs_dag_event_gdb_get(char *a_event_hash_str, size_t * a_event_size, + const char *a_group, dap_chain_cs_dag_event_round_cfg_t * a_event_round_cfg); + +