From 72bb7ffb4c9f210bc080d83eecd465ab29c076d1 Mon Sep 17 00:00:00 2001 From: Dmitriy Gerasimov <naeper@demlabs.net> Date: Tue, 21 May 2019 19:38:21 +0700 Subject: [PATCH] [*] No-chain GlobalDB chain object --- dap_chain_gdb.c | 234 +++++++++++++++++++++++++++++++----------------- dap_chain_gdb.h | 1 + 2 files changed, 153 insertions(+), 82 deletions(-) diff --git a/dap_chain_gdb.c b/dap_chain_gdb.c index 4a5e112..66913e6 100644 --- a/dap_chain_gdb.c +++ b/dap_chain_gdb.c @@ -26,33 +26,44 @@ #include <stdbool.h> #include <pthread.h> +#include "utlist.h" + #include "dap_common.h" #include "dap_strfuncs.h" #include "dap_config.h" +#include "dap_hash.h" #include "dap_chain_ledger.h" #include "dap_chain_global_db.h" +#include "dap_chain_global_db_pvt.h" #include "dap_chain_net.h" #include "dap_chain_cs.h" #include "dap_chain_gdb.h" #define LOG_TAG "dap_chain_gdb" -#define CONSENSUS_NAME "nochains-gdb" +#define CONSENSUS_NAME "gdb" + +typedef struct dap_chain_gdb_datum_hash_item{ + char key[70]; + dap_chain_hash_fast_t datum_data_hash; + uint8_t padding[2]; + struct dap_chain_gdb_datum_hash_item * prev; + struct dap_chain_gdb_datum_hash_item * next; +} dap_chain_gdb_datum_hash_item_t; typedef struct dap_chain_gdb_private { bool celled; - char *group_tx; - char *group_ledger; + bool is_load_mode; // If load mode - not save when new atom adds + uint8_t padding[7]; + char *group_datums; dap_chain_t *chain; - dap_ledger_t *ledger; - pthread_rwlock_t events_rwlock; + dap_chain_gdb_datum_hash_item_t * hash_items; } dap_chain_gdb_private_t; -#define GDB_INTERNAL(a) ( (dap_chain_gdb_private_t* ) (a) ? a->_internal : NULL ) -#define DAP_CHAIN_GDB(a) ( (dap_chain_gdb_t *) (a)->_inheritor) +#define PVT(a) ( (dap_chain_gdb_private_t* ) (a)->_internal ) static int dap_chain_gdb_ledger_load(dap_chain_gdb_t *a_gdb, dap_chain_net_t *a_net); @@ -88,23 +99,10 @@ static size_t s_chain_callback_datums_pool_proc(dap_chain_t * a_chain, dap_chain */ static int s_cs_callback_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg) { - dap_chain_gdb_new(a_chain, a_chain_cfg); - return 0; + return dap_chain_gdb_new(a_chain, a_chain_cfg); } -/** - * Get cell group by dap_chain_t - */ -static char* get_cell_group(dap_chain_t * a_chain) -{ - char *l_group = NULL; - if(!a_chain) - return NULL; - dap_chain_net_t *l_net = dap_chain_net_by_id(a_chain->net_id); - if(l_net) - l_group = dap_strdup_printf("cell.0x%016X.", l_net->pub.cell_id.uint64); - return l_group; -} + /** * @brief dap_chain_cs_gdb_init * @return @@ -112,17 +110,35 @@ static char* get_cell_group(dap_chain_t * a_chain) int dap_chain_gdb_init(void) { dap_chain_cs_add(CONSENSUS_NAME, s_cs_callback_new); - dap_chain_class_add("gdb", dap_chain_gdb_new); + dap_chain_class_add(CONSENSUS_NAME, dap_chain_gdb_new); log_it(L_NOTICE, "Initialized GDB chain items organization class"); return 0; } -static void db_obj_callback_notify(const char a_op_code, const char * a_prefix, const char * a_group, - const char * a_key, const void * a_value, const size_t a_value_len) +/** + * @brief s_history_callback_notify + * @param a_arg + * @param a_op_code + * @param a_prefix + * @param a_group + * @param a_key + * @param a_value + * @param a_value_len + */ +static void s_history_callback_notify(void * a_arg, const char a_op_code, const char * a_prefix, const char * a_group, + const char * a_key, const void * a_value, const size_t a_value_size) { - return; + (void) a_value; + (void) a_prefix; + if (a_arg){ + dap_chain_gdb_t * l_gdb = (dap_chain_gdb_t *) a_arg; + dap_chain_net_t *l_net = dap_chain_net_by_id( l_gdb->chain->net_id); + log_it(L_DEBUG,"%s.%s: op_code='%c' group=\"%s\" key=\"%s\" value_size=%u",l_net->pub.name, + l_gdb->chain->name, a_op_code, a_group, a_key, a_value_size); + } } + /** * @brief dap_chain_gdb_new * @param a_chain @@ -136,29 +152,29 @@ int dap_chain_gdb_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg) l_gdb->_internal = (void*) l_gdb_priv; a_chain->_inheritor = l_gdb; - pthread_rwlock_init(&l_gdb_priv->events_rwlock, NULL); - l_gdb_priv->celled = dap_config_get_item_bool(a_chain_cfg, CONSENSUS_NAME, "celled"); - //l_gdb_priv->group_tx = dap_strdup(dap_config_get_item_str(a_chain_cfg, CONSENSUS_NAME, "group_tx")); - //l_gdb_priv->group_ledger = dap_strdup(dap_config_get_item_str(a_chain_cfg, CONSENSUS_NAME, "group_ledger")); + l_gdb_priv->celled = dap_config_get_item_bool_default(a_chain_cfg, CONSENSUS_NAME, "celled",false); dap_chain_net_t *l_net = dap_chain_net_by_id(a_chain->net_id); - l_gdb_priv->ledger = (l_net) ? l_net->pub.ledger : NULL; l_gdb_priv->chain = a_chain; - if(!l_gdb_priv->celled) - l_gdb_priv->group_tx = dap_strdup("global."); - else { + if(!l_gdb_priv->celled){ + l_gdb_priv->group_datums = dap_strdup_printf( "chain-gdb.%s.chain-%016llX",l_net->pub.name, + a_chain->id.uint64); + }else { // here is not work because dap_chain_net_load() not yet fully performed - l_gdb_priv->group_tx = get_cell_group(a_chain); + l_gdb_priv->group_datums = dap_strdup_printf( "chain-gdb.%s.chain-%016llX.cell-%016llX",l_net->pub.name, + a_chain->id.uint64, l_net->pub.cell_id.uint64); } + // Add group prefix that will be tracking all changes - dap_chain_global_db_add_history_group_prefix(l_gdb_priv->group_tx); - dap_chain_global_db_add_history_group_prefix("global"); + dap_chain_global_db_add_history_group_prefix("chain-gdb"); + + dap_chain_global_db_add_history_callback_notify("chain-gdb", s_history_callback_notify,l_gdb); - dap_chain_global_db_add_history_callback_notify(l_gdb_priv->group_tx, db_obj_callback_notify); - dap_chain_global_db_add_history_callback_notify("global", db_obj_callback_notify); // load ledger - int l_res = dap_chain_gdb_ledger_load(l_gdb, l_net); + l_gdb_priv->is_load_mode = true; + dap_chain_gdb_ledger_load(l_gdb, l_net); + l_gdb_priv->is_load_mode = false; a_chain->callback_delete = dap_chain_gdb_delete; @@ -193,16 +209,20 @@ int dap_chain_gdb_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg) void dap_chain_gdb_delete(dap_chain_t * a_chain) { dap_chain_gdb_t * l_gdb = DAP_CHAIN_GDB(a_chain); - dap_chain_gdb_private_t *l_gdb_priv = GDB_INTERNAL(l_gdb); + dap_chain_gdb_private_t *l_gdb_priv = PVT(l_gdb); - pthread_rwlock_destroy(&l_gdb_priv->events_rwlock); - DAP_DELETE(l_gdb_priv->group_tx); - DAP_DELETE(l_gdb_priv->group_ledger); + DAP_DELETE(l_gdb_priv->group_datums); DAP_DELETE(l_gdb); a_chain->_inheritor = NULL; } +/** + * @brief compare_datum_items + * @param l_a + * @param l_b + * @return + */ static int compare_datum_items(const void * l_a, const void * l_b) { const dap_chain_datum_t *l_item_a = (const dap_chain_datum_t*) l_a; @@ -221,31 +241,17 @@ static int compare_datum_items(const void * l_a, const void * l_b) */ static int dap_chain_gdb_ledger_load(dap_chain_gdb_t *a_gdb, dap_chain_net_t *a_net) { - dap_chain_gdb_private_t *l_gdb_priv = GDB_INTERNAL(a_gdb); + dap_chain_gdb_private_t *l_gdb_priv = PVT(a_gdb); dap_list_t *l_datum_list = NULL, *l_list_tmp = NULL; // protect from reloading - if(dap_chain_ledger_count(l_gdb_priv->ledger) > 0) + if(dap_chain_ledger_count( a_net->pub.ledger ) > 0) return 0; - // Read first transaction mempool group name - //dap_chain_net_t *l_net = dap_chain_net_by_name(a_net_name); - //dap_chain_t * l_chain_base_tx = (a_net) ? dap_chain_net_get_chain_by_name(a_net, a_chain_name) : NULL; - char * l_gdb_group_mempool_base_tx = - (l_gdb_priv->chain) ? dap_chain_net_get_gdb_group_mempool(l_gdb_priv->chain) : NULL; - - // Read first transaction in mempool_groups from a_mempool_group_names_list size_t l_data_size = 0; - dap_global_db_obj_t **data_ft = NULL; - if(l_gdb_group_mempool_base_tx) { - data_ft = dap_chain_global_db_gr_load(l_gdb_group_mempool_base_tx, &l_data_size); - // make list of datums - for(size_t i = 0; i < l_data_size; i++) { - l_datum_list = dap_list_prepend(l_datum_list, data_ft[i]->value); - } - } + // Read the entire database into an array of size bytes - dap_global_db_obj_t **data = dap_chain_global_db_gr_load(l_gdb_priv->group_ledger, &l_data_size); + dap_global_db_obj_t **data = dap_chain_global_db_gr_load(l_gdb_priv->group_datums , &l_data_size); // make list of datums for(size_t i = 0; i < l_data_size; i++) { l_datum_list = dap_list_prepend(l_datum_list, data[i]->value); @@ -256,11 +262,7 @@ static int dap_chain_gdb_ledger_load(dap_chain_gdb_t *a_gdb, dap_chain_net_t *a_ // add datum_tx from list to ledger while(l_list_tmp) { dap_chain_datum_t *l_datum = (dap_chain_datum_t*) l_list_tmp->data; - if(l_datum->header.type_id == DAP_CHAIN_DATUM_TX) { - dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*) l_datum->data; - if(dap_chain_datum_tx_get_size(l_tx) == l_datum->header.data_size) - dap_chain_ledger_tx_add(l_gdb_priv->ledger, l_tx); - } + s_chain_callback_atom_add(a_gdb->chain,l_datum); l_list_tmp = dap_list_next(l_list_tmp); } dap_chain_global_db_objs_delete(data); @@ -277,12 +279,9 @@ static int dap_chain_gdb_ledger_load(dap_chain_gdb_t *a_gdb, dap_chain_net_t *a_ static size_t s_chain_callback_datums_pool_proc(dap_chain_t * a_chain, dap_chain_datum_t ** a_datums, size_t a_datums_count) { - dap_chain_gdb_t * l_gdb = DAP_CHAIN_GDB(a_chain); - dap_chain_gdb_private_t *l_gdb_priv = GDB_INTERNAL(l_gdb); for(size_t i = 0; i < a_datums_count; i++) { - dap_chain_datum_t *l_datum_tx = a_datums[i]; - if(l_datum_tx->header.type_id == DAP_CHAIN_DATUM_TX) - dap_chain_ledger_tx_add(l_gdb_priv->ledger, (dap_chain_datum_tx_t*) l_datum_tx->data); + dap_chain_datum_t * l_datum = a_datums[i]; + s_chain_callback_atom_add(a_chain, l_datum ); } return 0; } @@ -295,7 +294,36 @@ static size_t s_chain_callback_datums_pool_proc(dap_chain_t * a_chain, dap_chain */ static int s_chain_callback_atom_add(dap_chain_t * a_chain, dap_chain_atom_ptr_t a_atom) { + dap_chain_gdb_t * l_gdb = DAP_CHAIN_GDB(a_chain); + dap_chain_gdb_private_t *l_gdb_priv = PVT(l_gdb); dap_chain_datum_t *l_datum = (dap_chain_datum_t*) a_atom; + switch (l_datum->header.type_id) { + case DAP_CHAIN_DATUM_TOKEN_DECL:{ + dap_chain_datum_token_t *l_token = (dap_chain_datum_token_t*) l_datum->data; + dap_chain_ledger_token_add(a_chain->ledger,l_token, l_datum->header.data_size); + }break; + case DAP_CHAIN_DATUM_TOKEN_EMISSION: { + dap_chain_datum_token_emission_t *l_token_emission = (dap_chain_datum_token_emission_t*) l_datum->data; + dap_chain_ledger_token_emission_add(a_chain->ledger, l_token_emission, l_datum->header.data_size); + }break; + case DAP_CHAIN_DATUM_TX:{ + dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*) l_datum->data; + if(dap_chain_datum_tx_get_size(l_tx) == l_datum->header.data_size){ + dap_chain_ledger_tx_add(a_chain->ledger, l_tx); + }else + return -2; + }break; + default: return -1; + } + + dap_chain_gdb_datum_hash_item_t * l_hash_item = DAP_NEW_Z(dap_chain_gdb_datum_hash_item_t); + size_t l_datum_size = dap_chain_datum_size(l_datum); + dap_hash_fast(l_datum->data,l_datum->header.data_size,&l_hash_item->datum_data_hash ); + dap_chain_hash_fast_to_str(&l_hash_item->datum_data_hash,l_hash_item->key,sizeof(l_hash_item->key)-1); + if ( !l_gdb_priv->is_load_mode ) + dap_chain_global_db_gr_set(l_hash_item->key, l_datum, l_datum_size, l_gdb_priv->group_datums); + + DL_APPEND(l_gdb_priv->hash_items, l_hash_item); return 0; } @@ -307,6 +335,8 @@ static int s_chain_callback_atom_add(dap_chain_t * a_chain, dap_chain_atom_ptr_t */ static int s_chain_callback_atom_verify(dap_chain_t * a_chain, dap_chain_atom_ptr_t a_atom) { + (void) a_chain; + (void) a_atom; return 0; } @@ -316,8 +346,8 @@ static int s_chain_callback_atom_verify(dap_chain_t * a_chain, dap_chain_atom_pt * @return */ static size_t s_chain_callback_atom_hdr_get_size(dap_chain_atom_ptr_t a_atom) -{ - return 0; +{ + return ((dap_chain_datum_t *) a_atom)->header.data_size +sizeof (((dap_chain_datum_t *) a_atom)->header); } /** @@ -327,7 +357,8 @@ static size_t s_chain_callback_atom_hdr_get_size(dap_chain_atom_ptr_t a_atom) */ static size_t s_chain_callback_atom_get_static_hdr_size() { - return 0; + static dap_chain_datum_t *l_datum_null=NULL; + return sizeof(l_datum_null->header); } /** @@ -337,7 +368,9 @@ static size_t s_chain_callback_atom_get_static_hdr_size() */ static dap_chain_atom_iter_t* s_chain_callback_atom_iter_create(dap_chain_t * a_chain) { - return 0; + dap_chain_atom_iter_t * l_iter = DAP_NEW_Z(dap_chain_atom_iter_t); + l_iter->chain = a_chain; + return l_iter; } /** @@ -349,7 +382,10 @@ static dap_chain_atom_iter_t* s_chain_callback_atom_iter_create(dap_chain_t * a_ static dap_chain_atom_iter_t* s_chain_callback_atom_iter_create_from(dap_chain_t * a_chain, dap_chain_atom_ptr_t a_atom) { - return 0; + dap_chain_atom_iter_t * l_iter = DAP_NEW_Z(dap_chain_atom_iter_t); + l_iter->chain = a_chain; + l_iter->cur = a_atom; + return l_iter; } /** @@ -363,6 +399,7 @@ static void s_chain_callback_atom_iter_delete(dap_chain_atom_iter_t * a_atom_ite /** * @brief s_chain_callback_atom_iter_find_by_hash + * @details Searchs by datum data hash, not for datum's hash itself * @param a_atom_iter * @param a_atom_hash * @return @@ -370,7 +407,13 @@ static void s_chain_callback_atom_iter_delete(dap_chain_atom_iter_t * a_atom_ite static dap_chain_atom_ptr_t s_chain_callback_atom_iter_find_by_hash(dap_chain_atom_iter_t * a_atom_iter, dap_chain_hash_fast_t * a_atom_hash) { - return 0; + char * l_key = dap_chain_hash_fast_to_str_new(a_atom_hash); + size_t l_ret_size; + dap_chain_atom_ptr_t l_ret; + dap_chain_gdb_t * l_gdb = DAP_CHAIN_GDB(a_atom_iter->chain ); + l_ret = dap_chain_global_db_gr_get(l_key,&l_ret_size, + PVT ( l_gdb )->group_datums ); + return l_ret; } /** @@ -380,8 +423,19 @@ static dap_chain_atom_ptr_t s_chain_callback_atom_iter_find_by_hash(dap_chain_at */ static dap_chain_atom_ptr_t s_chain_callback_atom_iter_get_first(dap_chain_atom_iter_t * a_atom_iter) { - return 0; + dap_chain_datum_t * l_datum = NULL; + a_atom_iter->cur_item = PVT ( DAP_CHAIN_GDB(a_atom_iter->chain) )->hash_items; + if (a_atom_iter->cur_item ){ + dap_chain_gdb_datum_hash_item_t * l_item = PVT ( DAP_CHAIN_GDB(a_atom_iter->chain) )->hash_items; + size_t l_datum_size =0; + l_datum= (dap_chain_datum_t*) dap_chain_global_db_gr_get(l_item->key,&l_datum_size,PVT(DAP_CHAIN_GDB(a_atom_iter->chain))->group_datums ); + if (a_atom_iter->cur) // This iterator should clean up data for it because its allocate it + DAP_DELETE( a_atom_iter->cur); + a_atom_iter->cur = l_datum; + } + return l_datum; } + /** * @brief s_chain_callback_atom_iter_get_next Get the next dag event * @param a_atom_iter @@ -389,7 +443,19 @@ static dap_chain_atom_ptr_t s_chain_callback_atom_iter_get_first(dap_chain_atom_ */ static dap_chain_atom_ptr_t s_chain_callback_atom_iter_get_next(dap_chain_atom_iter_t * a_atom_iter) { - return 0; + dap_chain_datum_t * l_datum = NULL; + a_atom_iter->cur_item = a_atom_iter->cur_item? + ((dap_chain_gdb_datum_hash_item_t*) a_atom_iter->cur_item)->next : NULL; + if (a_atom_iter->cur_item ){ + size_t l_datum_size =0; + l_datum= (dap_chain_datum_t*) dap_chain_global_db_gr_get( + ((dap_chain_gdb_datum_hash_item_t*) a_atom_iter->cur_item)->key, + &l_datum_size, PVT(DAP_CHAIN_GDB(a_atom_iter->chain))->group_datums ); + if (a_atom_iter->cur) // This iterator should clean up data for it because its allocate it + DAP_DELETE( a_atom_iter->cur); + a_atom_iter->cur = l_datum; + } + return l_datum; } /** @@ -401,7 +467,9 @@ static dap_chain_atom_ptr_t s_chain_callback_atom_iter_get_next(dap_chain_atom_i static dap_chain_atom_ptr_t* s_chain_callback_atom_iter_get_links(dap_chain_atom_iter_t * a_atom_iter, size_t * a_links_size_ptr) { - return 0; + (void) a_atom_iter; + (void) a_links_size_ptr; + return NULL; } /** @@ -413,6 +481,8 @@ static dap_chain_atom_ptr_t* s_chain_callback_atom_iter_get_links(dap_chain_atom static dap_chain_atom_ptr_t* s_chain_callback_atom_iter_get_lasts(dap_chain_atom_iter_t * a_atom_iter, size_t * a_lasts_size_ptr) { - return 0; + (void) a_atom_iter; + (void) a_lasts_size_ptr; + return NULL; } diff --git a/dap_chain_gdb.h b/dap_chain_gdb.h index caffb2d..fdab44a 100644 --- a/dap_chain_gdb.h +++ b/dap_chain_gdb.h @@ -33,6 +33,7 @@ typedef struct dap_chain_gdb { void * _inheritor; // inheritor object } dap_chain_gdb_t; +#define DAP_CHAIN_GDB(a) ( (dap_chain_gdb_t *) (a)->_inheritor) int dap_chain_gdb_init(void); int dap_chain_gdb_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg); -- GitLab