diff --git a/modules/chain/dap_chain.c b/modules/chain/dap_chain.c index 0d6a2fe42d57f7ff5e4d98df84955c50efff6149..88288bb8d8566b27f791c7dc647c2d61330b4a77 100644 --- a/modules/chain/dap_chain.c +++ b/modules/chain/dap_chain.c @@ -101,7 +101,7 @@ void dap_chain_deinit(void) * @param a_chain_id chain id * @return dap_chain_t* */ -dap_chain_t * dap_chain_create(dap_ledger_t* a_ledger, const char * a_chain_net_name, const char * a_chain_name, dap_chain_net_id_t a_chain_net_id, dap_chain_id_t a_chain_id ) +dap_chain_t *dap_chain_create(const char *a_chain_net_name, const char *a_chain_name, dap_chain_net_id_t a_chain_net_id, dap_chain_id_t a_chain_id) { dap_chain_t * l_ret = DAP_NEW_Z(dap_chain_t); if ( !l_ret ) { @@ -113,7 +113,6 @@ dap_chain_t * dap_chain_create(dap_ledger_t* a_ledger, const char * a_chain_net_ memcpy(l_ret->net_id.raw,a_chain_net_id.raw,sizeof(a_chain_net_id)); l_ret->name = strdup (a_chain_name); l_ret->net_name = strdup (a_chain_net_name); - l_ret->ledger = a_ledger; pthread_rwlock_init(&l_ret->rwlock, NULL); pthread_rwlock_init(&l_ret->cell_rwlock,NULL); dap_chain_item_t * l_ret_item = DAP_NEW_Z(dap_chain_item_t); @@ -383,7 +382,7 @@ dap_chain_t * dap_chain_load_from_cfg(dap_ledger_t* a_ledger, const char * a_cha return NULL; } - l_chain = dap_chain_create(a_ledger,a_chain_net_name,l_chain_name, a_chain_net_id,l_chain_id); + l_chain = dap_chain_create(a_chain_net_name, l_chain_name, a_chain_net_id, l_chain_id); if ( dap_chain_cs_create(l_chain, l_cfg) == 0 ) { log_it (L_NOTICE, "Consensus initialized for chain id 0x%016"DAP_UINT64_FORMAT_x, l_chain_id.uint64); @@ -583,13 +582,18 @@ int dap_chain_load_all(dap_chain_t *a_chain) log_it(L_ERROR, "Cannot open directory %s", DAP_CHAIN_PVT(a_chain)->file_storage_dir); return -3; } - for (struct dirent *l_dir_entry = readdir(l_dir); l_dir_entry != NULL; l_dir_entry = readdir(l_dir)) - { + for (struct dirent *l_dir_entry = readdir(l_dir); l_dir_entry != NULL; l_dir_entry = readdir(l_dir)) { const char * l_filename = l_dir_entry->d_name; const char l_suffix[] = ".dchaincell"; size_t l_suffix_len = strlen(l_suffix); if (!strncmp(l_filename + strlen(l_filename) - l_suffix_len, l_suffix, l_suffix_len)) { - l_ret += dap_chain_cell_load(a_chain, l_filename); + dap_chain_cell_t *l_cell = dap_chain_cell_create_fill2(a_chain, l_filename); + l_ret += dap_chain_cell_load(a_chain, l_cell); + if (DAP_CHAIN_PVT(a_chain)->need_reorder) { + const char *l_filename_backup = dap_strdup_printf("%s.unsorted", l_cell->file_storage_path); + remove(l_filename_backup); + rename(l_cell->file_storage_path, l_filename_backup); + } } } closedir(l_dir); diff --git a/modules/chain/dap_chain_cell.c b/modules/chain/dap_chain_cell.c index 7689aab2f79106bf0d1b0727aec0b023d10bb4bf..623c0eee872cff38532e354cdffa67810d3f7725 100644 --- a/modules/chain/dap_chain_cell.c +++ b/modules/chain/dap_chain_cell.c @@ -108,7 +108,8 @@ dap_chain_cell_t * dap_chain_cell_create_fill(dap_chain_t * a_chain, dap_chain_c } l_cell->chain = a_chain; l_cell->id.uint64 = a_cell_id.uint64; - l_cell->file_storage_path = dap_strdup_printf("%0"DAP_UINT64_FORMAT_x".dchaincell", l_cell->id.uint64); + snprintf(l_cell->file_storage_path, MAX_PATH, "%s/%0"DAP_UINT64_FORMAT_x".dchaincell", + DAP_CHAIN_PVT(a_chain)->file_storage_dir, l_cell->id.uint64); pthread_rwlock_init(&l_cell->storage_rwlock, NULL); HASH_ADD(hh, a_chain->cells, id, sizeof(dap_chain_cell_id_t), l_cell); pthread_rwlock_unlock(&a_chain->cell_rwlock); @@ -167,7 +168,7 @@ void dap_chain_cell_delete(dap_chain_cell_t *a_cell) pthread_rwlock_unlock(&a_cell->chain->cell_rwlock); } a_cell->chain = NULL; - DAP_DEL_Z(a_cell->file_storage_path); + a_cell->file_storage_path[0] = '\0'; pthread_rwlock_destroy(&a_cell->storage_rwlock); DAP_DEL_Z(a_cell); } @@ -179,24 +180,22 @@ void dap_chain_cell_delete(dap_chain_cell_t *a_cell) * @param a_cell_file_path contains name of chain, for example "0.dchaincell" * @return */ -int dap_chain_cell_load(dap_chain_t * a_chain, const char * a_cell_file_path) +int dap_chain_cell_load(dap_chain_t *a_chain, dap_chain_cell_t *a_cell) { int l_ret = 0; - char l_file_path[MAX_PATH] = {'\0'}; - snprintf(l_file_path, MAX_PATH, "%s/%s", DAP_CHAIN_PVT(a_chain)->file_storage_dir, a_cell_file_path); - FILE *l_cell_file = fopen(l_file_path, "rb"); + FILE *l_cell_file = fopen(a_cell->file_storage_path, "rb"); if (!l_cell_file) { - log_it(L_WARNING,"Can't read chain \"%s\"", l_file_path); + log_it(L_WARNING,"Can't read chain \"%s\"", a_cell->file_storage_path); return -1; } dap_chain_cell_file_header_t l_hdr = { 0 }; if (fread(&l_hdr, 1, sizeof(l_hdr), l_cell_file) != sizeof (l_hdr)) { - log_it(L_ERROR,"Can't read chain header \"%s\"", l_file_path); + log_it(L_ERROR,"Can't read chain header \"%s\"", a_cell->file_storage_path); fclose(l_cell_file); return -2; } if (l_hdr.signature != DAP_CHAIN_CELL_FILE_SIGNATURE) { - log_it(L_ERROR, "Wrong signature in chain \"%s\", possible file corrupt", l_file_path); + log_it(L_ERROR, "Wrong signature in chain \"%s\", possible file corrupt", a_cell->file_storage_path); fclose(l_cell_file); return -3; } @@ -210,7 +209,7 @@ int dap_chain_cell_load(dap_chain_t * a_chain, const char * a_cell_file_path) uint64_t l_el_size = 0; while ((l_read = fread(&l_el_size, 1, sizeof(l_el_size), l_cell_file)) && !feof(l_cell_file)) { if (l_read != sizeof(l_el_size) || l_el_size == 0) { - log_it(L_ERROR, "Corrupted element size %zu, chain %s is damaged", l_el_size, l_file_path); + log_it(L_ERROR, "Corrupted element size %zu, chain %s is damaged", l_el_size, a_cell->file_storage_path); l_ret = -4; break; } @@ -237,10 +236,8 @@ int dap_chain_cell_load(dap_chain_t * a_chain, const char * a_cell_file_path) if (l_ret < 0) { log_it(L_INFO, "Couldn't load all atoms, %lu only", q); } else { - log_it(L_INFO, "Loaded all %lu atoms in cell %s", q, a_cell_file_path); + log_it(L_INFO, "Loaded all %lu atoms in cell %s", q, a_cell->file_storage_path); } - if (q) - dap_chain_cell_create_fill2(a_chain, a_cell_file_path); fclose(l_cell_file); return l_ret; @@ -308,13 +305,10 @@ int dap_chain_cell_file_append(dap_chain_cell_t *a_cell, const void *a_atom, siz pthread_rwlock_wrlock(&a_cell->storage_rwlock); if (!a_cell->file_storage) { - char l_file_path[MAX_PATH] = {'\0'}; - snprintf(l_file_path, MAX_PATH, "%s/%s", DAP_CHAIN_PVT(a_cell->chain)->file_storage_dir, - a_cell->file_storage_path); - a_cell->file_storage = fopen(l_file_path, "r+b"); + a_cell->file_storage = fopen(a_cell->file_storage_path, "r+b"); if (!a_cell->file_storage) { log_it(L_INFO, "Create chain cell"); - a_cell->file_storage = fopen(l_file_path, "w+b"); + a_cell->file_storage = fopen(a_cell->file_storage_path, "w+b"); if (!a_cell->file_storage) { log_it(L_ERROR, "Chain cell \"%s\" (0x%016"DAP_UINT64_FORMAT_X") cannot be created", a_cell->file_storage_path, @@ -346,7 +340,7 @@ int dap_chain_cell_file_append(dap_chain_cell_t *a_cell, const void *a_atom, siz dap_chain_atom_iter_t *l_atom_iter = a_cell->chain->callback_atom_iter_create(a_cell->chain, a_cell->id, 0); dap_chain_atom_ptr_t l_atom = a_cell->chain->callback_atom_iter_get_first(l_atom_iter, &l_atom_size); while (l_atom && l_atom_size && ++l_count) { - ssize_t l_atom_added_size = s_file_atom_add(a_cell, a_atom, a_atom_size); + ssize_t l_atom_added_size = s_file_atom_add(a_cell, l_atom, l_atom_size); if (l_atom_added_size < 0) { l_total_wrote_bytes = l_atom_added_size; break; diff --git a/modules/chain/include/dap_chain.h b/modules/chain/include/dap_chain.h index fb80f3a4b969b4face381ab00d55fa59af415e3c..35b6cd4c7e20e41f9b21d76000b8ebbff2ad58da 100644 --- a/modules/chain/include/dap_chain.h +++ b/modules/chain/include/dap_chain.h @@ -141,7 +141,6 @@ typedef struct dap_chain { uint16_t load_priority; char *name; char *net_name; - dap_ledger_t *ledger; // If present - pointer to associated ledger bool is_datum_pool_proc; // Nested cells (hashtab by cell_id) @@ -235,7 +234,7 @@ DAP_STATIC_INLINE int dap_chain_id_parse(const char *a_id_str, dap_chain_id_t *a int dap_chain_init(void); void dap_chain_deinit(void); -dap_chain_t *dap_chain_create(dap_ledger_t* a_ledger,const char * a_chain_net_name, const char * a_chain_name, dap_chain_net_id_t a_chain_net_id, dap_chain_id_t a_chain_id ); +dap_chain_t *dap_chain_create(const char *a_chain_net_name, const char *a_chain_name, dap_chain_net_id_t a_chain_net_id, dap_chain_id_t a_chain_id); int dap_chain_load_all (dap_chain_t * a_chain); int dap_chain_save_all (dap_chain_t * a_chain); diff --git a/modules/chain/include/dap_chain_cell.h b/modules/chain/include/dap_chain_cell.h index 4101245bffed72ad4990b09f271dfc04b3bf5620..c4e16bd2f90210a20cce0edd653a130596cdc523 100644 --- a/modules/chain/include/dap_chain_cell.h +++ b/modules/chain/include/dap_chain_cell.h @@ -33,7 +33,7 @@ typedef struct dap_chain_cell { dap_chain_cell_id_t id; dap_chain_t * chain; - char * file_storage_path; + char file_storage_path[MAX_PATH]; FILE * file_storage; /// @param file_cache @brief Cache for raw blocks uint8_t file_storage_type; /// @param file_storage_type @brief Is file_storage is raw, compressed or smth else pthread_rwlock_t storage_rwlock; @@ -77,6 +77,6 @@ dap_chain_cell_t *dap_chain_cell_create_fill2(dap_chain_t *a_chain, const char * dap_chain_cell_t *dap_chain_cell_find_by_id(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id); void dap_chain_cell_close(dap_chain_cell_t *a_cell); void dap_chain_cell_delete(dap_chain_cell_t *a_cell); -int dap_chain_cell_load(dap_chain_t *a_chain, const char *a_cell_file_path); +int dap_chain_cell_load(dap_chain_t *a_chain, dap_chain_cell_t *a_cell); int dap_chain_cell_file_update(dap_chain_cell_t *a_cell); int dap_chain_cell_file_append(dap_chain_cell_t *a_cell,const void *a_atom, size_t a_atom_size); diff --git a/modules/chain/include/dap_chain_pvt.h b/modules/chain/include/dap_chain_pvt.h index b4ccc158f2d0316ebbd5ccce89a7edc84634eed4..1e2dcb0d2f661942b33b0ab739383c0e16bdf163 100644 --- a/modules/chain/include/dap_chain_pvt.h +++ b/modules/chain/include/dap_chain_pvt.h @@ -42,6 +42,7 @@ typedef struct dap_chain_pvt char * cs_name; int celled; dap_list_t *mempool_notifires; + bool need_reorder; } dap_chain_pvt_t; typedef struct dap_chain_gdb_notifier { diff --git a/modules/common/dap_chain_datum.c b/modules/common/dap_chain_datum.c index c2d0b7d9fbfc168db3699b9d9e7c652cc3c702e8..296b68449889517c3242d31cd25f516922f120f5 100644 --- a/modules/common/dap_chain_datum.c +++ b/modules/common/dap_chain_datum.c @@ -223,7 +223,8 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum, const char *a_ticker, dap_string_t *a_str_out, const char *a_hash_out_type, - dap_hash_fast_t *a_tx_hash) + dap_hash_fast_t *a_tx_hash, + dap_chain_net_id_t a_net_id) { dap_time_t l_ts_create = (dap_time_t)a_datum->header.ts_created; bool l_is_first = false; @@ -326,6 +327,11 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum, case TX_ITEM_TYPE_SIG: { l_sign_tmp = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)item); dap_sign_get_information(l_sign_tmp, a_str_out, a_hash_out_type); + dap_chain_addr_t l_sender_addr; + dap_chain_addr_fill_from_sign(&l_sender_addr, l_sign_tmp, a_net_id); + const char *l_addr_str = dap_chain_addr_to_str(&l_sender_addr); + dap_string_append_printf(a_str_out, "\tSender addr: %s", l_addr_str); + DAP_DELETE(l_addr_str); } break; case TX_ITEM_TYPE_RECEIPT: { char *l_value_str = dap_chain_balance_print( @@ -545,7 +551,7 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum, * @param a_str_out * @param a_datum */ -void dap_chain_datum_dump(dap_string_t *a_str_out, dap_chain_datum_t *a_datum, const char *a_hash_out_type) +void dap_chain_datum_dump(dap_string_t *a_str_out, dap_chain_datum_t *a_datum, const char *a_hash_out_type, dap_chain_net_id_t a_net_id) { if( a_datum == NULL){ dap_string_append_printf(a_str_out,"==Datum is NULL\n"); @@ -731,7 +737,7 @@ void dap_chain_datum_dump(dap_string_t *a_str_out, dap_chain_datum_t *a_datum, c } break; case DAP_CHAIN_DATUM_TX: { dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *)a_datum->data; - dap_chain_datum_dump_tx(l_tx, NULL, a_str_out, a_hash_out_type, &l_datum_hash); + dap_chain_datum_dump_tx(l_tx, NULL, a_str_out, a_hash_out_type, &l_datum_hash, a_net_id); } break; case DAP_CHAIN_DATUM_DECREE:{ dap_chain_datum_decree_t *l_decree = (dap_chain_datum_decree_t *)a_datum->data; diff --git a/modules/common/include/dap_chain_datum.h b/modules/common/include/dap_chain_datum.h index adf51e19b675e506f554ebb087983a4b129bdf13..922688f6d167d1bc8018ab450ed32315c0920f7d 100644 --- a/modules/common/include/dap_chain_datum.h +++ b/modules/common/include/dap_chain_datum.h @@ -154,10 +154,11 @@ DAP_STATIC_INLINE const char *dap_chain_datum_type_id_to_str(uint16_t a_type_id) } void s_datum_token_dump_tsd(dap_string_t *a_str_out, dap_chain_datum_token_t *a_token, size_t a_token_size, const char *a_hash_out_type); -void dap_chain_datum_dump(dap_string_t *a_str_out, dap_chain_datum_t *a_datum, const char *a_hash_out_type); +void dap_chain_datum_dump(dap_string_t *a_str_out, dap_chain_datum_t *a_datum, const char *a_hash_out_type, dap_chain_net_id_t a_net_id); bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum, const char *a_ticker, dap_string_t *a_str_out, const char *a_hash_out_type, - dap_hash_fast_t *a_tx_hash); + dap_hash_fast_t *a_tx_hash, + dap_chain_net_id_t a_net_id); json_object * dap_chain_datum_to_json(dap_chain_datum_t* a_datum); diff --git a/modules/consensus/block-pos/dap_chain_cs_block_pos.c b/modules/consensus/block-pos/dap_chain_cs_block_pos.c index d0acf7c33c786bd797a6cd9e5abef387b6feda01..2bb0196dfd7cb6fac335e173ae2fe4a2b6f96da2 100644 --- a/modules/consensus/block-pos/dap_chain_cs_block_pos.c +++ b/modules/consensus/block-pos/dap_chain_cs_block_pos.c @@ -95,11 +95,11 @@ static int s_callback_new(dap_chain_t *a_chain, dap_config_t *a_chain_cfg) l_blocks->callback_block_verify = s_callback_block_verify; l_blocks->callback_block_sign = s_callback_block_sign; l_pos->_pvt = DAP_NEW_Z(dap_chain_cs_block_pos_pvt_t); - if (!l_pos->_pvt) { + dap_chain_cs_block_pos_pvt_t *l_pos_pvt = PVT(l_pos); + if (!l_pos_pvt) { log_it(L_CRITICAL, "Memory allocation error"); goto lb_err; } - dap_chain_cs_block_pos_pvt_t *l_pos_pvt = PVT(l_pos); l_tokens_hold = dap_config_get_array_str(a_chain_cfg, "block-pos", "stake_tokens", &l_tokens_hold_size); l_tokens_hold_value_str = dap_config_get_array_str(a_chain_cfg, "block-pos", "stake_tokens_value", &l_tokens_hold_value_size); @@ -229,11 +229,6 @@ static int s_callback_block_verify(dap_chain_cs_blocks_t *a_blocks, dap_chain_bl dap_chain_cs_block_pos_t *l_pos = DAP_CHAIN_CS_BLOCK_POS(a_blocks); dap_chain_cs_block_pos_pvt_t *l_pos_pvt = PVT(l_pos); - if (a_blocks->chain->ledger == NULL) { - log_it(L_CRITICAL,"Ledger is NULL can't check PoS on this chain %s", a_blocks->chain->name); - return -3; - } - if (sizeof(a_block->hdr) >= a_block_size) { log_it(L_WARNING,"Incorrect size with block %p on chain %s", a_block, a_blocks->chain->name); return -7; diff --git a/modules/consensus/dag-pos/dap_chain_cs_dag_pos.c b/modules/consensus/dag-pos/dap_chain_cs_dag_pos.c index b3da9c6230fc43f78f1e5c5a99fb20579a3e1e01..6396740f1af4654ddae1329dcfea8561cd994ae0 100644 --- a/modules/consensus/dag-pos/dap_chain_cs_dag_pos.c +++ b/modules/consensus/dag-pos/dap_chain_cs_dag_pos.c @@ -244,11 +244,6 @@ static int s_callback_event_verify(dap_chain_cs_dag_t * a_dag, dap_chain_cs_dag_ { dap_chain_cs_dag_pos_pvt_t * l_pos_pvt = PVT ( DAP_CHAIN_CS_DAG_POS( a_dag ) ); - if(a_dag->chain->ledger == NULL){ - log_it(L_CRITICAL,"Ledger is NULL can't check PoS on this chain %s", a_dag->chain->name); - return -3; - } - if (sizeof (a_dag_event->header)>= a_dag_event_size){ log_it(L_WARNING,"Incorrect size with event %p on chain %s", a_dag_event, a_dag->chain->name); return -7; diff --git a/modules/consensus/esbocs/dap_chain_cs_esbocs.c b/modules/consensus/esbocs/dap_chain_cs_esbocs.c index 31aafd7d105def0119226acbac2c35734597a010..ed6990416867e37fa4ce88915a87a21fa789cae9 100644 --- a/modules/consensus/esbocs/dap_chain_cs_esbocs.c +++ b/modules/consensus/esbocs/dap_chain_cs_esbocs.c @@ -1479,7 +1479,8 @@ static void s_check_db_callback_fee_collect (UNUSED_ARG dap_global_db_context_t log_it(L_WARNING, "The block_cache is empty"); return; } - dap_list_t *l_list_used_out = dap_chain_block_get_list_tx_cond_outs_with_val(l_chain->ledger,l_block_cache,&l_value_out_block); + dap_ledger_t *l_ledger = dap_chain_net_by_id(l_chain->net_id)->pub.ledger; + dap_list_t *l_list_used_out = dap_chain_block_get_list_tx_cond_outs_with_val(l_ledger, l_block_cache, &l_value_out_block); if(!l_list_used_out) { log_it(L_WARNING, "There aren't any fee in this block"); @@ -2468,10 +2469,7 @@ static int s_callback_block_verify(dap_chain_cs_blocks_t *a_blocks, dap_chain_bl { dap_chain_esbocs_t *l_esbocs = DAP_CHAIN_ESBOCS(a_blocks); dap_chain_esbocs_pvt_t *l_esbocs_pvt = PVT(l_esbocs); - if (a_blocks->chain->ledger == NULL) { - log_it(L_CRITICAL,"Ledger is NULL can't check consensus conditions on this chain %s", a_blocks->chain->name); - return -3; - } + if (sizeof(a_block->hdr) >= a_block_size) { log_it(L_WARNING, "Incorrect header size with block %p on chain %s", a_block, a_blocks->chain->name); return -7; @@ -2480,7 +2478,7 @@ static int s_callback_block_verify(dap_chain_cs_blocks_t *a_blocks, dap_chain_bl /*if (a_block->hdr.meta_n_datum_n_signs_size != a_block_size - sizeof(a_block->hdr)) { log_it(L_WARNING, "Incorrect size with block %p on chain %s", a_block, a_blocks->chain->name); return -8; - }*/ // TODO Retunn it after hard-fork with correct block sizes + }*/ // TODO Retun it after hard-fork with correct block sizes if (l_esbocs->session && l_esbocs->session->processing_candidate == a_block) // It's a block candidate, don't check signs diff --git a/modules/mempool/dap_chain_mempool.c b/modules/mempool/dap_chain_mempool.c index 1b2a10a46b73abb419a032ac4af72f1d2d069c87..40ad34ae818bc4a2ca090ffc199abc854def6c19 100644 --- a/modules/mempool/dap_chain_mempool.c +++ b/modules/mempool/dap_chain_mempool.c @@ -159,17 +159,18 @@ char *dap_chain_mempool_tx_create(dap_chain_t * a_chain, dap_enc_key_t *a_key_fr dap_list_t *l_list_fee_out = NULL; bool l_net_fee_used = dap_chain_net_tx_get_fee(a_chain->net_id, &l_net_fee, &l_addr_fee); SUM_256_256(l_net_fee, a_value_fee, &l_total_fee); + dap_ledger_t *l_ledger = dap_chain_net_by_id(a_chain->net_id)->pub.ledger; if (l_single_channel) SUM_256_256(l_value_need, l_total_fee, &l_value_need); else if (!IS_ZERO_256(l_total_fee)) { - l_list_fee_out = dap_chain_ledger_get_list_tx_outs_with_val(a_chain->ledger, l_native_ticker, + l_list_fee_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, l_native_ticker, a_addr_from, l_total_fee, &l_fee_transfer); if (!l_list_fee_out) { log_it(L_WARNING, "Not enough funds to pay fee"); return NULL; } } - dap_list_t *l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(a_chain->ledger, a_token_ticker, + dap_list_t *l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, a_token_ticker, a_addr_from, l_value_need, &l_value_transfer); if (!l_list_used_out) { log_it(L_WARNING, "Not enough funds to transfer"); @@ -306,12 +307,11 @@ char *dap_chain_mempool_tx_coll_fee_create(dap_enc_key_t *a_key_from,const dap_c log_it(L_WARNING, "Can't create datum tx"); return NULL; } - - for(dap_list_t *bl = a_block_list; bl; bl = bl->next) - { + dap_ledger_t *l_ledger = dap_chain_net_by_id(l_chain->net_id)->pub.ledger; + for(dap_list_t *bl = a_block_list; bl; bl = bl->next) { uint256_t l_value_out_block = {}; dap_chain_block_cache_t *l_block_cache = (dap_chain_block_cache_t *)bl->data; - dap_list_t *l_list_used_out = dap_chain_block_get_list_tx_cond_outs_with_val(l_chain->ledger,l_block_cache,&l_value_out_block); + dap_list_t *l_list_used_out = dap_chain_block_get_list_tx_cond_outs_with_val(l_ledger, l_block_cache, &l_value_out_block); if (!l_list_used_out) continue; //add 'in' items @@ -420,7 +420,8 @@ int dap_chain_mempool_tx_create_massive( dap_chain_t * a_chain, dap_enc_key_t *a char *l_balance = dap_chain_balance_to_coins(l_value_need); log_it(L_DEBUG, "Create %"DAP_UINT64_FORMAT_U" transactions, summary %s", a_tx_num, l_balance); DAP_DELETE(l_balance); - dap_list_t *l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(a_chain->ledger, a_token_ticker, + dap_ledger_t *l_ledger = dap_chain_net_by_id(a_chain->net_id)->pub.ledger; + dap_list_t *l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, a_token_ticker, a_addr_from, l_value_need, &l_value_transfer); if (!l_list_used_out) { log_it(L_WARNING,"Not enough funds to transfer"); @@ -880,8 +881,9 @@ char *dap_chain_mempool_base_tx_create(dap_chain_t *a_chain, dap_chain_hash_fast dap_chain_datum_tx_delete(l_tx); return NULL; } + dap_ledger_t *l_ledger = dap_chain_net_by_id(a_chain->net_id)->pub.ledger; // list of transaction with 'out' items - l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(a_chain->ledger, l_native_ticker, + l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, l_native_ticker, &l_addr_from_fee, l_total_fee, &l_value_transfer); if (!l_list_used_out) { log_it(L_WARNING,"Not enough funds to transfer"); diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c index 325109036487ea1e812d6c53d6fd000b444a07f3..e0c0bcd8e548bb6b7397f077b22c7f4215b7577b 100644 --- a/modules/net/dap_chain_net.c +++ b/modules/net/dap_chain_net.c @@ -886,7 +886,7 @@ static void s_node_link_callback_disconnected(dap_chain_node_client_t *a_node_cl //char *l_key = dap_chain_node_addr_to_hash_str(&a_node_client->info->hdr.address); //dap_global_db_del_sync(l_net->pub.gdb_nodes, l_key); //DAP_DELETE(l_key); - log_it(L_DEBUG, "Remove "NODE_ADDR_FP_STR" from local db",NODE_ADDR_FP_ARGS_S(a_node_client->info->hdr.address)); + a_node_client->keep_connection = false; a_node_client->callbacks.delete = NULL; dap_chain_node_client_close_mt(a_node_client); // Remove it on next context iteration @@ -1165,13 +1165,15 @@ static bool s_new_balancer_link_request(dap_chain_net_t *a_net, int a_link_repla return true; } if(!a_link_replace_tries){ - dap_chain_net_node_balancer_t *l_link_full_node_list = dap_chain_net_balancer_get_node(a_net->pub.name,l_net_pvt->required_links_count); - size_t node_cnt = 0,i = 0; + + dap_chain_net_node_balancer_t *l_link_full_node_list = dap_chain_net_balancer_get_node(a_net->pub.name,l_net_pvt->max_links_count*2); + size_t node_cnt = 0,i = 0; if(l_link_full_node_list) { dap_chain_node_info_t * l_node_info = (dap_chain_node_info_t *)l_link_full_node_list->nodes_info; node_cnt = l_link_full_node_list->count_node; int l_net_link_add = 0; + size_t l_links_count = 0; while(!l_net_link_add){ if(i >= node_cnt) break; @@ -1185,17 +1187,27 @@ static bool s_new_balancer_link_request(dap_chain_net_t *a_net, int a_link_repla break; case 1: log_it(L_MSG, "Network links table is full"); - break; + break; default: break; } + l_links_count = HASH_COUNT(l_net_pvt->net_links); + if(l_net_link_add && l_links_count < l_net_pvt->required_links_count && i < node_cnt)l_net_link_add = 0; i++; } DAP_DELETE(l_link_full_node_list); + pthread_mutex_lock(&l_net_pvt->uplinks_mutex); struct net_link *l_free_link = s_get_free_link(a_net); - if (l_free_link) + if (l_free_link){ s_net_link_start(a_net, l_free_link, l_net_pvt->reconnect_delay); - return true; + pthread_mutex_unlock(&l_net_pvt->uplinks_mutex); + return true; + } + else + { + pthread_mutex_unlock(&l_net_pvt->uplinks_mutex); + return false; + } } } dap_chain_node_info_t *l_link_node_info = dap_get_balancer_link_from_cfg(a_net); @@ -1539,6 +1551,7 @@ static dap_chain_net_t *s_net_new(const char *a_id, const char *a_name, pthread_mutexattr_init(&l_mutex_attr); pthread_mutexattr_settype(&l_mutex_attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&PVT(l_ret)->uplinks_mutex, &l_mutex_attr); + pthread_mutex_init(&l_ret->pub.balancer_mutex, &l_mutex_attr); pthread_mutexattr_destroy(&l_mutex_attr); pthread_rwlock_init(&PVT(l_ret)->downlinks_lock, NULL); pthread_rwlock_init(&PVT(l_ret)->states_lock, NULL); @@ -1577,6 +1590,7 @@ static dap_chain_net_t *s_net_new(const char *a_id, const char *a_name, void dap_chain_net_delete( dap_chain_net_t * a_net ) { pthread_mutex_destroy(&PVT(a_net)->uplinks_mutex); + pthread_mutex_destroy(&a_net->pub.balancer_mutex); pthread_rwlock_destroy(&PVT(a_net)->downlinks_lock); pthread_rwlock_destroy(&PVT(a_net)->states_lock); if(PVT(a_net)->seed_aliases) { @@ -1953,6 +1967,7 @@ static int s_cli_net(int argc, char **argv, char **a_str_reply) dap_cli_server_cmd_set_reply_text(a_str_reply, "Network \"%s\" going from state %s to %s", l_net->pub.name,c_net_states[PVT(l_net)->state], c_net_states[NET_STATE_ONLINE]); + dap_chain_net_balancer_prepare_list_links(l_net->pub.name,true); dap_chain_net_state_go_to(l_net, NET_STATE_ONLINE); } else if ( strcmp(l_go_str,"offline") == 0 ) { dap_cli_server_cmd_set_reply_text(a_str_reply, "Network \"%s\" going from state %s to %s", @@ -2292,6 +2307,7 @@ void s_main_timer_callback(void *a_arg) l_net_pvt->state >= NET_STATE_LINKS_ESTABLISHED && !s_net_get_active_links_count(l_net)) // restart network dap_chain_net_start(l_net); + dap_chain_net_balancer_prepare_list_links(l_net->pub.name,false); } /** @@ -2863,10 +2879,29 @@ int s_net_load(dap_chain_net_t *a_net) // load chains dap_chain_t *l_chain = l_net->pub.chains; while(l_chain){ - l_chain->ledger = l_net->pub.ledger; dap_chain_ledger_set_fee(l_net->pub.ledger, uint256_0, c_dap_chain_addr_blank); if (!dap_chain_load_all(l_chain)) { log_it (L_NOTICE, "Loaded chain files"); + if (DAP_CHAIN_PVT(l_chain)->need_reorder) { + log_it(L_DAP, "Reordering chain files for chain %s", l_chain->name); + if (l_chain->callback_atom_add_from_treshold) + while (l_chain->callback_atom_add_from_treshold(l_chain, NULL)) + log_it(L_DEBUG, "Added atom from treshold"); + dap_chain_save_all(l_chain); + DAP_CHAIN_PVT(l_chain)->need_reorder = false; + if (l_chain->callback_purge) { + l_chain->callback_purge(l_chain); + pthread_rwlock_wrlock(&l_chain->cell_rwlock); + for (dap_chain_cell_t *it = l_chain->cells; it; it = it->hh.next) + dap_chain_cell_delete(it); + pthread_rwlock_unlock(&l_chain->cell_rwlock); + dap_chain_ledger_purge(l_net->pub.ledger, false); + dap_chain_ledger_set_fee(l_net->pub.ledger, uint256_0, c_dap_chain_addr_blank); + dap_chain_net_decree_purge(l_net); + dap_chain_load_all(l_chain); + } else + log_it(L_WARNING, "No purge callback for chain %s, can't reload it with correct order", l_chain->name); + } } else { dap_chain_save_all( l_chain ); log_it (L_NOTICE, "Initialized chain files"); @@ -2937,9 +2972,12 @@ int s_net_load(dap_chain_net_t *a_net) } if (!l_net_pvt->only_static_links) - l_net_pvt->only_static_links = dap_config_get_item_bool_default(l_cfg, "general", "links_static_only", false); + l_net_pvt->only_static_links = dap_config_get_item_bool_default(l_cfg, "general", "links_static_only", true); if (dap_config_get_item_bool_default(g_config ,"general", "auto_online", false)) + { + dap_chain_net_balancer_prepare_list_links(l_net->pub.name,true); l_target_state = NET_STATE_ONLINE; + } l_net_pvt->load_mode = false; if (l_net->pub.ledger) @@ -3610,6 +3648,7 @@ int dap_chain_datum_add(dap_chain_t *a_chain, dap_chain_datum_t *a_datum, size_t a_datum_size ); return -101; } + dap_ledger_t *l_ledger = dap_chain_net_by_id(a_chain->net_id)->pub.ledger; switch (a_datum->header.type_id) { case DAP_CHAIN_DATUM_DECREE: { dap_chain_datum_decree_t *l_decree = (dap_chain_datum_decree_t *)a_datum->data; @@ -3630,10 +3669,10 @@ int dap_chain_datum_add(dap_chain_t *a_chain, dap_chain_datum_t *a_datum, size_t return dap_chain_net_anchor_load(l_anchor, a_chain); } case DAP_CHAIN_DATUM_TOKEN_DECL: - return dap_chain_ledger_token_load(a_chain->ledger, (dap_chain_datum_token_t *)a_datum->data, a_datum->header.data_size); + return dap_chain_ledger_token_load(l_ledger, (dap_chain_datum_token_t *)a_datum->data, a_datum->header.data_size); case DAP_CHAIN_DATUM_TOKEN_EMISSION: - return dap_chain_ledger_token_emission_load(a_chain->ledger, a_datum->data, a_datum->header.data_size, a_datum_hash); + return dap_chain_ledger_token_emission_load(l_ledger, a_datum->data, a_datum->header.data_size, a_datum_hash); case DAP_CHAIN_DATUM_TX: { dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *)a_datum->data; @@ -3642,7 +3681,7 @@ int dap_chain_datum_add(dap_chain_t *a_chain, dap_chain_datum_t *a_datum, size_t log_it(L_WARNING, "Corrupted trnsaction, datum size %zd is not equal to size of TX %zd", l_datum_data_size, l_tx_size); return -102; } - return dap_chain_ledger_tx_load(a_chain->ledger, l_tx, a_datum_hash); + return dap_chain_ledger_tx_load(l_ledger, l_tx, a_datum_hash); } case DAP_CHAIN_DATUM_CA: return dap_cert_chain_file_save(a_datum, a_chain->net_name); diff --git a/modules/net/dap_chain_net_balancer.c b/modules/net/dap_chain_net_balancer.c index 4b4087c85e0ddede0984670a1ca1159b92074d5a..daf444d9c61ec4c5cc390314c003c3a858e64cb0 100644 --- a/modules/net/dap_chain_net_balancer.c +++ b/modules/net/dap_chain_net_balancer.c @@ -25,42 +25,75 @@ along with any CellFrame SDK based project. If not, see <http://www.gnu.org/lic #include "dap_chain_net_balancer.h" #include "dap_chain_net.h" #include "http_status_code.h" +#include "dap_chain_node_client.h" #define LOG_TAG "dap_chain_net_balancer" -static int callback_compare_node_list(const void * a_item1, const void * a_item2, void *a_unused) +static bool dap_chain_net_balancer_find_link(dap_chain_node_info_t *a_node_info,dap_chain_net_t * a_net) { - UNUSED(a_unused); - if (!a_item1 || !a_item2) { - return 0; + dap_list_t * l_link_list = a_net->pub.link_list; + for(dap_list_t *ll = l_link_list; ll; ll = ll->next) + { + dap_chain_node_info_t *l_node_link = (dap_chain_node_info_t*)ll->data; + if(l_node_link && l_node_link->hdr.ext_addr_v4.s_addr == a_node_info->hdr.ext_addr_v4.s_addr) + return true; } - dap_chain_node_info_t *l_item1 = (dap_chain_node_info_t*)a_item1, *l_item2 = (dap_chain_node_info_t*)a_item2; - return l_item1->hdr.links_number == l_item2->hdr.links_number - ? 0 : l_item1->hdr.links_number > l_item2->hdr.links_number - ? 1 : -1; + + return false; } -dap_chain_net_node_balancer_t *dap_chain_net_balancer_get_node(const char *a_net_name,uint16_t a_links_need) +void dap_chain_net_balancer_set_link_list(dap_chain_node_info_t *a_node_info, const char *a_net_name) { - dap_list_t *l_node_addr_list = NULL,*l_objs_list = NULL; dap_chain_net_t *l_net = dap_chain_net_by_name(a_net_name); - if (l_net == NULL) { - log_it(L_WARNING, "There isn't any network by this name - %s", a_net_name); - return NULL; + if(dap_chain_net_balancer_find_link(a_node_info,l_net)) + return; + + dap_chain_node_info_t * l_node_info = DAP_NEW_Z( dap_chain_node_info_t); + *l_node_info = *a_node_info; + l_net->pub.link_list = dap_list_append(l_net->pub.link_list,l_node_info); + + log_it(L_DEBUG, "Add addr "NODE_ADDR_FP_STR" to balancer link list",NODE_ADDR_FP_ARGS_S(a_node_info->hdr.address)); +} + +void dap_chain_net_balancer_free_link_list(dap_chain_net_t * a_net) +{ + dap_list_free_full(a_net->pub.link_list, NULL); + a_net->pub.link_list = NULL; + log_it(L_DEBUG, "Balancer link list cleared"); +} + +static bool dap_chain_net_balancer_handshake(dap_chain_node_info_t *a_node_info,dap_chain_net_t * a_net) +{ + dap_chain_node_client_t *l_client = dap_chain_node_client_connect_default_channels(a_net,a_node_info); + if(!l_client) { + return false; } - // get nodes list from global_db - dap_global_db_obj_t *l_objs = NULL; - size_t l_nodes_count = 0; - size_t l_node_num = 0,l_links_need = 0; + // wait handshake + int timeout_ms = 1000; + int res = dap_chain_node_client_wait(l_client, NODE_CLIENT_STATE_ESTABLISHED, timeout_ms); + if (res) { + dap_chain_node_client_close_mt(l_client); + return false; + } + return true; +} +static bool is_it_node_from_list(dap_list_t *a_node_addr_list, dap_chain_node_info_t *a_node_cand) +{ + for(dap_list_t *node_i = a_node_addr_list; node_i; node_i = node_i->next) + { + struct in_addr *l_node_addr_cfg = (struct in_addr*)node_i->data; + if(a_node_cand->hdr.ext_addr_v4.s_addr && a_node_cand->hdr.ext_port && + (l_node_addr_cfg->s_addr == a_node_cand->hdr.ext_addr_v4.s_addr)) + return true; + } + return false; +} +static uint64_t min_count_blocks_events(dap_global_db_obj_t * a_objs,size_t a_node_count,dap_list_t * a_node_addr_list) +{ uint64_t l_blocks_events = 0; - // read all node - l_objs = dap_global_db_get_all_sync(l_net->pub.gdb_nodes, &l_nodes_count); - if (!l_nodes_count || !l_objs) - return NULL; - l_node_addr_list = dap_chain_net_get_node_list_cfg(l_net); - for (size_t i = 0; i < l_nodes_count; i++) { - dap_chain_node_info_t *l_node_cand = (dap_chain_node_info_t *)l_objs[i].value; - for (dap_list_t *node_i = l_node_addr_list; node_i; node_i = node_i->next) { + for (size_t i = 0; i < a_node_count; i++) { + dap_chain_node_info_t *l_node_cand = (dap_chain_node_info_t *)a_objs[i].value; + for (dap_list_t *node_i = a_node_addr_list; node_i; node_i = node_i->next) { if(((struct in_addr*)node_i->data)->s_addr == l_node_cand->hdr.ext_addr_v4.s_addr) { if (!l_blocks_events || l_blocks_events > l_node_cand->hdr.blocks_events) l_blocks_events = l_node_cand->hdr.blocks_events; @@ -68,34 +101,99 @@ dap_chain_net_node_balancer_t *dap_chain_net_balancer_get_node(const char *a_net } } } - log_it(L_DEBUG, "The smallest block size among seed nodes is - %ld", l_blocks_events); - for (size_t i = 0; i < l_nodes_count; i++) + return l_blocks_events; +} + +void dap_chain_net_balancer_prepare_list_links(const char *a_net_name,bool handshake_on) +{ + dap_list_t *l_node_addr_list = NULL,*l_links_temp = NULL; + dap_chain_net_t *l_net = dap_chain_net_by_name(a_net_name); + if (l_net == NULL) { + log_it(L_WARNING, "There isn't any network by this name - %s", a_net_name); + return; + } + + dap_global_db_obj_t *l_objs = NULL; + size_t l_nodes_count = 0,link_list_count = 0; + uint64_t l_blocks_events = 0; + // read all node + l_objs = dap_global_db_get_all_sync(l_net->pub.gdb_nodes, &l_nodes_count); + if (!l_nodes_count || !l_objs) + return; + + l_node_addr_list = dap_chain_net_get_node_list_cfg(l_net); + l_blocks_events = min_count_blocks_events(l_objs,l_nodes_count,l_node_addr_list); + pthread_mutex_lock(&l_net->pub.balancer_mutex); + //clear list links + //link_list_count = dap_list_length(l_net->pub.link_list); + if(!handshake_on) { - bool l_check = true; - dap_chain_node_info_t *l_node_cand = (dap_chain_node_info_t *)l_objs[i].value; - for(dap_list_t *node_i = l_node_addr_list; node_i; node_i = node_i->next) - { - struct in_addr *l_node_addr_cfg = (struct in_addr*)node_i->data; - if(l_node_cand->hdr.ext_addr_v4.s_addr && l_node_cand->hdr.ext_port && - (l_node_addr_cfg->s_addr != l_node_cand->hdr.ext_addr_v4.s_addr)) - { - continue; - } - else + log_it(L_DEBUG, "Adjusting node list"); + for (size_t i = 0; i < l_nodes_count; i++) { + dap_chain_node_info_t *l_node_cand = (dap_chain_node_info_t *)l_objs[i].value; + for(dap_list_t *node_i = l_net->pub.link_list; node_i; node_i = node_i->next) { - l_check = false; - break; + dap_chain_node_info_t *l_node_list = (dap_chain_node_info_t *)node_i->data; + if(l_node_list->hdr.address.uint64 == l_node_cand->hdr.address.uint64) + { + // if(l_node_cand->hdr.blocks_events >= l_blocks_events/2) + // { + dap_chain_node_info_t * l_node_info = DAP_NEW_Z( dap_chain_node_info_t); + *l_node_info = *l_node_cand; + l_links_temp = dap_list_append(l_links_temp,l_node_info); + // } + } } } - if(l_check){ - if(l_node_cand->hdr.blocks_events >= l_blocks_events){ - l_objs_list = dap_list_append(l_objs_list,l_objs[i].value); - l_node_num++; + dap_chain_net_balancer_free_link_list(l_net); + l_net->pub.link_list = dap_list_copy(l_links_temp); + dap_list_free(l_links_temp); + } + else{ + log_it(L_DEBUG, "Overwrite node list"); + dap_list_free_full(l_net->pub.link_list, NULL); + l_net->pub.link_list = NULL; + for (size_t i = 0; i < l_nodes_count; i++) + { + dap_chain_node_info_t *l_node_cand = (dap_chain_node_info_t *)l_objs[i].value; + if(!is_it_node_from_list(l_node_addr_list, l_node_cand)){ + if(l_node_cand->hdr.blocks_events >= l_blocks_events){ + if(dap_chain_net_balancer_handshake(l_node_cand,l_net)){ + dap_chain_net_balancer_set_link_list(l_node_cand,l_net->pub.name); + } + } } } } + pthread_mutex_unlock(&l_net->pub.balancer_mutex); + dap_global_db_objs_delete(l_objs, l_nodes_count); dap_list_free(l_node_addr_list); - l_objs_list = dap_list_sort(l_objs_list, callback_compare_node_list); +} + +static int callback_compare_node_list(const void * a_item1, const void * a_item2, void *a_unused) +{ + UNUSED(a_unused); + if (!a_item1 || !a_item2) { + return 0; + } + dap_chain_node_info_t *l_item1 = (dap_chain_node_info_t*)a_item1, *l_item2 = (dap_chain_node_info_t*)a_item2; + return l_item1->hdr.links_number == l_item2->hdr.links_number + ? 0 : l_item1->hdr.links_number > l_item2->hdr.links_number + ? 1 : -1; +} + +dap_chain_net_node_balancer_t *dap_chain_net_balancer_get_node(const char *a_net_name,uint16_t a_links_need) +{ + dap_chain_net_t *l_net = dap_chain_net_by_name(a_net_name); + if (l_net == NULL) { + log_it(L_WARNING, "There isn't any network by this name - %s", a_net_name); + return NULL; + } + // get nodes list from global_db + pthread_mutex_lock(&l_net->pub.balancer_mutex); + size_t l_node_num = 0,l_links_need = 0; + l_net->pub.link_list = dap_list_sort(l_net->pub.link_list, callback_compare_node_list); + l_node_num = dap_list_length(l_net->pub.link_list); dap_chain_node_info_t *l_node_candidate; if(l_node_num) { @@ -103,30 +201,28 @@ dap_chain_net_node_balancer_t *dap_chain_net_balancer_get_node(const char *a_net dap_chain_net_node_balancer_t *l_node_list_res = DAP_NEW_Z_SIZE(dap_chain_net_node_balancer_t, sizeof(dap_chain_net_node_balancer_t) + l_links_need * sizeof(dap_chain_node_info_t)); dap_chain_node_info_t * l_node_info = (dap_chain_node_info_t *)l_node_list_res->nodes_info; - dap_list_t *nl = l_objs_list; + dap_list_t *nl = l_net->pub.link_list; for(size_t i=0; i<l_links_need; i++,nl = nl->next) { l_node_candidate = (dap_chain_node_info_t*)nl->data; *(l_node_info + i) = *l_node_candidate; } l_node_list_res->count_node = l_links_need; - dap_list_free(l_objs_list); - dap_global_db_objs_delete(l_objs, l_nodes_count); + pthread_mutex_unlock(&l_net->pub.balancer_mutex); return l_node_list_res; } else - { - dap_list_free(l_objs_list); - dap_global_db_objs_delete(l_objs, l_nodes_count); + { log_it(L_ERROR, "Node list is empty"); + pthread_mutex_unlock(&l_net->pub.balancer_mutex); return NULL; } } -dap_chain_net_node_balancer_t *s_balancer_issue_link(const char *a_net_name,uint16_t a_links_need) +dap_chain_net_node_balancer_t *s_balancer_issue_link(const char *a_net_name, uint16_t a_links_need) { dap_chain_net_t *l_net = dap_chain_net_by_name(a_net_name); - dap_chain_net_node_balancer_t *l_link_full_node_list = dap_chain_net_balancer_get_node(a_net_name,a_links_need); + dap_chain_net_node_balancer_t *l_link_full_node_list = dap_chain_net_balancer_get_node(a_net_name, a_links_need); if(l_link_full_node_list) { dap_chain_node_info_t * l_node_info = (dap_chain_node_info_t *)l_link_full_node_list->nodes_info; @@ -168,8 +264,8 @@ void dap_chain_net_balancer_http_issue_link(dap_http_simple_t *a_http_simple, vo char l_issue_method = 0; const char l_net_token[] = "net="; uint16_t links_need = 0; - sscanf(a_http_simple->http_client->in_query_string, "version=%d,method=%c,needlink=%d,net=", - &l_protocol_version, &l_issue_method,&links_need); + sscanf(a_http_simple->http_client->in_query_string, "version=%d,method=%c,needlink=%hu,net=", + &l_protocol_version, &l_issue_method, &links_need); if (l_protocol_version != 1 || l_issue_method != 'r') { log_it(L_ERROR, "Unsupported prorocol version/method in the request to dap_chain_net_balancer module"); *l_return_code = Http_Status_MethodNotAllowed; @@ -206,5 +302,12 @@ void dap_chain_net_balancer_http_issue_link(dap_http_simple_t *a_http_simple, vo dap_chain_node_info_t *dap_chain_net_balancer_dns_issue_link(char *a_str) { log_it(L_DEBUG, "DNS balancer parser retrieve netname %s", a_str); - return s_balancer_issue_link(a_str,3); + dap_chain_net_node_balancer_t *l_balancer_reply = s_balancer_issue_link(a_str, 1); + if (!l_balancer_reply || !l_balancer_reply->count_node) { + DAP_DEL_Z(l_balancer_reply); + return NULL; + } + dap_chain_node_info_t *l_res = DAP_DUP(( dap_chain_node_info_t *)l_balancer_reply->nodes_info); + DAP_DELETE(l_balancer_reply); + return l_res; } diff --git a/modules/net/dap_chain_node_cli.c b/modules/net/dap_chain_node_cli.c index 81170611ae3c0c89db55c82d839e16d1cfa2da78..b31b10ab77ad7cdd0b33f107c79a45afbf6a0efc 100644 --- a/modules/net/dap_chain_node_cli.c +++ b/modules/net/dap_chain_node_cli.c @@ -103,6 +103,8 @@ int dap_chain_node_cli_init(dap_config_t * g_config) "node alias -addr <node_address> -alias <node_alias>\n\n" "node connect -net <net_name> {-addr <node_address> | -alias <node_alias> | auto}\n\n" "node handshake -net <net_name> {-addr <node_address> | -alias <node_alias>}\n" + "node connections -net <net_name>\n" + "node balancer -net <net_name>\n" "node dump -net <net_name> [ -addr <node_address> | -alias <node_alias>] [-full]\n\n" ); dap_cli_server_cmd_add ("ping", com_ping, "Send ICMP ECHO_REQUEST to network hosts", diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c index 1fd37e4d10d4e8cf26f401de8760b54138a1558a..c0f3cd62f1e231550a65af2605d7afdf20430447 100644 --- a/modules/net/dap_chain_node_cli_cmd.c +++ b/modules/net/dap_chain_node_cli_cmd.c @@ -1131,7 +1131,7 @@ int com_global_db(int a_argc, char ** a_argv, char **a_str_reply) int com_node(int a_argc, char ** a_argv, char **a_str_reply) { enum { - CMD_NONE, CMD_ADD, CMD_DEL, CMD_LINK, CMD_ALIAS, CMD_HANDSHAKE, CMD_CONNECT, CMD_DUMP, CMD_CONNECTIONS + CMD_NONE, CMD_ADD, CMD_DEL, CMD_LINK, CMD_ALIAS, CMD_HANDSHAKE, CMD_CONNECT, CMD_DUMP, CMD_CONNECTIONS, CMD_BALANCER }; int arg_index = 1; int cmd_num = CMD_NONE; @@ -1166,6 +1166,9 @@ int com_node(int a_argc, char ** a_argv, char **a_str_reply) // DAP_DELETE(l_str); // return 0; } + else if (dap_cli_server_cmd_find_option_val(a_argv, arg_index, MIN(a_argc, arg_index + 1), "balancer", NULL)){ + cmd_num = CMD_BALANCER; + } arg_index++; if(cmd_num == CMD_NONE) { dap_cli_server_cmd_set_reply_text(a_str_reply, "command %s not recognized", a_argv[1]); @@ -1578,8 +1581,8 @@ int com_node(int a_argc, char ** a_argv, char **a_str_reply) dap_string_t *l_str_uplinks = dap_string_new("---------------------------\n" "| ↑\\↓ |\t#\t|\t\tIP\t\t|\tPort\t|\n"); for (size_t i=0; i < l_uplink_count; i++) { - char *l_address = l_uplinks[i]->address; - short l_port = l_uplinks[i]->port; + char *l_address = l_uplinks[i]->stream->esocket->remote_addr_str; + short l_port = l_uplinks[i]->stream->esocket->remote_port; dap_string_append_printf(l_str_uplinks, "| ↑ |\t%zu\t|\t%s\t\t|\t%u\t|\n", i, l_address, l_port); @@ -1602,6 +1605,24 @@ int com_node(int a_argc, char ** a_argv, char **a_str_reply) return 0; } break; + case CMD_BALANCER: { + //balancer link list + size_t l_node_num = 0; + dap_string_t * l_string_balanc = dap_string_new("\n"); + l_node_num = dap_list_length(l_net->pub.link_list); + dap_string_append_printf(l_string_balanc, "Got %d records\n", (uint16_t)l_node_num); + for(dap_list_t *ll = l_net->pub.link_list; ll; ll = ll->next) + { + dap_chain_node_info_t *l_node_link = (dap_chain_node_info_t*)ll->data; + dap_string_append_printf(l_string_balanc, "node address "NODE_ADDR_FP_STR" \tipv4 %s \tnumber of links %u\n", + NODE_ADDR_FP_ARGS_S(l_node_link->hdr.address), + inet_ntoa(l_node_link->hdr.ext_addr_v4), + l_node_link->hdr.links_number); + } + dap_cli_server_cmd_set_reply_text(a_str_reply, "Balancer link list:\n %s \n", + l_string_balanc->str); + } + break; } return 0; } @@ -2894,7 +2915,7 @@ void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a l_datum->header.data_size, dap_ctime_r(&l_ts_create, buf)); if (!a_fast) - dap_chain_datum_dump(a_str_tmp, l_datum, a_hash_out_type); + dap_chain_datum_dump(a_str_tmp, l_datum, a_hash_out_type, a_net->pub.id); } if(a_add) dap_string_append_printf(a_str_tmp, l_objs_addr @@ -3099,7 +3120,7 @@ int com_mempool_check(int a_argc, char **a_argv, char ** a_str_reply) dap_string_append_printf(l_str_reply, "Atom hash is %s return code is %d (%s)\n", l_atom_hash_str, l_ret_code, dap_chain_ledger_tx_check_err_str(l_ret_code)); } - dap_chain_datum_dump(l_str_reply, l_datum, l_hash_out_type); + dap_chain_datum_dump(l_str_reply, l_datum, l_hash_out_type, l_net->pub.id); if (!l_found_in_chains) DAP_DELETE(l_datum); *a_str_reply = l_str_reply->str; @@ -5732,7 +5753,7 @@ int com_tx_history(int a_argc, char ** a_argv, char **a_str_reply) dap_string_append_printf(l_tx_all_str, "\t\t↓↓↓ Ledger rejected ↓↓↓\n"); l_tx_ledger_rejected++; } - dap_chain_datum_dump_tx(l_tx, l_token_ticker, l_tx_all_str, l_hash_out_type, &l_ttx_hash); + dap_chain_datum_dump_tx(l_tx, l_token_ticker, l_tx_all_str, l_hash_out_type, &l_ttx_hash, l_net->pub.id); } } DAP_DEL_Z(l_datums); diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c index ff303a5638b84c033b51b9fb6492b033f9529b08..db58e64ee0867d74341dad443673cf7d19ee2efb 100644 --- a/modules/net/dap_chain_node_cli_cmd_tx.c +++ b/modules/net/dap_chain_node_cli_cmd_tx.c @@ -104,7 +104,7 @@ static bool s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, : NULL; if (!l_ticker) return false; - dap_chain_datum_dump_tx(a_datum, l_ticker, a_str_out, a_hash_out_type, a_tx_hash); + dap_chain_datum_dump_tx(a_datum, l_ticker, a_str_out, a_hash_out_type, a_tx_hash, a_ledger->net_id); dap_list_t *l_out_items = dap_chain_datum_tx_items_get(a_datum, TX_ITEM_TYPE_OUT_ALL, NULL); int l_out_idx = 0; dap_string_append_printf(a_str_out, "Spenders:\r\n"); @@ -160,11 +160,12 @@ char* dap_db_history_tx(dap_chain_hash_fast_t* a_tx_hash, dap_chain_t * a_chain, char *l_atom_hash_str = dap_strcmp(a_hash_out_type, "hex") ? dap_enc_base58_encode_hash_to_str(&l_atom_hash) : dap_chain_hash_fast_to_str_new(&l_atom_hash); - const char *l_tx_token_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(a_chain->ledger, a_tx_hash); + dap_ledger_t *l_ledger = dap_chain_net_by_id(a_chain->net_id)->pub.ledger; + const char *l_tx_token_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, a_tx_hash); dap_string_append_printf(l_str_out, "%s TX with atom %s (ret_code %d)\n", l_tx_token_ticker ? "ACCEPTED" : "DECLINED", l_atom_hash_str, l_ret_code); DAP_DELETE(l_atom_hash_str); - dap_chain_datum_dump_tx(l_tx, l_tx_token_ticker, l_str_out, a_hash_out_type, a_tx_hash); + dap_chain_datum_dump_tx(l_tx, l_tx_token_ticker, l_str_out, a_hash_out_type, a_tx_hash, a_chain->net_id); } else { char *l_tx_hash_str = dap_strcmp(a_hash_out_type, "hex") ? dap_enc_base58_encode_hash_to_str(a_tx_hash) @@ -466,7 +467,7 @@ static char* dap_db_chain_history_token_list(dap_chain_t * a_chain, const char * continue; if (a_token_name && dap_strcmp(((dap_chain_datum_token_t *)l_datum->data)->ticker, a_token_name)) continue; - dap_chain_datum_dump(l_str_out, l_datum, a_hash_out_type); + dap_chain_datum_dump(l_str_out, l_datum, a_hash_out_type, a_chain->net_id); (*a_token_num)++; } DAP_DELETE(l_datums); @@ -566,7 +567,7 @@ static char* dap_db_history_filter(dap_chain_t * a_chain, dap_ledger_t *a_ledger break; } if(!a_filter_token_name || !dap_strcmp(l_token->ticker, a_filter_token_name)) { - dap_chain_datum_dump(l_str_out, l_datum, a_hash_out_type); + dap_chain_datum_dump(l_str_out, l_datum, a_hash_out_type, a_chain->net_id); dap_string_append(l_str_out, "\n"); l_token_num++; } @@ -586,7 +587,7 @@ static char* dap_db_history_filter(dap_chain_t * a_chain, dap_ledger_t *a_ledger if (a_filtr_addr_base58 && dap_strcmp(a_filtr_addr_base58, l_token_emission_address_str)) { break; } - dap_chain_datum_dump(l_str_out, l_datum, a_hash_out_type); + dap_chain_datum_dump(l_str_out, l_datum, a_hash_out_type, a_chain->net_id); dap_string_append(l_str_out, "\n"); l_emission_num++; } @@ -944,9 +945,9 @@ int com_token(int a_argc, char ** a_argv, char **a_str_reply) const char * l_hash_out_type = NULL; dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-H", &l_hash_out_type); - if(!l_hash_out_type) - l_hash_out_type = "base58"; - if(dap_strcmp(l_hash_out_type,"hex") && dap_strcmp(l_hash_out_type,"base58")) { + if (!l_hash_out_type) + l_hash_out_type = "hex"; + if (dap_strcmp(l_hash_out_type,"hex") && dap_strcmp(l_hash_out_type,"base58")) { dap_cli_server_cmd_set_reply_text(a_str_reply, "invalid parameter -H, valid values: -H <hex | base58>"); return -1; } diff --git a/modules/net/dap_chain_node_dns_client.c b/modules/net/dap_chain_node_dns_client.c index fab8ea735b5106511d8e64c478684a489d0482c2..04898ac3b8df78b1405cde68ab3d3bf5ac05d411 100644 --- a/modules/net/dap_chain_node_dns_client.c +++ b/modules/net/dap_chain_node_dns_client.c @@ -85,7 +85,8 @@ static void s_dns_client_esocket_read_callback(dap_events_socket_t * a_esocket, } l_cur = l_buf + l_addr_point; - dap_chain_net_node_balancer_t l_link_full_node_list = {}; + dap_chain_net_node_balancer_t *l_link_full_node_list = DAP_NEW_Z_SIZE(dap_chain_net_node_balancer_t, + sizeof(dap_chain_net_node_balancer_t) + sizeof(dap_chain_node_info_t)); dap_chain_node_info_t l_result = {}; l_result.hdr.ext_addr_v4.s_addr = ntohl(*(uint32_t *)l_cur); l_cur = l_buf + 5 * sizeof(uint16_t); @@ -96,13 +97,14 @@ static void s_dns_client_esocket_read_callback(dap_events_socket_t * a_esocket, l_cur += sizeof(uint16_t); l_result.hdr.address.uint64 = be64toh(*(uint64_t *)l_cur); } - *(dap_chain_node_info_t*)l_link_full_node_list.nodes_info = l_result; - l_link_full_node_list.count_node = 1; + *(dap_chain_node_info_t*)l_link_full_node_list->nodes_info = l_result; + l_link_full_node_list->count_node = 1; - l_dns_client->callback_success(a_esocket->context->worker ,&l_link_full_node_list, l_dns_client->callbacks_arg); + l_dns_client->callback_success(a_esocket->context->worker, l_link_full_node_list, l_dns_client->callbacks_arg); l_dns_client->is_callbacks_called = true; a_esocket->flags |= DAP_SOCK_SIGNAL_CLOSE; a_esocket->buf_in_size = a_esocket->buf_out_size = 0; + DAP_DELETE(l_link_full_node_list); } /** diff --git a/modules/net/include/dap_chain_net.h b/modules/net/include/dap_chain_net.h index 7b99fc79b57a1424d578d031ba65fbfb541efd4c..ffd4ea5ff1782ba248747c1aa3e02002b418d319 100644 --- a/modules/net/include/dap_chain_net.h +++ b/modules/net/include/dap_chain_net.h @@ -89,6 +89,8 @@ typedef struct dap_chain_net{ dap_ledger_t *ledger; dap_chain_net_decree_t *decree; + pthread_mutex_t balancer_mutex; + dap_list_t *link_list; dap_list_t *bridged_networks; // List of bridged network ID's allowed to cross-network TXs } pub; uint8_t pvt[]; @@ -173,6 +175,7 @@ dap_chain_node_role_t dap_chain_net_get_role(dap_chain_net_t * a_net); dap_chain_node_info_t *dap_get_balancer_link_from_cfg(dap_chain_net_t *a_net); + /** * @brief dap_chain_net_get_gdb_group_mempool * @param l_chain diff --git a/modules/net/include/dap_chain_net_balancer.h b/modules/net/include/dap_chain_net_balancer.h index 637ba8da659ec2973ce0257069299429a3133aba..a2a4f9770666f492e743122383425de4873c7d2f 100644 --- a/modules/net/include/dap_chain_net_balancer.h +++ b/modules/net/include/dap_chain_net_balancer.h @@ -34,4 +34,8 @@ typedef struct dap_chain_net_node_balancer { void dap_chain_net_balancer_http_issue_link(dap_http_simple_t *a_http_simple, void *a_arg); dap_chain_node_info_t *dap_chain_net_balancer_dns_issue_link(char *a_str); +void dap_chain_net_balancer_prepare_list_links(const char *a_net_name,bool handshake_on); dap_chain_net_node_balancer_t *dap_chain_net_balancer_get_node(const char *a_net_name,uint16_t a_links_need); +void dap_chain_net_balancer_set_link_ban(dap_chain_node_info_t *a_node_info, const char *a_net_name); +void dap_chain_net_balancer_free_link_ban(dap_chain_net_t * a_net); + diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c index 435769de77e086195459437632bca83b12f3c489..91cf58856548a4eea47f44898a73db8e92e0d55f 100644 --- a/modules/type/blocks/dap_chain_cs_blocks.c +++ b/modules/type/blocks/dap_chain_cs_blocks.c @@ -595,7 +595,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply) ctime_r(&l_datum_ts_create, buf); dap_string_append_printf(l_str_tmp,"\t\t\t\tts_create=%s\n", buf); dap_string_append_printf(l_str_tmp,"\t\t\t\tdata_size=%u\n", l_datum->header.data_size); - dap_chain_datum_dump(l_str_tmp, l_datum, "hex"); + dap_chain_datum_dump(l_str_tmp, l_datum, "hex", l_net->pub.id); } // Signatures dap_string_append_printf(l_str_tmp,"\t\tsignatures:\tcount: %zu\n",l_block_cache->sign_count ); diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c index 04af3944ca26ce43816fee9cf32b470e67164689..222e9295555555883b61e0ddf652506e331c0a05 100644 --- a/modules/type/dag/dap_chain_cs_dag.c +++ b/modules/type/dag/dap_chain_cs_dag.c @@ -482,6 +482,12 @@ static bool s_dap_chain_check_if_event_is_present(dap_chain_cs_dag_event_item_t return (l_event_search != NULL); } +static int s_sort_event_item(dap_chain_cs_dag_event_item_t* a, dap_chain_cs_dag_event_item_t* b) +{ + return a->event->header.ts_created == b->event->header.ts_created ? 0 : + a->event->header.ts_created < b->event->header.ts_created ? -1 : 1; +} + /** * @brief s_chain_callback_atom_add Accept new event in dag * @param a_chain DAG object @@ -524,7 +530,7 @@ static dap_chain_atom_verify_res_t s_chain_callback_atom_add(dap_chain_t * a_cha switch (ret) { case ATOM_ACCEPT: ret = s_chain_callback_atom_verify(a_chain, a_atom, a_atom_size); - if (ret == ATOM_MOVE_TO_THRESHOLD) + if (ret == ATOM_MOVE_TO_THRESHOLD && !dap_chain_net_get_load_mode(dap_chain_net_by_id(a_chain->net_id))) ret = ATOM_REJECT; /* TODO: A temporary fix for memory consumption */ if(s_debug_more) log_it(L_DEBUG, "Verified atom %p: %s", a_atom, ret == ATOM_ACCEPT ? "accepted" : @@ -583,7 +589,17 @@ static dap_chain_atom_verify_res_t s_chain_callback_atom_add(dap_chain_t * a_cha break; } pthread_mutex_lock(l_events_mutex); - HASH_ADD(hh, PVT(l_dag)->events,hash, sizeof(l_event_item->hash), l_event_item); + dap_chain_cs_dag_event_item_t *l_tail = PVT(l_dag)->events ? PVT(l_dag)->events->hh.tbl->tail->prev : NULL; + if (!l_tail) + l_tail = PVT(l_dag)->events; + else + l_tail = l_tail->hh.next; + if (l_tail && l_tail->event->header.ts_created > l_event->header.ts_created) + DAP_CHAIN_PVT(a_chain)->need_reorder = true; + if (DAP_CHAIN_PVT(a_chain)->need_reorder) + HASH_ADD_INORDER(hh, PVT(l_dag)->events, hash, sizeof(l_event_item->hash), l_event_item, s_sort_event_item); + else + HASH_ADD(hh, PVT(l_dag)->events, hash, sizeof(l_event_item->hash), l_event_item); s_dag_events_lasts_process_new_last_event(l_dag, l_event_item); pthread_mutex_unlock(l_events_mutex); } break; @@ -1889,7 +1905,7 @@ static int s_cli_dag(int argc, char ** argv, char **a_str_reply) l_offset += l_sign_size; DAP_DELETE( l_hash_str); } - dap_chain_datum_dump(l_str_tmp, l_datum, l_hash_out_type); + dap_chain_datum_dump(l_str_tmp, l_datum, l_hash_out_type, l_net->pub.id); dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_str_tmp->str); dap_string_free(l_str_tmp, true);