diff --git a/dap_chain.c b/dap_chain.c index dfd585c0cdfe2cba3ca1122d6aae4d5bcaefe235..56a43f8fde8808720ec85cfe987e76d453206d32 100755 --- a/dap_chain.c +++ b/dap_chain.c @@ -165,6 +165,8 @@ void dap_chain_delete(dap_chain_t * a_chain) }else log_it(L_WARNING,"Trying to remove non-existent 0x%16llX:0x%16llX chain",a_chain->id.uint64, a_chain->net_id.uint64); + a_chain->datum_types_count = 0; + DAP_DELETE (a_chain->datum_types); pthread_rwlock_unlock(&s_chain_items_rwlock); } @@ -239,6 +241,15 @@ dap_chain_t * dap_chain_load_from_cfg(dap_ledger_t* a_ledger, const char * a_cha return NULL; } + // Read chain datum types + char** l_datum_types = NULL; + uint16_t l_datum_types_count = 0; + if((l_datum_types = dap_config_get_array_str(l_cfg, "chain", "datum_types", &l_datum_types_count)) == NULL) { + log_it(L_WARNING, "Can't read chain datum types ", l_chain_id_str); + //dap_config_close(l_cfg); + //return NULL; + } + l_chain = dap_chain_create(a_ledger,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%016llX", @@ -248,6 +259,7 @@ dap_chain_t * dap_chain_load_from_cfg(dap_ledger_t* a_ledger, const char * a_cha DAP_CHAIN_PVT ( l_chain)->file_storage_dir = strdup ( dap_config_get_item_str( l_cfg , "files","storage_dir" ) ) ; if ( dap_chain_load_all( l_chain ) != 0 ){ + dap_chain_save_all( l_chain ); log_it (L_NOTICE, "Loaded chain files"); }else { dap_chain_save_all( l_chain ); @@ -264,6 +276,26 @@ dap_chain_t * dap_chain_load_from_cfg(dap_ledger_t* a_ledger, const char * a_cha dap_chain_delete(l_chain); l_chain = NULL; } + // add datum types + if(l_chain && l_datum_types_count > 0) { + l_chain->datum_types = DAP_NEW_SIZE(dap_chain_type_t, l_datum_types_count * sizeof(dap_chain_type_t)); + uint16_t l_count_recognized = 0; + for(uint16_t i = 0; i < l_datum_types_count; i++) { + if(!dap_strcmp(l_datum_types[i], "token")) { + l_chain->datum_types[l_count_recognized] = CHAIN_TYPE_TOKEN; + l_count_recognized++; + } + else if(!dap_strcmp(l_datum_types[i], "emission")) { + l_chain->datum_types[l_count_recognized] = CHAIN_TYPE_EMISSION; + l_count_recognized++; + } + else if(!dap_strcmp(l_datum_types[i], "transaction")) { + l_chain->datum_types[l_count_recognized] = CHAIN_TYPE_TX; + l_count_recognized++; + } + } + l_chain->datum_types_count = l_count_recognized; + } dap_config_close(l_cfg); return l_chain; @@ -312,11 +344,13 @@ int dap_chain_save_all (dap_chain_t * l_chain) */ int dap_chain_load_all (dap_chain_t * l_chain) { - int ret = -2; + int l_ret = -2; + if(!l_chain) + return l_ret; DIR * l_dir = opendir(DAP_CHAIN_PVT(l_chain)->file_storage_dir); if( l_dir ) { struct dirent * l_dir_entry; - ret = -1; + l_ret = -1; while((l_dir_entry=readdir(l_dir))!=NULL){ const char * l_filename = l_dir_entry->d_name; size_t l_filename_len = strlen (l_filename); @@ -327,15 +361,13 @@ int dap_chain_load_all (dap_chain_t * l_chain) size_t l_suffix_len = strlen(l_suffix); if (strncmp(l_filename+ l_filename_len-l_suffix_len,l_suffix,l_suffix_len) == 0 ){ if ( dap_chain_cell_load(l_chain,l_filename) == 0 ) - ret = 0; + l_ret = 0; } } - } closedir(l_dir); - } - return ret; + return l_ret; } /** diff --git a/dap_chain.h b/dap_chain.h index 91a0d90b2f3dcb52cfde6e28835587d15fb60920..04e81474e3919acad29b475a3274ceeec833e1f1 100755 --- a/dap_chain.h +++ b/dap_chain.h @@ -64,6 +64,7 @@ typedef size_t (*dap_chain_callback_atom_hdr_get_size_t)(dap_chain_atom_ptr_t ); typedef dap_chain_atom_iter_t* (*dap_chain_callback_atom_iter_create_t)(dap_chain_t * ); typedef dap_chain_atom_iter_t* (*dap_chain_callback_atom_iter_create_from_t)(dap_chain_t * ,dap_chain_atom_ptr_t); typedef dap_chain_atom_ptr_t (*dap_chain_callback_atom_iter_get_first_t)(dap_chain_atom_iter_t * ); +typedef dap_chain_datum_t* (*dap_chain_callback_atom_get_datum)(dap_chain_atom_ptr_t ); typedef dap_chain_atom_ptr_t (*dap_chain_callback_atom_iter_find_by_hash_t)(dap_chain_atom_iter_t * ,dap_chain_hash_fast_t *); typedef dap_chain_atom_ptr_t * (*dap_chain_callback_atom_iter_get_atoms_t)(dap_chain_atom_iter_t * ,size_t * ); @@ -75,6 +76,14 @@ typedef size_t (*dap_chain_datum_callback_datum_pool_proc_add_t)(dap_chain_t * , typedef size_t (*dap_chain_datum_callback_datum_pool_proc_add_with_group_t)(dap_chain_t * , dap_chain_datum_t **, size_t, const char *); +typedef enum dap_chain_type +{ + CHAIN_TYPE_FIRST, + CHAIN_TYPE_TOKEN, + CHAIN_TYPE_EMISSION, + CHAIN_TYPE_TX, + CHAIN_TYPE_LAST +} dap_chain_type_t; typedef struct dap_chain{ dap_chain_id_t id; @@ -87,6 +96,9 @@ typedef struct dap_chain{ // Nested cells (hashtab by cell_id dap_chain_cell_t * cells; + uint16_t datum_types_count; + dap_chain_type_t *datum_types; + // To hold it in double-linked lists struct dap_chain * next; struct dap_chain * prev; @@ -107,6 +119,8 @@ typedef struct dap_chain{ dap_chain_callback_atom_iter_create_t callback_atom_iter_create; dap_chain_callback_atom_iter_create_from_t callback_atom_iter_create_from; dap_chain_callback_atom_iter_get_first_t callback_atom_iter_get_first; + dap_chain_callback_atom_get_datum callback_atom_get_datum; + dap_chain_callback_atom_iter_find_by_hash_t callback_atom_find_by_hash; dap_chain_callback_atom_iter_get_next_t callback_atom_iter_get_next; dap_chain_callback_atom_iter_get_atoms_t callback_atom_iter_get_links; diff --git a/dap_chain_cell.c b/dap_chain_cell.c index 025e45a7481d2a95f69ccf31a3414545d5984e57..12f2cf3072999b130df9aee45f3fac2aaf36057a 100755 --- a/dap_chain_cell.c +++ b/dap_chain_cell.c @@ -29,6 +29,7 @@ #include "dap_chain.h" #include "dap_chain_cell.h" #include "dap_chain_cs.h" +#include "dap_chain_pvt.h" #define LOG_TAG "dap_chain_cell" @@ -53,7 +54,7 @@ typedef struct dap_chain_cell_file_header } DAP_ALIGN_PACKED dap_chain_cell_file_header_t; -static const char* s_cells_path = NULL; +//static const char* s_cells_path = NULL; /** * @brief dap_chain_cell_init @@ -61,7 +62,7 @@ static const char* s_cells_path = NULL; */ int dap_chain_cell_init(void) { - s_cells_path = dap_config_get_item_str(g_config,"resources","cells_storage"); + //s_cells_path = dap_config_get_item_str(g_config,"resources","cells_storage"); return 0; } @@ -75,6 +76,20 @@ dap_chain_cell_t * dap_chain_cell_create() return l_cell; } +/** + * @brief dap_chain_cell_delete + * @return + */ +void dap_chain_cell_delete(dap_chain_cell_t *a_cell) +{ + if(!a_cell) + return; + if(a_cell->file_storage) + fclose(a_cell->file_storage); + DAP_DELETE(a_cell->file_storage_path); + DAP_DELETE(a_cell); +} + /** * @brief dap_chain_cell_load * @param a_chain @@ -87,8 +102,11 @@ int dap_chain_cell_load(dap_chain_t * a_chain, const char * a_cell_file_path) l_cell->file_storage_path = dap_strdup( a_cell_file_path ); - l_cell->file_storage = fopen(l_cell->file_storage_path,"a+b"); + char *l_file_path = dap_strdup_printf("%s/%s", DAP_CHAIN_PVT (a_chain)->file_storage_dir, + l_cell->file_storage_path); + l_cell->file_storage = fopen(l_file_path,"rb"); + DAP_DELETE(l_file_path); if ( l_cell->file_storage ){ dap_chain_cell_file_header_t l_hdr = {0}; if ( fread( &l_hdr,1,sizeof(l_hdr),l_cell->file_storage ) == sizeof (l_hdr) ) { @@ -100,7 +118,7 @@ int dap_chain_cell_load(dap_chain_t * a_chain, const char * a_cell_file_path) if ( l_element_size > 0 ){ dap_chain_atom_ptr_t * l_element = DAP_NEW_Z_SIZE (dap_chain_atom_ptr_t, l_element_size ); if ( fread( l_element,1,l_element_size,l_cell->file_storage ) == l_element_size ) { - l_cell->chain->callback_atom_add (a_chain, l_element ); + a_chain->callback_atom_add (a_chain, l_element ); } } else { log_it (L_ERROR, "Zero element size, file is corrupted"); @@ -108,20 +126,25 @@ int dap_chain_cell_load(dap_chain_t * a_chain, const char * a_cell_file_path) } } } + dap_chain_cell_delete(l_cell); return 0; } else { log_it (L_ERROR,"Wrong signature in file \"%s\", possible file corrupt",l_cell->file_storage_path); + dap_chain_cell_delete(l_cell); return -3; } } else { log_it (L_ERROR,"Can't read dap_chain file header \"%s\"",l_cell->file_storage_path); + dap_chain_cell_delete(l_cell); return -2; } }else { log_it (L_WARNING,"Can't read dap_chain file \"%s\"",l_cell->file_storage_path); + dap_chain_cell_delete(l_cell); return -1; } - + dap_chain_cell_delete(l_cell); + return -4; } /** @@ -136,7 +159,7 @@ int dap_chain_cell_file_append( dap_chain_cell_t * a_cell, const void* a_atom, s size_t l_total_wrote_bytes = 0; if ( fwrite(&a_atom_size,1,sizeof(a_atom_size),a_cell->file_storage) == sizeof(a_atom_size) ){ l_total_wrote_bytes += sizeof (a_atom_size); - if ( fwrite(&a_atom,1,a_atom_size,a_cell->file_storage) == a_atom_size ){ + if ( fwrite(a_atom,1,a_atom_size,a_cell->file_storage) == a_atom_size ){ l_total_wrote_bytes += a_atom_size; } else { log_it (L_ERROR, "Can't write data from cell 0x%016X to the file \"%s\"", @@ -160,9 +183,17 @@ int dap_chain_cell_file_append( dap_chain_cell_t * a_cell, const void* a_atom, s */ int dap_chain_cell_file_update( dap_chain_cell_t * a_cell) { + if(!a_cell->chain){ + log_it(L_WARNING,"chain not defined for cell for cell 0x%016X ( %s )", + a_cell->id.uint64,a_cell->file_storage_path); + return -1; + } if(a_cell->file_storage == NULL ){ // File need to be created - a_cell->file_storage = fopen(a_cell->file_storage_path,"wb"); - if ( a_cell->file_storage ){ + char *l_file_path = dap_strdup_printf("%s/%s", DAP_CHAIN_PVT ( a_cell->chain)->file_storage_dir, + a_cell->file_storage_path); + a_cell->file_storage = fopen(l_file_path, "wb"); + DAP_DELETE(l_file_path); + if(a_cell->file_storage) { dap_chain_cell_file_header_t l_hdr = { .signature = DAP_CHAIN_CELL_FILE_SIGNATURE, .version = DAP_CHAIN_CELL_FILE_VERSION, diff --git a/dap_chain_cell.h b/dap_chain_cell.h index eb425343f66bc4291df88055fea21a9d4eb50b61..83bba2941348da89bdcdbfcc610a464774afa925 100755 --- a/dap_chain_cell.h +++ b/dap_chain_cell.h @@ -72,6 +72,8 @@ typedef struct dap_chain_cell_decl{ int dap_chain_cell_init(void); +dap_chain_cell_t * dap_chain_cell_create(); +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_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/dap_chain_common.c b/dap_chain_common.c index 3bb1f23ef1f45976d6f8b376762d21fc9150d641..44310f3239db9d0bcad759d511c8feb61382413f 100755 --- a/dap_chain_common.c +++ b/dap_chain_common.c @@ -177,7 +177,7 @@ void dap_chain_addr_fill(dap_chain_addr_t *a_addr, dap_enc_key_t *a_key, dap_cha if(dap_hash_fast(l_pub_key_data, l_pub_key_data_size, &l_hash_public_key)==1) memcpy(a_addr->data.hash, l_hash_public_key.raw, sizeof(l_hash_public_key.raw)); - + DAP_DELETE(l_pub_key_data); // calc checksum dap_hash_fast(a_addr, sizeof(dap_chain_addr_t) - sizeof(dap_chain_hash_fast_t), &a_addr->checksum); } diff --git a/dap_chain_ledger.c b/dap_chain_ledger.c index f09feef70abc208a5b36740693170e1c2db6bfa0..f42025960b83d9664d1ed7a9fe08921df9a44e65 100755 --- a/dap_chain_ledger.c +++ b/dap_chain_ledger.c @@ -591,7 +591,6 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t // go to next previous transaction l_list_tmp = dap_list_next(l_list_tmp); - continue; } else { log_it(L_INFO,"Previous transaction was found for hash %s",l_tx_prev_hash_str);