diff --git a/modules/chain/dap_chain.c b/modules/chain/dap_chain.c index 1e2856b2993c8d1b28fd6b3c0edce3bdab59c372..20dcd078c9c8428a3b67827093ad41b603bf0075 100644 --- a/modules/chain/dap_chain.c +++ b/modules/chain/dap_chain.c @@ -312,11 +312,46 @@ static uint16_t s_chain_type_convert(dap_chain_type_t a_type) return DAP_CHAIN_DATUM_TX; case CHAIN_TYPE_CA: return DAP_CHAIN_DATUM_CA; + case CHAIN_TYPE_SIGNER: + return DAP_CHAIN_DATUM_SIGNER; + default: return DAP_CHAIN_DATUM_CUSTOM; } } +/** + * @brief s_chain_in_chain_types + * looks for a type (chain_type) in an array of types (*chain_types) + * @param chain_type - the type we are looking for + * @param *chain_types - array of types in which we are looking for + * @param chain_types_count - number of elements in the array *chain_types + * @return true or false + */ +static bool s_chain_in_chain_types(dap_chain_type_t chain_type, dap_chain_type_t *chain_types, uint16_t chain_types_count) +{ + for (uint16_t i = 0; i < chain_types_count; i++) + if (chain_types[i] == chain_type) + return (true); + return (false); +} + +/** + * @brief s_datum_in_chain_types + * looks for a type (chain_type) in an array of types (*chain_types) + * @param datum_type - the type we are looking for + * @param *chain_types - array of types in which we are looking for + * @param chain_types_count - number of elements in the array *chain_types + * @return true or false + */ +static bool s_datum_in_chain_types(uint16_t datum_type, dap_chain_type_t *chain_types, uint16_t chain_types_count) +{ + for (uint16_t i = 0; i < chain_types_count; i++) + if (s_chain_type_convert(chain_types[i]) == datum_type) + return (true); + return (false); +} + /** * @brief dap_chain_load_from_cfg * Loading chain from config file @@ -329,20 +364,27 @@ static uint16_t s_chain_type_convert(dap_chain_type_t a_type) dap_chain_t * dap_chain_load_from_cfg(dap_ledger_t* a_ledger, const char * a_chain_net_name,dap_chain_net_id_t a_chain_net_id, const char * a_chain_cfg_name) { log_it (L_DEBUG, "Loading chain from config \"%s\"", a_chain_cfg_name); - if ( a_chain_net_name){ - dap_config_t * l_cfg = dap_config_open(a_chain_cfg_name); - if (l_cfg) { - dap_chain_t * l_chain = NULL; - dap_chain_id_t l_chain_id = {{0}}; - uint64_t l_chain_id_u = 0; - const char * l_chain_id_str = NULL; - const char * l_chain_name = NULL; + + if (a_chain_net_name) + { + dap_config_t *l_cfg = dap_config_open(a_chain_cfg_name); + if (l_cfg) + { + dap_chain_t *l_chain = NULL; + dap_chain_id_t l_chain_id = {{0}}; + uint64_t l_chain_id_u = 0; + const char *l_chain_id_str = NULL; + const char *l_chain_name = NULL; // Recognize chains id - if ( (l_chain_id_str = dap_config_get_item_str(l_cfg,"chain","id")) != NULL ){ - if ( dap_sscanf(l_chain_id_str,"0x%"DAP_UINT64_FORMAT_X,& l_chain_id_u ) !=1 ){ - if ( dap_sscanf(l_chain_id_str,"0x%"DAP_UINT64_FORMAT_x,&l_chain_id_u) !=1 ) { - if ( dap_sscanf(l_chain_id_str,"%"DAP_UINT64_FORMAT_U,&l_chain_id_u ) !=1 ){ + if ( (l_chain_id_str = dap_config_get_item_str(l_cfg,"chain","id")) != NULL ) + { + if (dap_sscanf(l_chain_id_str, "0x%"DAP_UINT64_FORMAT_X, & l_chain_id_u) !=1) + { + if (dap_sscanf(l_chain_id_str, "0x%"DAP_UINT64_FORMAT_x, &l_chain_id_u) !=1) + { + if (dap_sscanf(l_chain_id_str, "%"DAP_UINT64_FORMAT_U, &l_chain_id_u) !=1) + { log_it (L_ERROR,"Can't recognize '%s' string as chain net id, hex or dec",l_chain_id_str); dap_config_close(l_cfg); return NULL; @@ -352,93 +394,145 @@ dap_chain_t * dap_chain_load_from_cfg(dap_ledger_t* a_ledger, const char * a_cha } l_chain_id.uint64 = l_chain_id_u; - if (l_chain_id_str ) { - log_it (L_NOTICE, "Chain id 0x%016"DAP_UINT64_FORMAT_x" ( \"%s\" )",l_chain_id.uint64 , l_chain_id_str) ; - }else { - log_it (L_ERROR,"Wasn't recognized '%s' string as chain net id, hex or dec",l_chain_id_str); + if (l_chain_id_str) + log_it (L_NOTICE, "Chain id 0x%016"DAP_UINT64_FORMAT_x" ( \"%s\" )", l_chain_id.uint64, l_chain_id_str); + else { + log_it (L_ERROR,"Wasn't recognized '%s' string as chain net id, hex or dec", l_chain_id_str); dap_config_close(l_cfg); return NULL; } + // Read chain name - if ( ( l_chain_name = dap_config_get_item_str(l_cfg,"chain","name") ) == NULL ){ - log_it (L_ERROR,"Can't read chain net name %s",l_chain_id_str); + if ( ( l_chain_name = dap_config_get_item_str(l_cfg,"chain","name") ) == NULL ) + { + log_it (L_ERROR,"Can't read chain net name %s", 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%016"DAP_UINT64_FORMAT_x, - l_chain_id.uint64 ); - - if ( dap_config_get_item_str_default(l_cfg , "files","storage_dir",NULL ) ) { - 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) { + 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); + + if ( dap_config_get_item_str_default(l_cfg , "files","storage_dir",NULL ) ) + { + DAP_CHAIN_PVT(l_chain)->file_storage_dir = dap_strdup( dap_config_get_item_str( l_cfg , "files","storage_dir" ) ); + if (dap_chain_load_all(l_chain) == 0) log_it (L_NOTICE, "Loaded chain files"); - } else { + else { dap_chain_save_all( l_chain ); log_it (L_NOTICE, "Initialized chain files"); } - } else{ + } else log_it (L_INFO, "Not set file storage path, will not stored in files"); - } - if (!l_chain->cells) { + + if (!l_chain->cells) + { dap_chain_cell_id_t l_cell_id = {.uint64 = 0}; dap_chain_cell_create_fill(l_chain, l_cell_id); } - }else{ + } else { log_it (L_ERROR, "Can't init consensus \"%s\"",dap_config_get_item_str_default( l_cfg , "chain","consensus","NULL")); dap_chain_delete(l_chain); l_chain = 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 for chain %s", l_chain_id_str); - //dap_config_close(l_cfg); - //return NULL; - } - // add datum types - if(l_chain && l_datum_types && 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++) { - dap_chain_type_t l_chain_type = s_chain_type_from_str(l_datum_types[i]); - if (l_chain_type != CHAIN_TYPE_LAST) { - l_chain->datum_types[l_count_recognized] = l_chain_type; - l_count_recognized++; - } - } - l_chain->datum_types_count = l_count_recognized; - } - if((l_datum_types = dap_config_get_array_str(l_cfg, "chain", "mempool_auto_types", &l_datum_types_count)) == NULL) { - log_it(L_WARNING, "Can't read chain mempool auto types for chain %s", l_chain_id_str); - } - // add datum types - if(l_chain && l_datum_types && l_datum_types_count) { - l_chain->autoproc_datum_types = DAP_NEW_Z_SIZE(uint16_t, l_chain->datum_types_count * sizeof(uint16_t)); - uint16_t l_count_recognized = 0; - for(uint16_t i = 0; i < l_datum_types_count; i++) { - if (!strcmp(l_datum_types[i], "all") && l_chain->datum_types_count) { - for (int j = 0; j < l_chain->datum_types_count; j++) - l_chain->autoproc_datum_types[j] = s_chain_type_convert(l_chain->datum_types[j]); - l_count_recognized = l_chain->datum_types_count; - break; - } - uint16_t l_chain_type = s_datum_type_from_str(l_datum_types[i]); - if (l_chain_type != DAP_CHAIN_DATUM_CUSTOM) { - l_chain->autoproc_datum_types[l_count_recognized] = l_chain_type; - l_count_recognized++; - } - } - l_chain->autoproc_datum_types_count = l_count_recognized; - } + + if (l_chain) + { + // load priority for chain + l_chain->load_priority = dap_config_get_item_uint16_default(l_cfg, "chain", "load_priority", 100); + + char** l_datum_types = NULL; + char** l_default_datum_types = NULL; + uint16_t l_datum_types_count = 0; + uint16_t l_default_datum_types_count = 0; + uint16_t l_count_recognized = 0; + + // l_datum_types = (read chain datum types) + // || l_default_datum_types = (read chain default datum types if datum types readed and if present default datum types) + + if ( (l_datum_types = dap_config_get_array_str(l_cfg, "chain", "datum_types", &l_datum_types_count)) == NULL + || (l_default_datum_types = dap_config_get_array_str(l_cfg, "chain", "default_datum_types", &l_default_datum_types_count)) == NULL ) + { + if (!l_datum_types) + log_it(L_WARNING, "Can't read chain datum types for chain %s", l_chain_id_str); + else + log_it(L_WARNING, "Can't read chain DEFAULT datum types for chain %s", l_chain_id_str); + //dap_config_close(l_cfg); + //return NULL; + } + + // add datum types + if (l_datum_types && 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)); // TODO: pls check counter for recognized types before memory allocation! + l_count_recognized = 0; + for (uint16_t i = 0; i < l_datum_types_count; i++) + { + dap_chain_type_t l_chain_type = s_chain_type_from_str(l_datum_types[i]); + if (l_chain_type != CHAIN_TYPE_LAST) + { + l_chain->datum_types[l_count_recognized] = l_chain_type; + l_count_recognized++; + } + } + l_chain->datum_types_count = l_count_recognized; + } else + l_chain->datum_types_count = 0; + + // add default datum types present + if (l_default_datum_types && l_default_datum_types_count > 0) + { + l_chain->default_datum_types = DAP_NEW_SIZE(dap_chain_type_t, l_default_datum_types_count * sizeof(dap_chain_type_t)); // TODO: pls check counter for recognized types before memory allocation! + l_count_recognized = 0; + for (uint16_t i = 0; i < l_default_datum_types_count; i++) + { + dap_chain_type_t l_chain_type = s_chain_type_from_str(l_default_datum_types[i]); + if (l_chain_type != CHAIN_TYPE_LAST + && s_chain_in_chain_types(l_chain_type, l_chain->datum_types, l_chain->datum_types_count))// <<--- check this chain_type in readed datum_types + { + l_chain->default_datum_types[l_count_recognized] = l_chain_type; + l_count_recognized++; + } + } + l_chain->default_datum_types_count = l_count_recognized; + } else + l_chain->default_datum_types_count = 0; + + if ((l_datum_types = dap_config_get_array_str(l_cfg, "chain", "mempool_auto_types", &l_datum_types_count)) == NULL) + log_it(L_WARNING, "Can't read chain mempool auto types for chain %s", l_chain_id_str); + + // add datum types for autoproc + if (l_datum_types && l_datum_types_count) + { + l_chain->autoproc_datum_types = DAP_NEW_Z_SIZE(uint16_t, l_chain->datum_types_count * sizeof(uint16_t)); // TODO: pls check counter for recognized types before memory allocation! + l_count_recognized = 0; + for (uint16_t i = 0; i < l_datum_types_count; i++) + { + if (!dap_strcmp(l_datum_types[i], "all") && l_chain->datum_types_count) + { + for (int j = 0; j < l_chain->datum_types_count; j++) + l_chain->autoproc_datum_types[j] = s_chain_type_convert(l_chain->datum_types[j]); + l_count_recognized = l_chain->datum_types_count; + break; + } + uint16_t l_chain_type = s_datum_type_from_str(l_datum_types[i]); + if (l_chain_type != DAP_CHAIN_DATUM_CUSTOM + && s_datum_in_chain_types(l_chain_type, l_chain->datum_types, l_chain->datum_types_count))// <<--- check this chain_datum_type in readed datum_types + { + l_chain->autoproc_datum_types[l_count_recognized] = l_chain_type; + l_count_recognized++; + } + } + l_chain->autoproc_datum_types_count = l_count_recognized; + } else + l_chain->autoproc_datum_types_count = 0; + } dap_config_close(l_cfg); return l_chain; - }else + } else return NULL; } else { diff --git a/modules/chain/include/dap_chain.h b/modules/chain/include/dap_chain.h index e852f5a59904afbf2f859d4b3c009df20b6c7eb1..9405bb5bbf96696fbbee2423ca2adf9b2d0a0f93 100644 --- a/modules/chain/include/dap_chain.h +++ b/modules/chain/include/dap_chain.h @@ -112,6 +112,7 @@ typedef struct dap_chain{ dap_chain_id_t id; dap_chain_net_id_t net_id; + uint16_t load_priority; char * name; char * net_name; dap_ledger_t * ledger; // If present - pointer to associated ledger @@ -122,6 +123,8 @@ typedef struct dap_chain{ uint16_t datum_types_count; dap_chain_type_t *datum_types; + uint16_t default_datum_types_count; + dap_chain_type_t *default_datum_types; uint16_t autoproc_datum_types_count; uint16_t *autoproc_datum_types; diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c index 0f163d709e8c33e00caa157ae3c43a8f208a7063..e20ee3230610790dd6e99bc222fbc73931ad7146 100644 --- a/modules/net/dap_chain_net.c +++ b/modules/net/dap_chain_net.c @@ -1756,6 +1756,31 @@ bool s_chain_net_reload_ledger_cache_once(dap_chain_net_t *l_net) return true; } +/** + * @brief s_chain_type_convert + * convert dap_chain_type_t to DAP_CNAIN* constants + * @param a_type - dap_chain_type_t a_type [CHAIN_TYPE_TOKEN, CHAIN_TYPE_EMISSION, CHAIN_TYPE_TX] + * @return uint16_t + */ +static const char *s_chain_type_convert_to_string(dap_chain_type_t a_type) +{ + switch (a_type) { + case CHAIN_TYPE_TOKEN: + return ("token"); + case CHAIN_TYPE_EMISSION: + return ("emission"); + case CHAIN_TYPE_TX: + return ("transaction"); + case CHAIN_TYPE_CA: + return ("ca"); + case CHAIN_TYPE_SIGNER: + return ("signer"); + + default: + return ("custom"); + } +} + /** * @brief * register net* command in cellframe-node-cli interface @@ -1811,6 +1836,13 @@ static int s_cli_net(int argc, char **argv, char **a_str_reply) dap_chain_t * l_chain = l_net->pub.chains; while (l_chain) { dap_string_append_printf(l_string_ret, "\t\t%s:\n", l_chain->name ); + if (l_chain->default_datum_types_count) + { + dap_string_append_printf(l_string_ret, "\t\t"); + for (uint16_t i = 0; i < l_chain->default_datum_types_count; i++) + dap_string_append_printf(l_string_ret, "| %s ", s_chain_type_convert_to_string(l_chain->default_datum_types[i]) ); + dap_string_append_printf(l_string_ret, "|\n"); + } l_chain = l_chain->next; } } @@ -2149,6 +2181,33 @@ static int s_cli_net(int argc, char **argv, char **a_str_reply) return ret; } +/** + * @brief remove_duplicates_in_chain_by_priority + * remove duplicates default datum types in chain by priority + * @param *l_chain_1 chain 1 + * @param *l_chain_2 chain 2 + * @return void + */ + +static void remove_duplicates_in_chain_by_priority(dap_chain_t *l_chain_1, dap_chain_t *l_chain_2) +{ + dap_chain_t *l_chain_high_priority = (l_chain_1->load_priority > l_chain_2->load_priority) ? l_chain_2 : l_chain_1; //such distribution is made for correct operation with the same priority + dap_chain_t *l_chain_low_priority = (l_chain_1->load_priority > l_chain_2->load_priority) ? l_chain_1 : l_chain_2; //...^...^...^... + + for (int i = 0; i < l_chain_high_priority->default_datum_types_count; i++) + { + for (int j = 0; j < l_chain_low_priority->default_datum_types_count; j++) + { + if (l_chain_high_priority->default_datum_types[i] == l_chain_low_priority->default_datum_types[j]) + { + l_chain_low_priority->default_datum_types[j] = l_chain_low_priority->default_datum_types[l_chain_low_priority->default_datum_types_count - 1]; + --l_chain_low_priority->default_datum_types_count; + --j; + } + } + } +} + // for sequential loading chains typedef struct list_priority_{ uint16_t prior; @@ -2632,6 +2691,7 @@ int s_net_load(const char * a_net_name, uint16_t a_acl_idx) log_it(L_ERROR, "Please, fix your configs and restart node"); return -2; } + remove_duplicates_in_chain_by_priority(l_chain, l_chain02); } } }