From d75a523ab289a4290760e323489ea1a9e9da5eb0 Mon Sep 17 00:00:00 2001 From: "Dmitriy A. Gerasimov" <dmitriy.gerasimov@demlabs.net> Date: Sat, 17 Oct 2020 02:00:21 +0700 Subject: [PATCH] [*] Changed callback_atom_get_datum chain callback to callback_atom_get_datums to let to return more then one datum from a chain atom [+] More blockchain callback realized --- modules/chain/include/dap_chain.h | 4 +- modules/net/dap_chain_node_cli_cmd_tx.c | 590 +++++++++--------- modules/type/blocks/dap_chain_block.c | 129 ++++ modules/type/blocks/dap_chain_block_cache.c | 13 +- modules/type/blocks/dap_chain_cs_blocks.c | 131 +++- modules/type/blocks/include/dap_chain_block.h | 17 + .../blocks/include/dap_chain_block_cache.h | 2 +- modules/type/dag/dap_chain_cs_dag.c | 22 +- 8 files changed, 579 insertions(+), 329 deletions(-) diff --git a/modules/chain/include/dap_chain.h b/modules/chain/include/dap_chain.h index baad228c86..8cb420e0b5 100644 --- a/modules/chain/include/dap_chain.h +++ b/modules/chain/include/dap_chain.h @@ -71,7 +71,7 @@ typedef size_t (*dap_chain_callback_atom_get_hdr_size_t)(void); 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, size_t); typedef dap_chain_atom_ptr_t (*dap_chain_callback_atom_iter_get_first_t)(dap_chain_atom_iter_t * , size_t*); -typedef dap_chain_datum_t* (*dap_chain_callback_atom_get_datum)(dap_chain_atom_ptr_t, size_t ); +typedef dap_chain_datum_t** (*dap_chain_callback_atom_get_datum_t)(dap_chain_atom_ptr_t, size_t, size_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 *,size_t*); typedef dap_chain_datum_tx_t* (*dap_chain_callback_tx_find_by_hash_t)(dap_chain_t * ,dap_chain_hash_fast_t *); @@ -132,7 +132,7 @@ 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_get_datum_t callback_atom_get_datums; dap_chain_callback_atom_iter_find_by_hash_t callback_atom_find_by_hash; dap_chain_callback_tx_find_by_hash_t callback_tx_find_by_hash; diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c index 7838fc1920..67cc3f8066 100644 --- a/modules/net/dap_chain_node_cli_cmd_tx.c +++ b/modules/net/dap_chain_node_cli_cmd_tx.c @@ -316,168 +316,129 @@ char* dap_db_history_addr(dap_chain_addr_t * a_addr, dap_chain_t * a_chain, cons } while(l_atom && l_atom_size) { - dap_chain_datum_t *l_datum = a_chain->callback_atom_get_datum ? a_chain->callback_atom_get_datum(l_atom, l_atom_size) : - (dap_chain_datum_t*)l_atom; - if(!l_datum || l_datum->header.type_id != DAP_CHAIN_DATUM_TX) { - // go to next transaction - l_atom = a_chain->callback_atom_iter_get_next(l_atom_iter, &l_atom_size); - continue; + size_t l_datums_count =0; + dap_chain_datum_t **l_datums = a_chain->callback_atom_get_datums ? a_chain->callback_atom_get_datums(l_atom, l_atom_size, &l_datums_count) : + NULL; + if (! l_datums){ + log_it(L_WARNING,"Not defined callback_atom_get_datums for chain \"%s\"", a_chain->name); + break; } - // transaction - dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*) l_datum->data; - dap_list_t *l_records_out = NULL; - // transaction time - char *l_time_str = NULL; - { - if(l_tx->header.ts_created > 0) { - time_t rawtime = (time_t) l_tx->header.ts_created; - struct tm * timeinfo; - timeinfo = localtime(&rawtime); - if(timeinfo) - l_time_str = dap_strdup(asctime(timeinfo)); - } - else - l_time_str = dap_strdup(" "); - } - - // find Token items - present in emit transaction - dap_list_t *l_list_tx_token = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_TOKEN, NULL); - // list of dap_tx_data_t*; info about OUT item in current transaction - dap_list_t *l_list_out_info = NULL; - - // find OUT items - dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT, NULL); - dap_list_t *l_list_out_items_tmp = l_list_out_items; - while(l_list_out_items_tmp) { - const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t*) l_list_out_items_tmp->data; - // save OUT item l_tx_out + for (size_t d=0; d< l_datums_count; d++){ + dap_chain_datum_t *l_datum = l_datums && l_datums_count ? l_datums[d] :NULL; + if(!l_datum || l_datum->header.type_id != DAP_CHAIN_DATUM_TX) { + // go to next transaction + l_atom = a_chain->callback_atom_iter_get_next(l_atom_iter, &l_atom_size); + continue; + } + // transaction + dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*) l_datum->data; + dap_list_t *l_records_out = NULL; + // transaction time + char *l_time_str = NULL; { - // save tx hash - // info about OUT item in current transaction - dap_tx_data_t *l_tx_data = DAP_NEW_Z(dap_tx_data_t); - dap_chain_hash_fast_t l_tx_hash; - dap_hash_fast(l_tx, dap_chain_datum_tx_get_size(l_tx), &l_tx_hash); - memcpy(&l_tx_data->tx_hash, &l_tx_hash, sizeof(dap_chain_hash_fast_t)); - memcpy(&l_tx_data->addr, &l_tx_out->addr, sizeof(dap_chain_addr_t)); - dap_chain_hash_fast_to_str(&l_tx_data->tx_hash, l_tx_data->tx_hash_str, sizeof(l_tx_data->tx_hash_str)); - l_tx_data->datum = DAP_NEW_SIZE(dap_chain_datum_t, l_atom_size); - memcpy(l_tx_data->datum, l_datum, l_atom_size); - // save token name - if(l_tx_data && l_list_tx_token) { - dap_chain_tx_token_t *tk = l_list_tx_token->data; - memcpy(l_tx_data->token_ticker, tk->header.ticker, sizeof(l_tx_data->token_ticker)); + if(l_tx->header.ts_created > 0) { + time_t rawtime = (time_t) l_tx->header.ts_created; + struct tm * timeinfo; + timeinfo = localtime(&rawtime); + if(timeinfo) + l_time_str = dap_strdup(asctime(timeinfo)); } - HASH_ADD(hh, l_tx_data_hash, tx_hash, sizeof(dap_chain_hash_fast_t), l_tx_data); - - // save OUT items to list - l_records_out = dap_list_append(l_records_out, (void*) l_tx_out); - // save info about OUT items to list - l_list_out_info = dap_list_append(l_list_out_info, (void*) l_tx_data); + else + l_time_str = dap_strdup(" "); } - l_list_out_items_tmp = dap_list_next(l_list_out_items_tmp); - } - - // find IN items - dap_list_t *l_list_in_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_IN, NULL); - dap_list_t *l_list_in_items_tmp = l_list_in_items; - // find cur addr in prev OUT items - //bool l_is_use_all_cur_out = false; - { - while(l_list_in_items_tmp) { - const dap_chain_tx_in_t *l_tx_in = (const dap_chain_tx_in_t*) l_list_in_items_tmp->data; - dap_chain_hash_fast_t tx_prev_hash = l_tx_in->header.tx_prev_hash; - - //find prev OUT item - dap_tx_data_t *l_tx_data_prev = NULL; - HASH_FIND(hh, l_tx_data_hash, &tx_prev_hash, sizeof(dap_chain_hash_fast_t), l_tx_data_prev); - if(l_tx_data_prev != NULL) { - // fill token in all l_tx_data from prev transaction - - dap_list_t *l_list_out_info_tmp = l_list_out_info; - while(l_list_out_info_tmp) { - dap_tx_data_t *l_tx_data = (dap_tx_data_t*) l_list_out_info_tmp->data; - if(l_tx_data) { - // get token from prev tx - memcpy(l_tx_data->token_ticker, l_tx_data_prev->token_ticker, - sizeof(l_tx_data->token_ticker)); - dap_chain_datum_t *l_datum_prev = get_prev_tx(l_tx_data_prev); - dap_chain_datum_tx_t *l_tx_prev = - l_datum_prev ? (dap_chain_datum_tx_t*) l_datum_prev->data : NULL; - - // find OUT items in prev datum - dap_list_t *l_list_out_prev_items = dap_chain_datum_tx_items_get(l_tx_prev, - TX_ITEM_TYPE_OUT, NULL); - // find OUT item for IN item; - dap_list_t *l_list_out_prev_item = dap_list_nth(l_list_out_prev_items, - l_tx_in->header.tx_out_prev_idx); - dap_chain_tx_out_t *l_tx_prev_out = - l_list_out_prev_item ? - (dap_chain_tx_out_t*) l_list_out_prev_item->data : - NULL; - if(l_tx_prev_out && !memcmp(&l_tx_prev_out->addr, a_addr, sizeof(dap_chain_addr_t))) - l_tx_data->is_use_all_cur_out = true; - } - l_list_out_info_tmp = dap_list_next(l_list_out_info_tmp); + // find Token items - present in emit transaction + dap_list_t *l_list_tx_token = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_TOKEN, NULL); + + // list of dap_tx_data_t*; info about OUT item in current transaction + dap_list_t *l_list_out_info = NULL; + + // find OUT items + dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT, NULL); + dap_list_t *l_list_out_items_tmp = l_list_out_items; + while(l_list_out_items_tmp) { + const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t*) l_list_out_items_tmp->data; + // save OUT item l_tx_out + { + // save tx hash + // info about OUT item in current transaction + dap_tx_data_t *l_tx_data = DAP_NEW_Z(dap_tx_data_t); + dap_chain_hash_fast_t l_tx_hash; + dap_hash_fast(l_tx, dap_chain_datum_tx_get_size(l_tx), &l_tx_hash); + memcpy(&l_tx_data->tx_hash, &l_tx_hash, sizeof(dap_chain_hash_fast_t)); + memcpy(&l_tx_data->addr, &l_tx_out->addr, sizeof(dap_chain_addr_t)); + dap_chain_hash_fast_to_str(&l_tx_data->tx_hash, l_tx_data->tx_hash_str, sizeof(l_tx_data->tx_hash_str)); + l_tx_data->datum = DAP_NEW_SIZE(dap_chain_datum_t, l_atom_size); + memcpy(l_tx_data->datum, l_datum, l_atom_size); + // save token name + if(l_tx_data && l_list_tx_token) { + dap_chain_tx_token_t *tk = l_list_tx_token->data; + memcpy(l_tx_data->token_ticker, tk->header.ticker, sizeof(l_tx_data->token_ticker)); } + HASH_ADD(hh, l_tx_data_hash, tx_hash, sizeof(dap_chain_hash_fast_t), l_tx_data); + + // save OUT items to list + l_records_out = dap_list_append(l_records_out, (void*) l_tx_out); + // save info about OUT items to list + l_list_out_info = dap_list_append(l_list_out_info, (void*) l_tx_data); } - l_list_in_items_tmp = dap_list_next(l_list_in_items_tmp); + l_list_out_items_tmp = dap_list_next(l_list_out_items_tmp); } - // find prev OUT items for IN items - dap_list_t *l_list_in_items2_tmp = l_list_in_items; // go to begin of list - while(l_list_in_items2_tmp) { - const dap_chain_tx_in_t *l_tx_in = (const dap_chain_tx_in_t*) l_list_in_items2_tmp->data; - dap_chain_hash_fast_t tx_prev_hash = l_tx_in->header.tx_prev_hash; - // if first transaction - empty prev OUT item - if(dap_hash_fast_is_blank(&tx_prev_hash)) { - - dap_tx_data_t *l_tx_data = NULL; - dap_list_t *l_list_out_info_tmp = l_list_out_info; - while(l_list_out_info_tmp) { - l_tx_data = (dap_tx_data_t*) l_list_out_info_tmp->data; - if(l_tx_data->token_ticker[0]) - break; - l_list_out_info_tmp = dap_list_next(l_list_out_info_tmp); - } - // add emit info to ret string - if(l_tx_data && !memcmp(&l_tx_data->addr, a_addr, sizeof(dap_chain_addr_t))) { - dap_list_t *l_records_tmp = l_records_out; - while(l_records_tmp) { - char *tx_hash_str; - if(!dap_strcmp(a_hash_out_type,"hex")) - tx_hash_str = dap_strdup( l_tx_data->tx_hash_str); - else - tx_hash_str = dap_enc_base58_from_hex_str_to_str( l_tx_data->tx_hash_str); - const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t*) l_records_tmp->data; - - if(!dap_strcmp(a_hash_out_type,"hex")){ - dap_string_append_printf(l_str_out, "tx hash %s \n emit %lu %s\n", - tx_hash_str,//l_tx_data->tx_hash_str, - l_tx_out->header.value, - l_tx_data->token_ticker); - } - else { - dap_string_append_printf(l_str_out, "tx hash %s \n emit %lu %s\n", - l_tx_data->tx_hash_str, - l_tx_out->header.value, - l_tx_data->token_ticker); - } - DAP_DELETE(tx_hash_str); - l_records_tmp = dap_list_next(l_records_tmp); - } - } - //dap_list_free(l_records_out); - } - // in other transactions except first one - else { + // find IN items + dap_list_t *l_list_in_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_IN, NULL); + dap_list_t *l_list_in_items_tmp = l_list_in_items; + // find cur addr in prev OUT items + //bool l_is_use_all_cur_out = false; + { + while(l_list_in_items_tmp) { + const dap_chain_tx_in_t *l_tx_in = (const dap_chain_tx_in_t*) l_list_in_items_tmp->data; + dap_chain_hash_fast_t tx_prev_hash = l_tx_in->header.tx_prev_hash; + //find prev OUT item dap_tx_data_t *l_tx_data_prev = NULL; HASH_FIND(hh, l_tx_data_hash, &tx_prev_hash, sizeof(dap_chain_hash_fast_t), l_tx_data_prev); if(l_tx_data_prev != NULL) { - char *l_src_str = NULL; - bool l_src_str_is_cur = false; + // fill token in all l_tx_data from prev transaction + + dap_list_t *l_list_out_info_tmp = l_list_out_info; + while(l_list_out_info_tmp) { + dap_tx_data_t *l_tx_data = (dap_tx_data_t*) l_list_out_info_tmp->data; + if(l_tx_data) { + // get token from prev tx + memcpy(l_tx_data->token_ticker, l_tx_data_prev->token_ticker, + sizeof(l_tx_data->token_ticker)); + dap_chain_datum_t *l_datum_prev = get_prev_tx(l_tx_data_prev); + dap_chain_datum_tx_t *l_tx_prev = + l_datum_prev ? (dap_chain_datum_tx_t*) l_datum_prev->data : NULL; + + // find OUT items in prev datum + dap_list_t *l_list_out_prev_items = dap_chain_datum_tx_items_get(l_tx_prev, + TX_ITEM_TYPE_OUT, NULL); + // find OUT item for IN item; + dap_list_t *l_list_out_prev_item = dap_list_nth(l_list_out_prev_items, + l_tx_in->header.tx_out_prev_idx); + dap_chain_tx_out_t *l_tx_prev_out = + l_list_out_prev_item ? + (dap_chain_tx_out_t*) l_list_out_prev_item->data : + NULL; + if(l_tx_prev_out && !memcmp(&l_tx_prev_out->addr, a_addr, sizeof(dap_chain_addr_t))) + l_tx_data->is_use_all_cur_out = true; + + } + l_list_out_info_tmp = dap_list_next(l_list_out_info_tmp); + } + } + l_list_in_items_tmp = dap_list_next(l_list_in_items_tmp); + } + // find prev OUT items for IN items + dap_list_t *l_list_in_items2_tmp = l_list_in_items; // go to begin of list + while(l_list_in_items2_tmp) { + const dap_chain_tx_in_t *l_tx_in = (const dap_chain_tx_in_t*) l_list_in_items2_tmp->data; + dap_chain_hash_fast_t tx_prev_hash = l_tx_in->header.tx_prev_hash; + // if first transaction - empty prev OUT item + if(dap_hash_fast_is_blank(&tx_prev_hash)) { dap_tx_data_t *l_tx_data = NULL; dap_list_t *l_list_out_info_tmp = l_list_out_info; @@ -487,174 +448,223 @@ char* dap_db_history_addr(dap_chain_addr_t * a_addr, dap_chain_t * a_chain, cons break; l_list_out_info_tmp = dap_list_next(l_list_out_info_tmp); } - if(l_tx_data) { - // get token from prev tx - memcpy(l_tx_data->token_ticker, l_tx_data_prev->token_ticker, - sizeof(l_tx_data->token_ticker)); - - dap_chain_datum_t *l_datum_prev = get_prev_tx(l_tx_data_prev); - dap_chain_datum_tx_t *l_tx_prev = - l_datum_prev ? (dap_chain_datum_tx_t*) l_datum_prev->data : NULL; - - // find OUT items in prev datum - dap_list_t *l_list_out_prev_items = dap_chain_datum_tx_items_get(l_tx_prev, - TX_ITEM_TYPE_OUT, NULL); - // find OUT item for IN item; - dap_list_t *l_list_out_prev_item = dap_list_nth(l_list_out_prev_items, - l_tx_in->header.tx_out_prev_idx); - dap_chain_tx_out_t *l_tx_prev_out = - l_list_out_prev_item ? - (dap_chain_tx_out_t*) l_list_out_prev_item->data : - NULL; - // if use src addr - bool l_is_use_src_addr = false; - // find source addrs - dap_string_t *l_src_addr = dap_string_new(NULL); - { - // find IN items in prev datum - for get destination addr - dap_list_t *l_list_in_prev_items = dap_chain_datum_tx_items_get(l_tx_prev, - TX_ITEM_TYPE_IN, NULL); - dap_list_t *l_list_tmp = l_list_in_prev_items; - while(l_list_tmp) { - dap_chain_tx_in_t *l_tx_prev_in = l_list_tmp->data; - dap_chain_hash_fast_t l_tx_prev_prev_hash = - l_tx_prev_in->header.tx_prev_hash; - //find prev OUT item - dap_tx_data_t *l_tx_data_prev_prev = NULL; - HASH_FIND(hh, l_tx_data_hash, &l_tx_prev_prev_hash, - sizeof(dap_chain_hash_fast_t), l_tx_data_prev_prev); - if(l_tx_data_prev_prev) { - // if use src addr - if(l_tx_data_prev_prev && - !memcmp(&l_tx_data_prev_prev->addr, a_addr, - sizeof(dap_chain_addr_t))) - l_is_use_src_addr = true; - char *l_str = dap_chain_addr_to_str(&l_tx_data_prev_prev->addr); - if(l_src_addr->len > 0) - dap_string_append_printf(l_src_addr, "\n %s", l_str); - else - dap_string_append_printf(l_src_addr, "%s", l_str); // first record - DAP_DELETE(l_str); - } - l_list_tmp = dap_list_next(l_list_tmp); + + // add emit info to ret string + if(l_tx_data && !memcmp(&l_tx_data->addr, a_addr, sizeof(dap_chain_addr_t))) { + dap_list_t *l_records_tmp = l_records_out; + while(l_records_tmp) { + char *tx_hash_str; + if(!dap_strcmp(a_hash_out_type,"hex")) + tx_hash_str = dap_strdup( l_tx_data->tx_hash_str); + else + tx_hash_str = dap_enc_base58_from_hex_str_to_str( l_tx_data->tx_hash_str); + const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t*) l_records_tmp->data; + + if(!dap_strcmp(a_hash_out_type,"hex")){ + dap_string_append_printf(l_str_out, "tx hash %s \n emit %lu %s\n", + tx_hash_str,//l_tx_data->tx_hash_str, + l_tx_out->header.value, + l_tx_data->token_ticker); } + else { + dap_string_append_printf(l_str_out, "tx hash %s \n emit %lu %s\n", + l_tx_data->tx_hash_str, + l_tx_out->header.value, + l_tx_data->token_ticker); + } + DAP_DELETE(tx_hash_str); + l_records_tmp = dap_list_next(l_records_tmp); } - - l_src_str_is_cur = l_is_use_src_addr; - if(l_src_addr->len <= 1) { - l_src_str = - (l_tx_data) ? dap_chain_addr_to_str(&l_tx_data->addr) : - NULL; - if(l_tx_prev_out && !memcmp(&l_tx_prev_out->addr, a_addr, sizeof(dap_chain_addr_t))) - l_src_str_is_cur = true; - dap_string_free(l_src_addr, true); + } + //dap_list_free(l_records_out); + } + // in other transactions except first one + else { + //find prev OUT item + dap_tx_data_t *l_tx_data_prev = NULL; + HASH_FIND(hh, l_tx_data_hash, &tx_prev_hash, sizeof(dap_chain_hash_fast_t), l_tx_data_prev); + if(l_tx_data_prev != NULL) { + char *l_src_str = NULL; + bool l_src_str_is_cur = false; + + dap_tx_data_t *l_tx_data = NULL; + dap_list_t *l_list_out_info_tmp = l_list_out_info; + while(l_list_out_info_tmp) { + l_tx_data = (dap_tx_data_t*) l_list_out_info_tmp->data; + if(l_tx_data->token_ticker[0]) + break; + l_list_out_info_tmp = dap_list_next(l_list_out_info_tmp); } - else - l_src_str = dap_string_free(l_src_addr, false); - - if(l_tx_prev_out) { - char *l_dst_to_str = dap_chain_addr_to_str(&l_tx_prev_out->addr); - // if use dst addr - bool l_is_use_dst_addr = false; - if(!memcmp(&l_tx_prev_out->addr, a_addr, sizeof(dap_chain_addr_t))) - l_is_use_dst_addr = true; - char *tx_hash_str; - if(!dap_strcmp(a_hash_out_type, "hex")) - tx_hash_str = dap_strdup(l_tx_data->tx_hash_str); + if(l_tx_data) { + // get token from prev tx + memcpy(l_tx_data->token_ticker, l_tx_data_prev->token_ticker, + sizeof(l_tx_data->token_ticker)); + + dap_chain_datum_t *l_datum_prev = get_prev_tx(l_tx_data_prev); + dap_chain_datum_tx_t *l_tx_prev = + l_datum_prev ? (dap_chain_datum_tx_t*) l_datum_prev->data : NULL; + + // find OUT items in prev datum + dap_list_t *l_list_out_prev_items = dap_chain_datum_tx_items_get(l_tx_prev, + TX_ITEM_TYPE_OUT, NULL); + // find OUT item for IN item; + dap_list_t *l_list_out_prev_item = dap_list_nth(l_list_out_prev_items, + l_tx_in->header.tx_out_prev_idx); + dap_chain_tx_out_t *l_tx_prev_out = + l_list_out_prev_item ? + (dap_chain_tx_out_t*) l_list_out_prev_item->data : + NULL; + // if use src addr + bool l_is_use_src_addr = false; + // find source addrs + dap_string_t *l_src_addr = dap_string_new(NULL); + { + // find IN items in prev datum - for get destination addr + dap_list_t *l_list_in_prev_items = dap_chain_datum_tx_items_get(l_tx_prev, + TX_ITEM_TYPE_IN, NULL); + dap_list_t *l_list_tmp = l_list_in_prev_items; + while(l_list_tmp) { + dap_chain_tx_in_t *l_tx_prev_in = l_list_tmp->data; + dap_chain_hash_fast_t l_tx_prev_prev_hash = + l_tx_prev_in->header.tx_prev_hash; + //find prev OUT item + dap_tx_data_t *l_tx_data_prev_prev = NULL; + HASH_FIND(hh, l_tx_data_hash, &l_tx_prev_prev_hash, + sizeof(dap_chain_hash_fast_t), l_tx_data_prev_prev); + if(l_tx_data_prev_prev) { + // if use src addr + if(l_tx_data_prev_prev && + !memcmp(&l_tx_data_prev_prev->addr, a_addr, + sizeof(dap_chain_addr_t))) + l_is_use_src_addr = true; + char *l_str = dap_chain_addr_to_str(&l_tx_data_prev_prev->addr); + if(l_src_addr->len > 0) + dap_string_append_printf(l_src_addr, "\n %s", l_str); + else + dap_string_append_printf(l_src_addr, "%s", l_str); // first record + DAP_DELETE(l_str); + } + l_list_tmp = dap_list_next(l_list_tmp); + } + } + + l_src_str_is_cur = l_is_use_src_addr; + if(l_src_addr->len <= 1) { + l_src_str = + (l_tx_data) ? dap_chain_addr_to_str(&l_tx_data->addr) : + NULL; + if(l_tx_prev_out && !memcmp(&l_tx_prev_out->addr, a_addr, sizeof(dap_chain_addr_t))) + l_src_str_is_cur = true; + dap_string_free(l_src_addr, true); + } else - tx_hash_str = dap_enc_base58_from_hex_str_to_str(l_tx_data->tx_hash_str); - if(l_is_use_src_addr && !l_is_use_dst_addr) { - dap_string_append_printf(l_str_out, - "tx hash %s \n %s in send %lu %s from %s\n to %s\n", - tx_hash_str,//l_tx_data->tx_hash_str, - l_time_str ? l_time_str : "", - l_tx_prev_out->header.value, - l_tx_data->token_ticker, - l_src_str ? l_src_str : "", - l_dst_to_str); - } else if(l_is_use_dst_addr && !l_is_use_src_addr) { - if(!l_src_str_is_cur) + l_src_str = dap_string_free(l_src_addr, false); + + if(l_tx_prev_out) { + char *l_dst_to_str = dap_chain_addr_to_str(&l_tx_prev_out->addr); + // if use dst addr + bool l_is_use_dst_addr = false; + if(!memcmp(&l_tx_prev_out->addr, a_addr, sizeof(dap_chain_addr_t))) + l_is_use_dst_addr = true; + char *tx_hash_str; + if(!dap_strcmp(a_hash_out_type, "hex")) + tx_hash_str = dap_strdup(l_tx_data->tx_hash_str); + else + tx_hash_str = dap_enc_base58_from_hex_str_to_str(l_tx_data->tx_hash_str); + if(l_is_use_src_addr && !l_is_use_dst_addr) { dap_string_append_printf(l_str_out, - "tx hash %s \n %s in recv %lu %s from %s\n", + "tx hash %s \n %s in send %lu %s from %s\n to %s\n", tx_hash_str,//l_tx_data->tx_hash_str, l_time_str ? l_time_str : "", l_tx_prev_out->header.value, l_tx_data->token_ticker, - l_src_str ? l_src_str : ""); + l_src_str ? l_src_str : "", + l_dst_to_str); + } else if(l_is_use_dst_addr && !l_is_use_src_addr) { + if(!l_src_str_is_cur) + dap_string_append_printf(l_str_out, + "tx hash %s \n %s in recv %lu %s from %s\n", + tx_hash_str,//l_tx_data->tx_hash_str, + l_time_str ? l_time_str : "", + l_tx_prev_out->header.value, + l_tx_data->token_ticker, + l_src_str ? l_src_str : ""); + } + DAP_DELETE(tx_hash_str); + DAP_DELETE(l_dst_to_str); } - DAP_DELETE(tx_hash_str); - DAP_DELETE(l_dst_to_str); + dap_list_free(l_list_out_prev_items); } - dap_list_free(l_list_out_prev_items); - } - - // OUT items - dap_list_t *l_records_tmp = l_records_out; - while(l_records_tmp) { - const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t*) l_records_tmp->data; - - if(l_tx_data->is_use_all_cur_out - || !memcmp(&l_tx_out->addr, a_addr, sizeof(dap_chain_addr_t))) { - - char *l_addr_str = (l_tx_out) ? dap_chain_addr_to_str(&l_tx_out->addr) : NULL; - - char *tx_hash_str; - if(!dap_strcmp(a_hash_out_type, "hex")) - tx_hash_str = dap_strdup(l_tx_data->tx_hash_str); - else - tx_hash_str = dap_enc_base58_from_hex_str_to_str(l_tx_data->tx_hash_str); - if(!memcmp(&l_tx_out->addr, a_addr, sizeof(dap_chain_addr_t))) { - if(!l_src_str_is_cur) + // OUT items + dap_list_t *l_records_tmp = l_records_out; + while(l_records_tmp) { + + const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t*) l_records_tmp->data; + + if(l_tx_data->is_use_all_cur_out + || !memcmp(&l_tx_out->addr, a_addr, sizeof(dap_chain_addr_t))) { + + char *l_addr_str = (l_tx_out) ? dap_chain_addr_to_str(&l_tx_out->addr) : NULL; + + char *tx_hash_str; + if(!dap_strcmp(a_hash_out_type, "hex")) + tx_hash_str = dap_strdup(l_tx_data->tx_hash_str); + else + tx_hash_str = dap_enc_base58_from_hex_str_to_str(l_tx_data->tx_hash_str); + if(!memcmp(&l_tx_out->addr, a_addr, sizeof(dap_chain_addr_t))) { + if(!l_src_str_is_cur) + dap_string_append_printf(l_str_out, + "tx hash %s \n %s recv %lu %s from %s\n", + tx_hash_str,//l_tx_data->tx_hash_str, + l_time_str ? l_time_str : "", + l_tx_out->header.value, + l_tx_data_prev->token_ticker, + l_src_str ? l_src_str : "?"); + // break search prev OUT items for IN items + l_list_in_items2_tmp = NULL; + } + else { dap_string_append_printf(l_str_out, - "tx hash %s \n %s recv %lu %s from %s\n", + "tx hash %s \n %s send %lu %s to %s\n", tx_hash_str,//l_tx_data->tx_hash_str, l_time_str ? l_time_str : "", l_tx_out->header.value, l_tx_data_prev->token_ticker, - l_src_str ? l_src_str : "?"); - // break search prev OUT items for IN items - l_list_in_items2_tmp = NULL; - } - else { - dap_string_append_printf(l_str_out, - "tx hash %s \n %s send %lu %s to %s\n", - tx_hash_str,//l_tx_data->tx_hash_str, - l_time_str ? l_time_str : "", - l_tx_out->header.value, - l_tx_data_prev->token_ticker, - l_addr_str ? l_addr_str : ""); - l_list_in_items2_tmp = NULL; + l_addr_str ? l_addr_str : ""); + l_list_in_items2_tmp = NULL; + } + DAP_DELETE(tx_hash_str); + DAP_DELETE(l_addr_str); } - DAP_DELETE(tx_hash_str); - DAP_DELETE(l_addr_str); + + l_records_tmp = dap_list_next(l_records_tmp); } + //dap_list_free(l_records_out); + DAP_DELETE(l_src_str); - l_records_tmp = dap_list_next(l_records_tmp); } - //dap_list_free(l_records_out); - DAP_DELETE(l_src_str); - } + l_list_in_items2_tmp = dap_list_next(l_list_in_items2_tmp); } - l_list_in_items2_tmp = dap_list_next(l_list_in_items2_tmp); + // l_list_in_items_tmp = dap_list_next(l_list_in_items_tmp); + // } } -// l_list_in_items_tmp = dap_list_next(l_list_in_items_tmp); -// } - } - if(l_list_tx_token) - dap_list_free(l_list_tx_token); - if(l_list_out_items) - dap_list_free(l_list_out_items); - if(l_list_in_items) - dap_list_free(l_list_in_items); - dap_list_free(l_records_out); - dap_list_free(l_list_out_info); - DAP_DELETE(l_time_str); + if(l_list_tx_token) + dap_list_free(l_list_tx_token); + if(l_list_out_items) + dap_list_free(l_list_out_items); + if(l_list_in_items) + dap_list_free(l_list_in_items); + dap_list_free(l_records_out); + dap_list_free(l_list_out_info); + DAP_DELETE(l_time_str); - // go to next transaction - l_atom = a_chain->callback_atom_iter_get_next(l_atom_iter, &l_atom_size); + // go to next transaction + l_atom = a_chain->callback_atom_iter_get_next(l_atom_iter, &l_atom_size); + } + DAP_DELETE(l_datums); } // delete hashes diff --git a/modules/type/blocks/dap_chain_block.c b/modules/type/blocks/dap_chain_block.c index f4c204bd8b..e1999a5c67 100644 --- a/modules/type/blocks/dap_chain_block.c +++ b/modules/type/blocks/dap_chain_block.c @@ -102,3 +102,132 @@ size_t dap_chain_block_datum_del_by_hash(dap_chain_block_t * a_block, size_t a_b return a_block_size; } +dap_chain_datum_t** dap_chain_block_get_datums(dap_chain_block_t * a_block, size_t a_block_size,size_t * a_datums_count ) +{ + +} + +dap_chain_block_meta_t** dap_chain_block_get_meta(dap_chain_block_t * a_block, size_t a_block_size,size_t * a_meta_count ) +{ + +} + +/** + * @brief dap_chain_block_meta_extract_generals + * @param a_meta + * @param a_meta_count + * @param a_block_prev_hash + * @param a_block_anchor_hash + * @param a_is_genesis + * @param a_nonce + * @param a_nonce2 + */ +void dap_chain_block_meta_extract(dap_chain_block_meta_t ** a_meta, size_t a_meta_count, + dap_chain_hash_fast_t * a_block_prev_hash, + dap_chain_hash_fast_t * a_block_anchor_hash, + dap_chain_hash_fast_t ** a_block_links, + size_t *a_block_links_count, + bool * a_is_genesis, + uint64_t *a_nonce, + uint64_t *a_nonce2 + ) +{ + // Check for meta that could be faced only once + bool l_was_prev = false; + bool l_was_genesis = false; + bool l_was_anchor = false; + bool l_was_nonce = false; + bool l_was_nonce2 = false; + // Init links parsing + size_t l_links_count_max = 5; + if (a_block_links_count) + *a_block_links_count = 0; + + + for(size_t i = 0; i < a_meta_count; i++){ + dap_chain_block_meta_t * l_meta = a_meta[i]; + switch (l_meta->hdr.type) { + case DAP_CHAIN_BLOCK_META_GENESIS: + if(l_was_genesis){ + log_it(L_WARNING, "Genesis meta could be only one in the block, meta #%u is ignored ", i); + break; + } + l_was_genesis = true; + if (a_is_genesis) + *a_is_genesis = true; + break; + case DAP_CHAIN_BLOCK_META_PREV: + if(l_was_prev){ + log_it(L_WARNING, "Prev meta could be only one in the block, meta #%u is ignored ", i); + break; + } + l_was_prev = true; + if (a_block_prev_hash){ + if (l_meta->hdr.size == sizeof (*a_block_prev_hash) ) + memcpy(a_block_prev_hash, l_meta->data, l_meta->hdr.size); + else + log_it(L_WARNING, "Meta #%zd PREV has wrong size %zd when expecting %zd",i, l_meta->hdr.size, sizeof (*a_block_prev_hash)); + } + break; + case DAP_CHAIN_BLOCK_META_ANCHOR: + if(l_was_anchor){ + log_it(L_WARNING, "Anchor meta could be only one in the block, meta #%u is ignored ", i); + break; + } + l_was_anchor = true; + if ( a_block_anchor_hash){ + if (l_meta->hdr.size == sizeof (*a_block_anchor_hash) ) + memcpy(a_block_anchor_hash, l_meta->data, l_meta->hdr.size); + else + log_it(L_WARNING, "Anchor meta #%zd has wrong size %zd when expecting %zd",i, l_meta->hdr.size, sizeof (*a_block_prev_hash)); + } + break; + case DAP_CHAIN_BLOCK_META_LINK: + if ( a_block_links && a_block_links_count){ + if ( *a_block_links_count == 0 ){ + *a_block_links = DAP_NEW_Z_SIZE(dap_chain_hash_fast_t, sizeof (dap_chain_hash_fast_t *) *l_links_count_max); + *a_block_links_count = 0; + }else if ( *a_block_links_count == l_links_count_max ){ + l_links_count_max *=2; + *a_block_links = DAP_REALLOC(*a_block_links, l_links_count_max); + } + + if (l_meta->hdr.size == sizeof (**a_block_links) ){ + memcpy(&a_block_links[*a_block_links_count], l_meta->data, l_meta->hdr.size); + (*a_block_links_count)++; + }else + log_it(L_WARNING, "Link meta #%zd has wrong size %zd when expecting %zd", i, l_meta->hdr.size, sizeof (*a_block_prev_hash)); + } + break; + case DAP_CHAIN_BLOCK_META_NONCE: + if(l_was_nonce){ + log_it(L_WARNING, "NONCE could be only one in the block, meta #%u is ignored ", i); + break; + } + l_was_nonce = true; + + if ( a_nonce){ + if (l_meta->hdr.size == sizeof (*a_nonce ) ) + memcpy(a_nonce, l_meta->data, l_meta->hdr.size); + else + log_it(L_WARNING, "NONCE meta #%zd has wrong size %zd when expecting %zd",i, l_meta->hdr.size, sizeof (*a_nonce)); + } + break; + case DAP_CHAIN_BLOCK_META_NONCE2: + if(l_was_nonce2){ + log_it(L_WARNING, "NONCE2 could be only one in the block, meta #%u is ignored ", i); + break; + } + l_was_nonce2 = true; + if ( a_nonce2){ + if (l_meta->hdr.size == sizeof (*a_nonce2 ) ) + memcpy(a_nonce2, l_meta->data, l_meta->hdr.size); + else + log_it(L_WARNING, "NONCE2 meta #%zd has wrong size %zd when expecting %zd",i, l_meta->hdr.size, sizeof (*a_nonce2)); + } + break; + default: { log_it(L_WARNING, "Unknown meta #%zd type 0x%02x (size %zd), possible corrupted block or you need to upgrade your software", + i, l_meta->hdr.type, l_meta->hdr.type); } + } + } +} diff --git a/modules/type/blocks/dap_chain_block_cache.c b/modules/type/blocks/dap_chain_block_cache.c index 2d4defa28e..98c58befea 100644 --- a/modules/type/blocks/dap_chain_block_cache.c +++ b/modules/type/blocks/dap_chain_block_cache.c @@ -80,16 +80,6 @@ dap_chain_block_cache_t * dap_chain_block_cache_dup(dap_chain_block_cache_t * a_ return l_ret; } -/** - * @brief dap_chain_block_cache_get_by_hash - * @param a_block_hash - * @return - */ -dap_chain_block_cache_t * dap_chain_block_cache_get_by_hash(dap_chain_hash_fast_t a_block_hash) -{ - return NULL; -} - /** * @brief dap_chain_block_cache_update * @param a_block_cache @@ -99,6 +89,9 @@ void dap_chain_block_cache_update(dap_chain_block_cache_t * a_block_cache) assert(a_block_cache); assert(a_block_cache->block); dap_hash_fast(a_block_cache->block, a_block_cache->block_size, &a_block_cache->block_hash); + if (a_block_cache->datum) + DAP_DELETE(a_block_cache->datum); + a_block_cache->datum = dap_chain_block_get_datums( a_block_cache->block, a_block_cache->block_size, &a_block_cache->datum_count ); } /** diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c index 4553ae187e..9c245fc597 100644 --- a/modules/type/blocks/dap_chain_cs_blocks.c +++ b/modules/type/blocks/dap_chain_cs_blocks.c @@ -69,8 +69,15 @@ typedef struct dap_chain_cs_blocks_pvt size_t block_new_size; } dap_chain_cs_blocks_pvt_t; +typedef struct dap_chain_cs_blocks_iter +{ + dap_chain_cs_blocks_t * blocks; +} dap_chain_cs_blocks_iter_t; + #define PVT(a) ((dap_chain_cs_blocks_pvt_t *) a->_pvt ) +#define ITER_PVT(a) ((dap_chain_cs_blocks_iter_t *) a->_inheritor ) + static int s_cli_parse_cmd_hash(char ** a_argv, int a_arg_index, int a_argc, char **a_str_reply,const char * a_param, dap_chain_hash_fast_t * a_datum_hash); static void s_cli_meta_hash_print( dap_string_t * a_str_tmp, const char * a_meta_title, dap_chain_block_meta_t * a_meta); static int s_cli_blocks(int a_argc, char ** a_argv, void *a_arg_func, char **a_str_reply); @@ -93,9 +100,9 @@ static dap_chain_atom_iter_t* s_callback_atom_iter_create_from(dap_chain_t * , static dap_chain_atom_ptr_t s_callback_atom_iter_find_by_hash(dap_chain_atom_iter_t * a_atom_iter , dap_chain_hash_fast_t * a_atom_hash, size_t * a_atom_size); static dap_chain_datum_tx_t* s_callback_atom_iter_find_by_tx_hash(dap_chain_t * a_chain , - dap_chain_hash_fast_t * a_atom_hash); + dap_chain_hash_fast_t * a_tx_hash); -static dap_chain_datum_t* s_callback_atom_get_datum(dap_chain_atom_ptr_t a_event, size_t a_atom_size); +static dap_chain_datum_t** s_callback_atom_get_datums(dap_chain_atom_ptr_t a_atom, size_t a_atom_size, size_t * a_datums_count); // Get blocks static dap_chain_atom_ptr_t s_callback_atom_iter_get_first( dap_chain_atom_iter_t * a_atom_iter, size_t *a_atom_size ); // Get the fisrt block static dap_chain_atom_ptr_t s_callback_atom_iter_get_next( dap_chain_atom_iter_t * a_atom_iter,size_t *a_atom_size ); // Get the next block @@ -181,7 +188,7 @@ int dap_chain_cs_blocks_new(dap_chain_t * a_chain, dap_config_t * a_chain_config // Linear pass through a_chain->callback_atom_iter_get_first = s_callback_atom_iter_get_first; // Get the fisrt element from chain a_chain->callback_atom_iter_get_next = s_callback_atom_iter_get_next; // Get the next element from chain from the current one - a_chain->callback_atom_get_datum = s_callback_atom_get_datum; + a_chain->callback_atom_get_datums = s_callback_atom_get_datums; a_chain->callback_atom_iter_get_links = s_callback_atom_iter_get_links; // Get the next element from chain from the current one a_chain->callback_atom_iter_get_lasts = s_callback_atom_iter_get_lasts; @@ -226,6 +233,20 @@ void dap_chain_cs_blocks_delete(dap_chain_t * a_chain) pthread_rwlock_destroy(&PVT(a_chain)->rwlock ); } +/** + * @brief dap_chain_block_cs_cache_get_by_hash + * @param a_blocks + * @param a_block_hash + * @return + */ +dap_chain_block_cache_t * dap_chain_block_cs_cache_get_by_hash(dap_chain_cs_blocks_t * a_blocks, dap_chain_hash_fast_t *a_block_hash) +{ + dap_chain_block_cache_t * l_ret = NULL; + pthread_rwlock_rdlock(& PVT(a_blocks)->rwlock); + HASH_FIND(hh, PVT(a_blocks)->blocks,a_block_hash, sizeof (*a_block_hash), l_ret ); + pthread_rwlock_unlock(& PVT(a_blocks)->rwlock); + return l_ret; +} /** * @brief s_cli_parse_cmd_hash @@ -322,9 +343,6 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void *a_arg_func, char **a_s int arg_index = 1; - const char * l_net_name = NULL; - const char * l_chain_name = NULL; - dap_chain_t * l_chain = NULL; dap_chain_cs_blocks_t * l_blocks = NULL; dap_chain_net_t * l_net = NULL; @@ -429,7 +447,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void *a_arg_func, char **a_s dap_enc_base58_hex_to_hash( l_subcmd_str_arg, &l_block_hash); // Convert argument to hash l_block = (dap_chain_block_t*) dap_chain_get_atom_by_hash( l_chain, &l_block_hash, &l_block_size); if ( l_block){ - dap_chain_block_cache_t *l_block_cache = dap_chain_block_cache_get(l_block, l_block_size); + dap_chain_block_cache_t *l_block_cache = dap_chain_block_cs_cache_get_by_hash(l_blocks, &l_block_hash); if ( l_block_cache ){ dap_string_t * l_str_tmp = dap_string_new(NULL); char buf[50]; @@ -649,6 +667,10 @@ static int s_add_atom_to_blocks(dap_chain_cs_blocks_t * a_blocks, dap_ledger_t * //All correct, no matter for result pthread_rwlock_wrlock( &PVT(a_blocks)->rwlock ); HASH_ADD(hh, PVT(a_blocks)->blocks,block_hash,sizeof (a_block_cache->block_hash), a_block_cache); + if (! (PVT(a_blocks)->block_cache_first ) ) + PVT(a_blocks)->block_cache_first = a_block_cache; + PVT(a_blocks)->block_cache_last = a_block_cache; + } else { log_it(L_WARNING,"Dag event %s check failed: code %d", a_block_cache->block_hash_str, res ); } @@ -671,11 +693,11 @@ static dap_chain_atom_verify_res_t s_callback_atom_add(dap_chain_t * a_chain, da dap_chain_hash_fast_t l_block_hash; size_t l_block_size = a_atom_size; dap_hash_fast(a_atom,a_atom_size, & l_block_hash); - dap_chain_block_cache_t * l_block_cache = dap_chain_block_cache_get_by_hash(l_block_hash); + dap_chain_block_cache_t * l_block_cache = dap_chain_block_cs_cache_get_by_hash(l_blocks, &l_block_hash); if (l_block_cache ){ - ret = ATOM_PASS; log_it(L_DEBUG, "... already present in blocks %s",l_block_cache->block_hash_str); - } else{ + return ATOM_PASS; + } else { l_block_cache = dap_chain_block_cache_new( l_block, l_block_size); log_it(L_DEBUG, "... new block %s",l_block_cache->block_hash_str); ret = ATOM_ACCEPT; @@ -702,9 +724,6 @@ static dap_chain_atom_verify_res_t s_callback_atom_add(dap_chain_t * a_chain, da ret = ATOM_REJECT; } } - // will added in callback s_chain_callback_atom_add_from_treshold() - //while(dap_chain_cs_dag_proc_treshold(l_dag, a_chain->ledger)); - if(ret == ATOM_PASS){ DAP_DELETE(l_block_cache); } @@ -720,7 +739,58 @@ static dap_chain_atom_verify_res_t s_callback_atom_add(dap_chain_t * a_chain, da */ static dap_chain_atom_verify_res_t s_callback_atom_verify(dap_chain_t * a_chain, dap_chain_atom_ptr_t a_atom , size_t a_atom_size) { + dap_chain_cs_blocks_t * l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain); + assert(l_blocks); + dap_chain_cs_blocks_pvt_t * l_blocks_pvt = PVT(l_blocks); + assert(l_blocks_pvt); + dap_chain_block_t * l_block = (dap_chain_block_t *) a_atom; + dap_chain_atom_verify_res_t res = ATOM_ACCEPT; + if(sizeof (l_block->hdr) >= a_atom_size){ + log_it(L_WARNING,"Size of block is %zd that is equal or less then block's header size %zd",a_atom_size,sizeof (l_block->hdr)); + return ATOM_REJECT; + } + size_t l_meta_count = 0; + dap_chain_block_meta_t ** l_meta= dap_chain_block_get_meta(l_block, a_atom_size, & l_meta_count); + // Parse metadata + bool l_is_genesis=false; + dap_chain_hash_fast_t l_block_prev_hash = {0}; + dap_chain_hash_fast_t l_block_anchor_hash = {0}; + uint64_t l_nonce = 0; + uint64_t l_nonce2 = 0; + dap_chain_block_meta_extract(l_meta, l_meta_count, + &l_block_prev_hash, + &l_block_anchor_hash, + NULL, + NULL, + &l_is_genesis, + &l_nonce, + &l_nonce2 ) ; + // genesis or seed mode + if ( l_is_genesis){ + if( s_seed_mode && ! l_blocks_pvt->blocks ){ + log_it(L_NOTICE,"Accepting new genesis block"); + return ATOM_ACCEPT; + }else if(s_seed_mode){ + log_it(L_WARNING,"Cant accept genesis blockt: already present data in blockchain"); + return ATOM_REJECT; + } + }else{ + dap_chain_block_cache_t * l_block_prev_cache = dap_chain_block_cs_cache_get_by_hash(l_blocks,&l_block_prev_hash); + if ( ! l_block_prev_cache ){ + res = ATOM_REJECT; + log_it(L_WARNING, "Can't find PREV hash (but because still no bysantium consensus we just drop such block off)"); + // TODO make treshold and bysantium consensus + } + } + + // 2nd level consensus + if(res == ATOM_ACCEPT) + if(l_blocks->callback_block_verify) + if (l_blocks->callback_block_verify(l_blocks, l_block, a_atom_size)) + res = ATOM_REJECT; + + return res; } /** @@ -729,7 +799,7 @@ static dap_chain_atom_verify_res_t s_callback_atom_verify(dap_chain_t * a_chain, */ static size_t s_callback_atom_get_static_hdr_size(void) { - + return sizeof (dap_chain_block_hdr_t); } /** @@ -739,7 +809,10 @@ static size_t s_callback_atom_get_static_hdr_size(void) */ static dap_chain_atom_iter_t* s_callback_atom_iter_create(dap_chain_t * a_chain ) { - + dap_chain_atom_iter_t * l_atom_iter = DAP_NEW_Z(dap_chain_atom_iter_t); + l_atom_iter->chain = a_chain; + l_atom_iter->_inheritor = DAP_NEW_Z(dap_chain_cs_blocks_iter_t); + return l_atom_iter; } /** @@ -773,7 +846,7 @@ static dap_chain_atom_ptr_t s_callback_atom_iter_find_by_hash(dap_chain_atom_ite * @param a_atom_hash * @return */ -static dap_chain_datum_tx_t* s_callback_atom_iter_find_by_tx_hash(dap_chain_t * a_chain, dap_chain_hash_fast_t * a_atom_hash) +static dap_chain_datum_tx_t* s_callback_atom_iter_find_by_tx_hash(dap_chain_t * a_chain, dap_chain_hash_fast_t * a_tx_hash) { } @@ -784,9 +857,11 @@ static dap_chain_datum_tx_t* s_callback_atom_iter_find_by_tx_hash(dap_chain_t * * @param a_atom_size * @return */ -static dap_chain_datum_t* s_callback_atom_get_datum(dap_chain_atom_ptr_t a_event, size_t a_atom_size) +static dap_chain_datum_t** s_callback_atom_get_datums(dap_chain_atom_ptr_t a_atom, size_t a_atom_size, size_t * a_datums_count) { - + assert(a_datums_count); + dap_chain_datum_t ** l_ret = dap_chain_block_get_datums(a_atom, a_atom_size,a_datums_count); + return l_ret; } /** @@ -797,7 +872,23 @@ static dap_chain_datum_t* s_callback_atom_get_datum(dap_chain_atom_ptr_t a_event */ static dap_chain_atom_ptr_t s_callback_atom_iter_get_first( dap_chain_atom_iter_t * a_atom_iter, size_t *a_atom_size ) { - + if(! a_atom_iter){ + log_it(L_ERROR, "NULL iterator on input for atom_iter_get_first function"); + return NULL; + } + dap_chain_cs_blocks_t * l_blocks = DAP_CHAIN_CS_BLOCKS(a_atom_iter->chain); + dap_chain_cs_blocks_pvt_t *l_blocks_pvt = l_blocks ? PVT(l_blocks) : NULL; + assert(l_blocks_pvt); + a_atom_iter->cur_item = l_blocks_pvt->block_cache_last ; + a_atom_iter->cur = l_blocks_pvt->block_cache_last ? l_blocks_pvt->block_cache_last->block : NULL ; + a_atom_iter->cur_size = l_blocks_pvt->block_cache_first ? l_blocks_pvt->block_cache_first->block_size : 0; + +// a_atom_iter->cur = a_atom_iter->cur ? +// (dap_chain_cs_dag_event_t*) PVT (DAP_CHAIN_CS_DAG( a_atom_iter->chain) )->events->event : NULL; +// a_atom_iter->cur_item = PVT (DAP_CHAIN_CS_DAG( a_atom_iter->chain) )->events; + if (a_atom_size) + *a_atom_size = a_atom_iter->cur_size; + return a_atom_iter->cur; } /** @@ -841,7 +932,7 @@ static dap_chain_atom_ptr_t *s_callback_atom_iter_get_lasts( dap_chain_atom_iter */ static void s_callback_atom_iter_delete(dap_chain_atom_iter_t * a_atom_iter ) { - + DAP_DELETE(a_atom_iter); } /** diff --git a/modules/type/blocks/include/dap_chain_block.h b/modules/type/blocks/include/dap_chain_block.h index cad3a15179..3b75aa4e72 100644 --- a/modules/type/blocks/include/dap_chain_block.h +++ b/modules/type/blocks/include/dap_chain_block.h @@ -93,3 +93,20 @@ size_t dap_chain_block_meta_add(dap_chain_block_t * a_block, size_t a_block_size // Add datum in block size_t dap_chain_block_datum_add(dap_chain_block_t * a_block, size_t a_block_size, dap_chain_datum_t * a_datum, size_t a_datum_size); size_t dap_chain_block_datum_del_by_hash(dap_chain_block_t * a_block, size_t a_block_size, dap_chain_hash_fast_t* a_datum_hash); + +// Create and return datums list +dap_chain_datum_t** dap_chain_block_get_datums(dap_chain_block_t * a_block, size_t a_block_size,size_t * a_datums_count ); + +// Create and return meta parameters list +dap_chain_block_meta_t** dap_chain_block_get_meta(dap_chain_block_t * a_block, size_t a_block_size,size_t * a_meta_count ); + +void dap_chain_block_meta_extract(dap_chain_block_meta_t ** a_meta, size_t a_meta_count, + dap_chain_hash_fast_t * a_block_prev_hash, + dap_chain_hash_fast_t * a_block_anchor_hash, + dap_chain_hash_fast_t ** a_block_links, + size_t *a_block_links_count, + bool * a_is_genesis, + uint64_t *a_nonce, + uint64_t *a_nonce2 + ); + diff --git a/modules/type/blocks/include/dap_chain_block_cache.h b/modules/type/blocks/include/dap_chain_block_cache.h index d29cf3aaf4..1018855d18 100644 --- a/modules/type/blocks/include/dap_chain_block_cache.h +++ b/modules/type/blocks/include/dap_chain_block_cache.h @@ -36,7 +36,7 @@ typedef struct dap_chain_block_cache{ time_t ts_created; // Block's datums - uint32_t datum_count; + size_t datum_count; dap_chain_datum_t ** datum; // Block's metadatas diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c index 6823ea1c67..b21506e4e5 100644 --- a/modules/type/dag/dap_chain_cs_dag.c +++ b/modules/type/dag/dap_chain_cs_dag.c @@ -97,7 +97,7 @@ static dap_chain_atom_ptr_t s_chain_callback_atom_iter_find_by_hash(dap_chain_at static dap_chain_datum_tx_t* s_chain_callback_atom_iter_find_by_tx_hash(dap_chain_t * a_chain , dap_chain_hash_fast_t * a_atom_hash); -static dap_chain_datum_t* s_chain_callback_atom_get_datum(dap_chain_atom_ptr_t a_event, size_t a_atom_size); +static dap_chain_datum_t** s_chain_callback_atom_get_datum(dap_chain_atom_ptr_t a_event, size_t a_atom_size, size_t *a_datums_count); // Get event(s) from dag static dap_chain_atom_ptr_t s_chain_callback_atom_iter_get_first( dap_chain_atom_iter_t * a_atom_iter, size_t *a_atom_size ); // Get the fisrt event from dag static dap_chain_atom_ptr_t s_chain_callback_atom_iter_get_next( dap_chain_atom_iter_t * a_atom_iter,size_t *a_atom_size ); // Get the next event from dag @@ -187,7 +187,7 @@ int dap_chain_cs_dag_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg) // Linear pass through a_chain->callback_atom_iter_get_first = s_chain_callback_atom_iter_get_first; // Get the fisrt element from chain a_chain->callback_atom_iter_get_next = s_chain_callback_atom_iter_get_next; // Get the next element from chain from the current one - a_chain->callback_atom_get_datum = s_chain_callback_atom_get_datum; + a_chain->callback_atom_get_datums = s_chain_callback_atom_get_datum; a_chain->callback_atom_iter_get_links = s_chain_callback_atom_iter_get_links; // Get the next element from chain from the current one a_chain->callback_atom_iter_get_lasts = s_chain_callback_atom_iter_get_lasts; @@ -928,13 +928,23 @@ static dap_chain_atom_iter_t* s_chain_callback_atom_iter_create(dap_chain_t * a_ /** * @brief s_chain_callback_atom_get_datum Get the datum from event * @param a_atom_iter + * @param a_datums_count * @return */ -static dap_chain_datum_t* s_chain_callback_atom_get_datum(dap_chain_atom_ptr_t a_event, size_t a_atom_size) +static dap_chain_datum_t** s_chain_callback_atom_get_datum(dap_chain_atom_ptr_t a_event, size_t a_atom_size, size_t *a_datums_count) { - if(a_event) - return dap_chain_cs_dag_event_get_datum((dap_chain_cs_dag_event_t*) a_event, a_atom_size); - return NULL; + assert(a_datums_count); + if(a_event){ + dap_chain_datum_t * l_datum = dap_chain_cs_dag_event_get_datum((dap_chain_cs_dag_event_t*) a_event, a_atom_size); + if (l_datum){ + dap_chain_datum_t ** l_datums = DAP_NEW_SIZE(dap_chain_datum_t*, sizeof(dap_chain_datum_t*)); + *a_datums_count = 1; + l_datums[0] = l_datum; + return l_datums; + }else + return NULL; + }else + return NULL; } /** -- GitLab