From e919b5e36fd4a5656369af29ed95f41a303ca054 Mon Sep 17 00:00:00 2001 From: "roman.khlopkov" <roman.khlopkov@demlabs.net> Date: Wed, 29 Nov 2023 20:05:20 +0300 Subject: [PATCH] [+] Reward history by block num --- modules/chain/include/dap_chain.h | 2 +- modules/net/dap_chain_net.c | 39 +- modules/net/dap_chain_net_decree.c | 28 +- modules/net/include/dap_chain_net.h | 6 +- modules/type/blocks/dap_chain_block.c | 496 ++++++++++-------- modules/type/blocks/dap_chain_block_cache.c | 24 +- modules/type/blocks/dap_chain_block_chunk.c | 2 +- modules/type/blocks/dap_chain_cs_blocks.c | 187 ++++--- modules/type/blocks/include/dap_chain_block.h | 27 +- .../blocks/include/dap_chain_block_cache.h | 9 +- .../type/blocks/include/dap_chain_cs_blocks.h | 2 + 11 files changed, 442 insertions(+), 380 deletions(-) diff --git a/modules/chain/include/dap_chain.h b/modules/chain/include/dap_chain.h index 6912588c49..d868605fef 100644 --- a/modules/chain/include/dap_chain.h +++ b/modules/chain/include/dap_chain.h @@ -111,7 +111,7 @@ typedef void (*dap_chain_callback_atom_iter_delete_t)(dap_chain_atom_iter_t *); typedef void (*dap_chain_callback_notify_t)(void *a_arg, dap_chain_t *a_chain, dap_chain_cell_id_t a_id, void *a_atom, size_t a_atom_size); //change in chain happened -typedef size_t(*dap_chain_callback_get_count)(dap_chain_t *a_chain); +typedef uint64_t (*dap_chain_callback_get_count)(dap_chain_t *a_chain); typedef dap_list_t *(*dap_chain_callback_get_list)(dap_chain_t *a_chain, size_t a_count, size_t a_page, bool a_reverse); typedef dap_list_t *(*dap_chain_callback_get_poa_certs)(dap_chain_t *a_chain, size_t *a_auth_certs_count, uint16_t *count_verify); typedef void (*dap_chain_callback_set_min_validators_count)(dap_chain_t *a_chain, uint16_t a_new_value); diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c index 801bdf39de..ebeddd4c23 100644 --- a/modules/net/dap_chain_net.c +++ b/modules/net/dap_chain_net.c @@ -145,6 +145,12 @@ struct net_link { UT_hash_handle hh; }; +struct block_reward { + uint64_t block_number; + uint256_t reward; + struct block_reward *prev, *next; +}; + /** * @struct dap_chain_net_pvt * @details Private part of chain_net dap object @@ -188,6 +194,9 @@ typedef struct dap_chain_net_pvt{ dap_global_db_cluster_t *mempool_clusters; // List of chains mempools dap_global_db_cluster_t *orders_cluster; dap_global_db_cluster_t *nodes_cluster; + + // Block sign rewards history + struct block_reward *rewards; } dap_chain_net_pvt_t; typedef struct dap_chain_net_item{ @@ -2088,7 +2097,6 @@ int s_net_init(const char * a_net_name, uint16_t a_acl_idx) dap_chain_net_pvt_t *l_net_pvt = PVT(l_net); l_net_pvt->load_mode = true; l_net_pvt->acl_idx = a_acl_idx; - // Bridged netwoks allowed to send transactions to uint16_t l_net_ids_count = 0; char **l_bridged_net_ids = dap_config_get_array_str(l_cfg, "general", "bridged_network_ids", &l_net_ids_count); @@ -3202,6 +3210,35 @@ bool dap_chain_net_get_load_mode(dap_chain_net_t * a_net) return PVT(a_net)->load_mode; } +int dap_chain_net_add_reward(dap_chain_net_t *a_net, uint256_t a_reward, uint64_t a_block_num) +{ + dap_return_val_if_fail(a_net, -1); + if (PVT(a_net)->rewards && PVT(a_net)->rewards->block_number >= a_block_num) { + log_it(L_ERROR, "Can't add retrospective reward for block"); + return -2; + } + struct block_reward *l_new_reward = DAP_NEW_Z(struct block_reward); + if (!l_new_reward) { + log_it(L_CRITICAL, "Out of memory"); + return -3; + } + l_new_reward->block_number = a_block_num; + l_new_reward->reward = a_reward; + // Place new reward at begining + DL_PREPEND(PVT(a_net)->rewards, l_new_reward); + return 0; +} + +uint256_t dap_chain_net_get_reward(dap_chain_net_t *a_net, uint64_t a_block_num) +{ + struct block_reward *l_reward; + DL_FOREACH(PVT(a_net)->rewards, l_reward) { + if (l_reward->block_number <= a_block_num) + return l_reward->reward; + } + return uint256_0; +} + void dap_chain_net_announce_addrs() { if(!HASH_COUNT(s_net_items)){ log_it(L_ERROR, "Can't find any nets"); diff --git a/modules/net/dap_chain_net_decree.c b/modules/net/dap_chain_net_decree.c index e2ba495305..37ad25a48a 100644 --- a/modules/net/dap_chain_net_decree.c +++ b/modules/net/dap_chain_net_decree.c @@ -53,8 +53,8 @@ static struct decree_hh { // Private fuctions prototype static bool s_verify_pkey (dap_sign_t *a_sign, dap_chain_net_t *a_net); -static int s_common_decree_handler(dap_chain_datum_decree_t * a_decree, dap_chain_net_t *a_net, dap_chain_t *a_chain, bool a_apply); -static int s_service_decree_handler(dap_chain_datum_decree_t * a_decree, dap_chain_t *a_chain, bool a_apply); +static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain_t *a_chain, bool a_apply); +static int s_service_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain_t *a_chain, bool a_apply); // Public functions @@ -86,10 +86,8 @@ int dap_chain_net_decree_init(dap_chain_net_t *a_net) dap_chain_net_decree_t *l_decree = NULL; l_decree = DAP_NEW_Z(dap_chain_net_decree_t); - - if (!l_decree) - { - log_it(L_WARNING,"Out of memory."); + if (!l_decree) { + log_it(L_CRITICAL, "Out of memory"); return -2; } @@ -100,7 +98,7 @@ int dap_chain_net_decree_init(dap_chain_net_t *a_net) a_net->pub.decree = l_decree; // Preset reward for block signs, before first reward decree - l_net->pub.base_reward = dap_chain_balance_scan("2851988815387151461"); + dap_chain_net_add_reward(a_net, dap_chain_balance_scan("2851988815387151461"), 0); return 0; } @@ -138,7 +136,7 @@ int s_decree_verify_tsd(dap_chain_datum_decree_t * a_decree, dap_chain_net_t *a_ // Process decree switch(a_decree->header.type){ case DAP_CHAIN_DATUM_DECREE_TYPE_COMMON:{ - ret_val = s_common_decree_handler(a_decree, a_net, NULL, false); + ret_val = s_common_decree_handler(a_decree, a_net->pub.chains, false); break; } case DAP_CHAIN_DATUM_DECREE_TYPE_SERVICE:{ @@ -292,7 +290,7 @@ int dap_chain_net_decree_apply(dap_hash_fast_t *a_decree_hash, dap_chain_datum_d // Process decree switch(l_decree_hh->decree->header.type) { case DAP_CHAIN_DATUM_DECREE_TYPE_COMMON: - ret_val = s_common_decree_handler(l_decree_hh->decree, l_net, a_chain, true); + ret_val = s_common_decree_handler(l_decree_hh->decree, a_chain, true); break; case DAP_CHAIN_DATUM_DECREE_TYPE_SERVICE: ret_val = s_service_decree_handler(l_decree_hh->decree, a_chain, true); @@ -358,14 +356,14 @@ static bool s_verify_pkey (dap_sign_t *a_sign, dap_chain_net_t *a_net) return false; } -static int s_common_decree_handler(dap_chain_datum_decree_t * a_decree, dap_chain_net_t *a_net, dap_chain_t *a_chain, bool a_apply) +static int s_common_decree_handler(dap_chain_datum_decree_t * a_decree, dap_chain_t *a_chain, bool a_apply) { uint256_t l_uint256_buffer; uint16_t l_uint16_buffer; dap_chain_addr_t l_addr = {}; //???????? dap_hash_fast_t l_hash = {}; dap_chain_node_addr_t l_node_addr = {}; - dap_chain_net_t *l_net = a_net; + dap_chain_net_t *l_net = dap_chain_net_by_id(a_chain->net_id); dap_list_t *l_owners_list = NULL; if (a_apply && !a_chain){ @@ -465,9 +463,8 @@ static int s_common_decree_handler(dap_chain_datum_decree_t * a_decree, dap_chai log_it(L_WARNING,"Can't get min stake value from decree."); return -105; } - dap_chain_t *l_chain = a_chain; - if (!a_chain) - l_chain = dap_chain_find_by_id(a_net->pub.id, a_decree->header.common_decree_params.chain_id); + dap_chain_t *l_chain = a_chain ? a_chain + : dap_chain_find_by_id(l_net->pub.id, a_decree->header.common_decree_params.chain_id); if (!l_chain) { log_it(L_WARNING, "Specified chain not found"); return -106; @@ -548,7 +545,8 @@ static int s_common_decree_handler(dap_chain_datum_decree_t * a_decree, dap_chai } if (!a_apply) break; - a_net->pub.base_reward = l_uint256_buffer; + uint64_t l_cur_block_num = a_chain->callback_count_atom(a_chain); + dap_chain_net_add_reward(l_net, l_uint256_buffer, l_cur_block_num); } break; default: return -1; diff --git a/modules/net/include/dap_chain_net.h b/modules/net/include/dap_chain_net.h index b82409b423..719c635e49 100644 --- a/modules/net/include/dap_chain_net.h +++ b/modules/net/include/dap_chain_net.h @@ -81,8 +81,6 @@ typedef struct dap_chain_net{ // Net fee uint256_t fee_value; dap_chain_addr_t fee_addr; - // Block sign reward - uint256_t base_reward; pthread_mutex_t balancer_mutex; dap_list_t *link_list; @@ -158,10 +156,14 @@ dap_list_t* dap_chain_net_get_node_list(dap_chain_net_t * a_net); dap_list_t* dap_chain_net_get_node_list_cfg(dap_chain_net_t * a_net); dap_chain_node_role_t dap_chain_net_get_role(dap_chain_net_t * a_net); dap_chain_node_info_t *dap_chain_net_balancer_link_from_cfg(dap_chain_net_t *a_net); + int dap_chain_net_add_poa_certs_to_cluster(dap_chain_net_t *a_net, dap_global_db_cluster_t *a_cluster); bool dap_chain_net_add_validator_to_clusters(dap_chain_t *a_chain, dap_stream_node_addr_t *a_addr); dap_global_db_cluster_t *dap_chain_net_get_mempool_cluster(dap_chain_t *a_chain); +int dap_chain_net_add_reward(dap_chain_net_t *a_net, uint256_t a_reward, uint64_t a_block_num); +uint256_t dap_chain_net_get_reward(dap_chain_net_t *a_net, uint64_t a_block_num); + /** * @brief dap_chain_net_get_gdb_group_mempool * @param l_chain diff --git a/modules/type/blocks/dap_chain_block.c b/modules/type/blocks/dap_chain_block.c index 2b64edb253..ecd8665b90 100644 --- a/modules/type/blocks/dap_chain_block.c +++ b/modules/type/blocks/dap_chain_block.c @@ -25,6 +25,7 @@ #include "dap_common.h" #include "dap_config.h" #include "dap_hash.h" +#include "dap_uuid.h" #include "dap_chain_block.h" #include "dap_chain_block_cache.h" @@ -55,34 +56,44 @@ void dap_chain_block_deinit() /** * @brief dap_chain_block_new * @param a_prev_block + * @param a_blockreward + * @param a_block_size * @return */ dap_chain_block_t *dap_chain_block_new(dap_chain_hash_fast_t *a_prev_block, size_t *a_block_size) { - // Type sizeof's misunderstanding in malloc? - dap_chain_block_t * l_block = DAP_NEW_Z_SIZE (dap_chain_block_t,sizeof(l_block->hdr)); - if( l_block == NULL){ + dap_chain_block_t *l_block = DAP_NEW_Z(dap_chain_block_t); + if (!l_block) { log_it(L_CRITICAL, "Can't allocate memory for the new block"); return NULL; - }else{ - l_block->hdr.signature = DAP_CHAIN_BLOCK_SIGNATURE; - l_block->hdr.version = 1; - l_block->hdr.ts_created = time(NULL); - - l_block->hdr.merkle = (dap_chain_hash_fast_t){ 0 }; - - size_t l_block_size = sizeof(l_block->hdr); - if( a_prev_block ){ - l_block_size = dap_chain_block_meta_add(&l_block, l_block_size, DAP_CHAIN_BLOCK_META_PREV, - a_prev_block, sizeof(*a_prev_block)); - }else{ - l_block_size = dap_chain_block_meta_add(&l_block, l_block_size, DAP_CHAIN_BLOCK_META_GENESIS, NULL, 0); - log_it(L_INFO, "Genesis block produced"); - } - if (a_block_size) - *a_block_size = l_block_size; - return l_block; } + l_block->hdr.signature = DAP_CHAIN_BLOCK_SIGNATURE; + l_block->hdr.version = 1; + l_block->hdr.ts_created = time(NULL); + + size_t l_block_size = sizeof(l_block->hdr); + if (a_prev_block) { + l_block_size = dap_chain_block_meta_add(&l_block, l_block_size, DAP_CHAIN_BLOCK_META_PREV, + a_prev_block, sizeof(*a_prev_block)); + } else { + l_block_size = dap_chain_block_meta_add(&l_block, l_block_size, DAP_CHAIN_BLOCK_META_GENESIS, NULL, 0); + log_it(L_INFO, "Genesis block produced"); + } + if (l_block_size) { + uint64_t l_nonce = dap_uuid_generate_uint64(); + l_block_size = dap_chain_block_meta_add(&l_block, l_block_size, DAP_CHAIN_BLOCK_META_NONCE, + &l_nonce, sizeof(uint64_t)); + } + /*if (l_block_size && a_block_reward) + l_block_size = dap_chain_block_meta_add(&l_block, l_block_size, DAP_CHAIN_BLOCK_META_REWARD, + a_block_reward, sizeof(uint256_t));*/ + if (!l_block_size) { + log_it(L_ERROR, "Can't add meta to block"); + DAP_DEL_Z(l_block); + } + if (a_block_size) + *a_block_size = l_block_size; + return l_block; } /** @@ -113,53 +124,6 @@ size_t s_block_get_datum_offset(const dap_chain_block_t *a_block, size_t a_block return l_offset; } -// -/** - * @brief dap_chain_block_meta_add - * @details Add metadata in block - * @param a_block_ptr - * @param a_block_size - * @param a_meta_type - * @param a_data - * @param a_data_size - * @return - */ -size_t dap_chain_block_meta_add(dap_chain_block_t ** a_block_ptr, size_t a_block_size, uint8_t a_meta_type, const void * a_data, size_t a_data_size) -{ - assert(a_block_ptr); - dap_chain_block_t * l_block = *a_block_ptr; - dap_chain_block_meta_t * l_meta = NULL; - if( a_block_size < sizeof(l_block->hdr) ){ - log_it(L_ERROR,"Meta add: Corrupted block size %zd thats smaller then block header size %zd ", a_block_size, sizeof (l_block->hdr)); - return 0; - } - if(l_block->hdr.meta_count == UINT16_MAX){ - log_it(L_ERROR,"Meta add: Can't add more, maximum meta count %hu is achieved", UINT16_MAX); - return 0; - } - if( UINT32_MAX - l_block->hdr.meta_n_datum_n_signs_size < a_data_size + sizeof (l_meta->hdr) ){ - log_it(L_ERROR,"Meta add: Can't add more, maximum block data section size %u achieved", UINT32_MAX); - return 0; - } - - size_t l_add_size = sizeof(l_meta->hdr) + a_data_size; - *a_block_ptr = l_block = DAP_REALLOC(l_block, a_block_size + l_add_size); - size_t l_offset = s_block_get_datum_offset(l_block, a_block_size); - size_t l_datum_n_sign_copy_size = a_block_size - sizeof(l_block->hdr) - l_offset; - if (l_datum_n_sign_copy_size) { - byte_t *l_meta_end = l_block->meta_n_datum_n_sign + l_offset; - memmove(l_meta_end + l_add_size, l_meta_end, l_datum_n_sign_copy_size); - } - l_meta = (dap_chain_block_meta_t *)(l_block->meta_n_datum_n_sign + l_offset); // Update data end in reallocated block - l_meta->hdr.data_size = a_data_size; - l_meta->hdr.type = a_meta_type; - if (a_data_size) - memcpy(l_meta->data, a_data, a_data_size); - l_block->hdr.meta_n_datum_n_signs_size = l_offset + l_datum_n_sign_copy_size; - l_block->hdr.meta_count++; - return a_block_size + l_add_size; -} - /** * @brief dap_chain_block_datum_add * @param a_block_ptr @@ -202,6 +166,10 @@ size_t dap_chain_block_datum_add(dap_chain_block_t ** a_block_ptr, size_t a_bloc if (a_datum_size + l_block->hdr.meta_n_datum_n_signs_size < UINT32_MAX && l_block->hdr.datum_count < UINT16_MAX) { // If were signs - they would be deleted after because signed should be all the block filled *a_block_ptr = l_block = DAP_REALLOC(l_block, sizeof(l_block->hdr) + l_offset + a_datum_size); + if (!l_block) { + log_it(L_CRITICAL, "Memory reallocation error"); + return 0; + } memcpy(l_block->meta_n_datum_n_sign + l_offset, a_datum, a_datum_size); l_offset += a_datum_size; l_block->hdr.datum_count++; @@ -333,6 +301,10 @@ size_t dap_chain_block_sign_add(dap_chain_block_t **a_block_ptr, size_t a_block_ if (!l_block_sign_size) return 0; *a_block_ptr = l_block = DAP_REALLOC(l_block, l_block_sign_size + a_block_size); + if (!l_block) { + log_it(L_CRITICAL, "Memory reallocation error"); + return 0; + } memcpy(((byte_t *)l_block) + a_block_size, l_block_sign, l_block_sign_size); DAP_DELETE(l_block_sign); return a_block_size + l_block_sign_size; @@ -393,13 +365,12 @@ size_t dap_chain_block_get_signs_count(const dap_chain_block_t * a_block, size_t bool dap_chain_block_sign_match_pkey(const dap_chain_block_t *a_block, size_t a_block_size, dap_pkey_t *a_sign_pkey) { dap_return_val_if_fail(a_block && a_block_size, false); - uint16_t l_sign_count = 0; size_t l_offset = dap_chain_block_get_sign_offset(a_block, a_block_size); while (l_offset + sizeof(a_block->hdr) < a_block_size) { dap_sign_t *l_sign = (dap_sign_t *)(a_block->meta_n_datum_n_sign + l_offset); size_t l_sign_size = dap_sign_get_size(l_sign); if (!l_sign_size) { - log_it(L_WARNING, "Empty sign #%hu", l_sign_count); + log_it(L_WARNING, "Empty or corrupted sign"); return false; } if (dap_pkey_match_sign(a_sign_pkey, l_sign)) @@ -430,8 +401,11 @@ dap_chain_datum_t** dap_chain_block_get_datums(const dap_chain_block_t *a_block, return NULL; size_t l_offset = s_block_get_datum_offset(a_block,a_block_size); dap_chain_datum_t * l_datum =(dap_chain_datum_t *) (a_block->meta_n_datum_n_sign + l_offset); - dap_chain_datum_t ** l_ret =DAP_NEW_Z_SIZE( dap_chain_datum_t *, sizeof (dap_chain_datum_t *)* a_block->hdr.datum_count); - + dap_chain_datum_t **l_ret = DAP_NEW_Z_SIZE(dap_chain_datum_t *, sizeof(dap_chain_datum_t *) * a_block->hdr.datum_count); + if (!l_ret) { + log_it(L_CRITICAL, "Memory allocation error"); + return NULL; + } for(size_t n=0; n<a_block->hdr.datum_count && l_offset<(a_block_size-sizeof (a_block->hdr)) ; n++){ size_t l_datum_size = dap_chain_datum_size(l_datum); @@ -461,48 +435,106 @@ dap_chain_datum_t** dap_chain_block_get_datums(const dap_chain_block_t *a_block, } /** - * @brief dap_chain_block_get_meta - * @param a_block + * @brief dap_chain_block_meta_add + * @details Add metadata in block + * @param a_block_ptr * @param a_block_size - * @param a_meta_count + * @param a_meta_type + * @param a_data + * @param a_data_size * @return */ -dap_chain_block_meta_t** dap_chain_block_get_meta(const dap_chain_block_t * a_block, size_t a_block_size,size_t * a_meta_count ) +size_t dap_chain_block_meta_add(dap_chain_block_t ** a_block_ptr, size_t a_block_size, uint8_t a_meta_type, const void * a_data, size_t a_data_size) { - if (a_meta_count) - *a_meta_count = 0; - if( a_block_size < sizeof(a_block->hdr) ){ - log_it(L_ERROR,"Get meta: corrupted block size %zu thats smaller then block header size %zu", a_block_size, sizeof (a_block->hdr)); - return NULL; + assert(a_block_ptr); + dap_chain_block_t * l_block = *a_block_ptr; + dap_chain_block_meta_t * l_meta = NULL; + if( a_block_size < sizeof(l_block->hdr) ){ + log_it(L_ERROR,"Meta add: Corrupted block size %zd thats smaller then block header size %zd ", a_block_size, sizeof (l_block->hdr)); + return 0; } - if (a_block->hdr.meta_count == 0) // no meta - nothing to return - return NULL; - size_t l_offset = 0; - dap_chain_block_meta_t * l_meta=NULL; - dap_chain_block_meta_t ** l_ret = DAP_NEW_Z_SIZE(dap_chain_block_meta_t *,sizeof (dap_chain_block_meta_t *)* a_block->hdr.meta_count ); - if (!l_ret) { - log_it(L_CRITICAL, "Memory allocation error"); - return NULL; + if(l_block->hdr.meta_count == UINT16_MAX){ + log_it(L_ERROR,"Meta add: Can't add more, maximum meta count %hu is achieved", UINT16_MAX); + return 0; } - for( size_t i = 0; i< a_block->hdr.meta_count && - l_offset < (a_block_size-sizeof (a_block->hdr)) && - sizeof (l_meta->hdr) <= (a_block_size-sizeof (a_block->hdr)) - l_offset ; i++){ - l_meta =(dap_chain_block_meta_t *) (a_block->meta_n_datum_n_sign +l_offset); - size_t l_meta_data_size = l_meta->hdr.data_size; - if (l_meta_data_size + sizeof (l_meta->hdr) + l_offset <= (a_block_size-sizeof (a_block->hdr)) ){ - l_ret[i] = l_meta; - if (a_meta_count) - (*a_meta_count)++; - l_offset += sizeof(l_meta->hdr) + l_meta_data_size; - }else { - log_it(L_WARNING, "Get meta: corrupted block, can read only %zu from %hu metas", i, a_block->hdr.meta_count); - return l_ret; - } + if( UINT32_MAX - l_block->hdr.meta_n_datum_n_signs_size < a_data_size + sizeof (l_meta->hdr) ){ + log_it(L_ERROR,"Meta add: Can't add more, maximum block data section size %u achieved", UINT32_MAX); + return 0; } - return l_ret; + + size_t l_add_size = sizeof(l_meta->hdr) + a_data_size; + *a_block_ptr = l_block = DAP_REALLOC(l_block, a_block_size + l_add_size); + if (!l_block) { + log_it(L_CRITICAL, "Memory reallocation error"); + return 0; + } + size_t l_offset = s_block_get_datum_offset(l_block, a_block_size); + size_t l_datum_n_sign_copy_size = a_block_size - sizeof(l_block->hdr) - l_offset; + if (l_datum_n_sign_copy_size) { + byte_t *l_meta_end = l_block->meta_n_datum_n_sign + l_offset; + memmove(l_meta_end + l_add_size, l_meta_end, l_datum_n_sign_copy_size); + } + l_meta = (dap_chain_block_meta_t *)(l_block->meta_n_datum_n_sign + l_offset); // Update data end in reallocated block + l_meta->hdr.data_size = a_data_size; + l_meta->hdr.type = a_meta_type; + if (a_data_size) + memcpy(l_meta->data, a_data, a_data_size); + l_block->hdr.meta_n_datum_n_signs_size = l_offset + l_datum_n_sign_copy_size; + l_block->hdr.meta_count++; + return a_block_size + l_add_size; +} + +static uint8_t *s_meta_extract(dap_chain_block_meta_t *a_meta) +{ + switch (a_meta->hdr.type) { + case DAP_CHAIN_BLOCK_META_GENESIS: + if (a_meta->hdr.data_size == 0) + return DAP_INT_TO_POINTER(1); + break; + case DAP_CHAIN_BLOCK_META_PREV: + if (a_meta->hdr.data_size == sizeof(dap_hash_t)) + return a_meta->data; + else + log_it(L_WARNING, "Meta PREV has wrong size %hu when expecting %zu", a_meta->hdr.data_size, sizeof(dap_hash_t)); + break; + case DAP_CHAIN_BLOCK_META_ANCHOR: + if (a_meta->hdr.data_size == sizeof(dap_hash_t)) + return a_meta->data; + else + log_it(L_WARNING, "Anchor meta has wrong size %hu when expecting %zu", a_meta->hdr.data_size, sizeof(dap_hash_t)); + break; + case DAP_CHAIN_BLOCK_META_LINK: + if (a_meta->hdr.data_size == sizeof(dap_hash_t)) + return a_meta->data; + else + log_it(L_WARNING, "Link meta has wrong size %hu when expecting %zu", a_meta->hdr.data_size, sizeof(dap_hash_t)); + break; + case DAP_CHAIN_BLOCK_META_NONCE: + if (a_meta->hdr.data_size == sizeof(uint64_t)) + return a_meta->data; + else + log_it(L_WARNING, "NONCE meta has wrong size %hu when expecting %zu", a_meta->hdr.data_size, sizeof(uint64_t)); + break; + case DAP_CHAIN_BLOCK_META_NONCE2: + if (a_meta->hdr.data_size == sizeof(uint64_t)) + return a_meta->data; + else + log_it(L_WARNING, "NONCE2 meta has wrong size %hu when expecting %zu", a_meta->hdr.data_size, sizeof(uint64_t)); + break; + case DAP_CHAIN_BLOCK_META_MERKLE: + if (a_meta->hdr.data_size == sizeof(dap_hash_t)) + return a_meta->data; + else + log_it(L_WARNING, "Merkle root meta has wrong size %hu when expecting %zu", a_meta->hdr.data_size, sizeof (dap_hash_t)); + break; + default: + log_it(L_WARNING, "Unknown meta type 0x%02x (size %u), possible corrupted block or you need to upgrade your software", + a_meta->hdr.type, a_meta->hdr.type); + } + return NULL; } -dap_hash_fast_t *dap_chain_block_get_prev_hash(const dap_chain_block_t *a_block, size_t a_block_size) +uint8_t *dap_chain_block_meta_get(const dap_chain_block_t *a_block, size_t a_block_size, uint8_t a_meta_type) { if( a_block_size < sizeof(a_block->hdr) ){ log_it(L_ERROR, "Get meta: corrupted block size %zu thats smaller then block header size %zu", a_block_size, sizeof (a_block->hdr)); @@ -521,151 +553,165 @@ dap_hash_fast_t *dap_chain_block_get_prev_hash(const dap_chain_block_t *a_block, log_it(L_WARNING, "Get meta: corrupted block, can read only %zu from %hu metas", i, a_block->hdr.meta_count); return NULL; } - if (l_meta->hdr.type == DAP_CHAIN_BLOCK_META_PREV) { - if (l_meta->hdr.data_size != sizeof(dap_hash_t)) { - log_it(L_WARNING, "Get meta: corrupted block, incorrect size DAP_CHAIN_BLOCK_META_PREV %hu, must be %zu", - l_meta->hdr.data_size, sizeof(dap_hash_t)); - return NULL; - } - return (dap_hash_t *)l_meta->data; - } + if (l_meta->hdr.type == a_meta_type) + return s_meta_extract(l_meta); } return NULL; } /** * @brief dap_chain_block_meta_extract_generals - * @param a_meta - * @param a_meta_count + * @param a_block + * @param a_block_size * @param a_block_prev_hash * @param a_block_anchor_hash + * @param a_merkle + * @param a_block_links + * @param a_block_links_count * @param a_is_genesis * @param a_nonce * @param a_nonce2 + * @param a_reward */ -void dap_chain_block_meta_extract(dap_chain_block_meta_t ** a_meta, size_t a_meta_count, +int dap_chain_block_meta_extract(dap_chain_block_t *a_block, size_t a_block_size, dap_chain_hash_fast_t * a_block_prev_hash, dap_chain_hash_fast_t * a_block_anchor_hash, dap_chain_hash_fast_t *a_merkle, dap_chain_hash_fast_t ** a_block_links, size_t *a_block_links_count, - bool * a_is_genesis, + bool *a_is_genesis, uint64_t *a_nonce, - uint64_t *a_nonce2 - ) + uint64_t *a_nonce2) { - if (!a_meta || !a_meta_count) - return; + dap_return_val_if_fail(a_block && a_block_size, -1); // 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; - bool l_was_merkle = false; + bool l_was_prev = false, l_was_genesis = false, l_was_anchor = false, l_was_nonce = false, + l_was_nonce2 = false, l_was_merkle = false, l_was_reward = false; // Init links parsing - size_t l_links_count_max = 5; - if (a_block_links_count) - *a_block_links_count = 0; + size_t l_links_count = 0, l_links_count_max = 5; + if (a_block_size < sizeof(a_block->hdr)) { + log_it(L_ERROR, "Get meta: corrupted block size %zu thats smaller then block header size %zu", a_block_size, sizeof(a_block->hdr)); + return -2; + } + if (a_block->hdr.meta_count == 0) // no meta - nothing to return + return 0; - for(size_t i = 0; i < a_meta_count; i++){ - dap_chain_block_meta_t * l_meta = a_meta[i]; + dap_chain_block_meta_t *l_meta = NULL; + uint8_t *l_meta_data = NULL; + for (size_t l_offset = 0, i = 0; + i < a_block->hdr.meta_count && l_offset + sizeof(a_block->hdr) + sizeof(dap_chain_block_meta_t) < a_block_size; + i++) { + l_meta = (dap_chain_block_meta_t *)(a_block->meta_n_datum_n_sign + l_offset); + l_offset += sizeof(l_meta->hdr) + l_meta->hdr.data_size; + if (l_offset + sizeof(a_block->hdr) > a_block_size) { + log_it(L_WARNING, "Get meta: corrupted block, can read only %zu from %hu metas", i, a_block->hdr.meta_count); + return -3; + } 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 #%zu 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 #%zu is ignored ", i); - break; - } - l_was_prev = true; - if (a_block_prev_hash){ - if (l_meta->hdr.data_size == sizeof (*a_block_prev_hash) ) - memcpy(a_block_prev_hash, l_meta->data, l_meta->hdr.data_size); - else - log_it(L_WARNING, "Meta #%zu PREV has wrong size %hu when expecting %zu",i, l_meta->hdr.data_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 #%zu is ignored ", i); - break; - } - l_was_anchor = true; - if ( a_block_anchor_hash){ - if (l_meta->hdr.data_size == sizeof (*a_block_anchor_hash) ) - memcpy(a_block_anchor_hash, l_meta->data, l_meta->hdr.data_size); - else - log_it(L_WARNING, "Anchor meta #%zu has wrong size %hu when expecting %zu",i, l_meta->hdr.data_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 ){ - // Type sizeof's misunderstanding in malloc? - *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.data_size == sizeof (**a_block_links) ){ - *a_block_links[*a_block_links_count] = *(dap_chain_hash_fast_t*)l_meta->data; - (*a_block_links_count)++; - }else - log_it(L_WARNING, "Link meta #%zu has wrong size %hu when expecting %zu", i, l_meta->hdr.data_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 #%zu is ignored ", i); - break; - } - l_was_nonce = true; - - if ( a_nonce){ - if (l_meta->hdr.data_size == sizeof (*a_nonce ) ) - memcpy(a_nonce, l_meta->data, l_meta->hdr.data_size); - else - log_it(L_WARNING, "NONCE meta #%zu has wrong size %hu when expecting %zu",i, l_meta->hdr.data_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 #%zu is ignored ", i); - break; - } - l_was_nonce2 = true; - if ( a_nonce2){ - if (l_meta->hdr.data_size == sizeof (*a_nonce2 ) ) - memcpy(a_nonce2, l_meta->data, l_meta->hdr.data_size); - else - log_it(L_WARNING, "NONCE2 meta #%zu has wrong size %hu when expecting %zu",i, l_meta->hdr.data_size, sizeof (*a_nonce2)); - } - break; - case DAP_CHAIN_BLOCK_META_MERKLE: - if(l_was_merkle){ - log_it(L_WARNING, "Merckle root could be only one in the block, meta #%zu is ignored ", i); - break; + case DAP_CHAIN_BLOCK_META_GENESIS: + if(l_was_genesis) { + log_it(L_WARNING, "Genesis meta could be only one in the block, meta #%zu is ignored ", i); + break; + } + l_was_genesis = true; + if (a_is_genesis) + *a_is_genesis = s_meta_extract(l_meta); + 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 #%zu is ignored ", i); + break; + } + l_was_prev = true; + if (a_block_prev_hash) { + l_meta_data = s_meta_extract(l_meta); + if (l_meta_data) + *a_block_prev_hash = *(dap_hash_t *)l_meta_data; + else + return -4; + } + 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 #%zu is ignored ", i); + break; + } + l_was_anchor = true; + if (a_block_anchor_hash) { + l_meta_data = s_meta_extract(l_meta); + if (l_meta_data) + *a_block_anchor_hash = *(dap_hash_t *)l_meta_data; + else + return -4; + } + break; + case DAP_CHAIN_BLOCK_META_LINK: + if (a_block_links) { + if (l_links_count == 0) + *a_block_links = DAP_NEW_Z_SIZE(dap_hash_t, sizeof(dap_hash_t) * l_links_count_max); + else if (l_links_count == l_links_count_max) { + l_links_count_max *= 2; + *a_block_links = DAP_REALLOC(*a_block_links, l_links_count_max); } - l_was_merkle = true; - if (a_merkle) { - if (l_meta->hdr.data_size == sizeof(*a_merkle)) - memcpy(a_merkle, l_meta->data, l_meta->hdr.data_size); - else - log_it(L_WARNING, "Merkle root meta #%zu has wrong size %hu when expecting %zu", i, l_meta->hdr.data_size, sizeof (*a_nonce2)); + if (!*a_block_links) { + log_it(L_CRITICAL, "Not enough memory"); + return -5; } - break; - default: { log_it(L_WARNING, "Unknown meta #%zu type 0x%02x (size %u), possible corrupted block or you need to upgrade your software", - i, l_meta->hdr.type, l_meta->hdr.type); } + l_meta_data = s_meta_extract(l_meta); + if (l_meta_data) + *a_block_links[l_links_count++] = *(dap_hash_t *)l_meta_data; + else + return -4; + if (a_block_links_count) + *a_block_links_count = l_links_count; + } + break; + case DAP_CHAIN_BLOCK_META_NONCE: + if (l_was_nonce) { + log_it(L_WARNING, "NONCE could be only one in the block, meta #%zu is ignored ", i); + break; + } + l_was_nonce = true; + if (a_nonce) { + l_meta_data = s_meta_extract(l_meta); + if (l_meta_data) + *a_nonce = *(uint64_t *)l_meta_data; + else + return -4; + } + break; + case DAP_CHAIN_BLOCK_META_NONCE2: + if (l_was_nonce2) { + log_it(L_WARNING, "NONCE2 could be only one in the block, meta #%zu is ignored ", i); + break; + } + l_was_nonce2 = true; + if (a_nonce2) { + l_meta_data = s_meta_extract(l_meta); + if (l_meta_data) + *a_nonce2 = *(uint64_t *)l_meta_data; + else + return -4; + } + break; + case DAP_CHAIN_BLOCK_META_MERKLE: + if (l_was_merkle) { + log_it(L_WARNING, "Merckle root could be only one in the block, meta #%zu is ignored ", i); + break; + } + l_was_merkle = true; + if (a_merkle) { + l_meta_data = s_meta_extract(l_meta); + if (l_meta_data) + *a_merkle = *(dap_hash_t *)l_meta_data; + else + return -4; + } + break; + default: log_it(L_WARNING, "Unknown meta #%zu type 0x%02x (size %u), possible corrupted block or you need to upgrade your software", + i, l_meta->hdr.type, l_meta->hdr.type); + break; } } + return 0; } diff --git a/modules/type/blocks/dap_chain_block_cache.c b/modules/type/blocks/dap_chain_block_cache.c index c5994830db..2fccdd5bca 100644 --- a/modules/type/blocks/dap_chain_block_cache.c +++ b/modules/type/blocks/dap_chain_block_cache.c @@ -54,7 +54,8 @@ void dap_chain_block_cache_deinit() * @return */ -dap_chain_block_cache_t *dap_chain_block_cache_new(dap_hash_fast_t *a_block_hash, dap_chain_block_t *a_block, size_t a_block_size) +dap_chain_block_cache_t *dap_chain_block_cache_new(dap_hash_fast_t *a_block_hash, dap_chain_block_t *a_block, + size_t a_block_size, uint64_t a_block_number) { if (! a_block) return NULL; @@ -65,7 +66,8 @@ dap_chain_block_cache_t *dap_chain_block_cache_new(dap_hash_fast_t *a_block_hash return NULL; } l_block_cache->block = a_block; - l_block_cache->block_size= a_block_size; + l_block_cache->block_size = a_block_size; + l_block_cache->block_number = a_block_number; l_block_cache->ts_created = a_block->hdr.ts_created; l_block_cache->sign_count = dap_chain_block_get_signs_count(a_block, a_block_size); if (dap_chain_block_cache_update(l_block_cache, a_block_hash)) { @@ -107,13 +109,8 @@ int dap_chain_block_cache_update(dap_chain_block_cache_t *a_block_cache, dap_has else dap_hash_fast(a_block_cache->block, a_block_cache->block_size, &a_block_cache->block_hash); a_block_cache->block_hash_str = dap_hash_fast_to_str_new(&a_block_cache->block_hash); - DAP_DEL_Z(a_block_cache->meta); - a_block_cache->meta = dap_chain_block_get_meta(a_block_cache->block, a_block_cache->block_size, &a_block_cache->meta_count); - if (a_block_cache->meta_count != a_block_cache->block->hdr.meta_count) { - DAP_DELETE(a_block_cache->meta); - return -1; - } - dap_chain_block_meta_extract(a_block_cache->meta,a_block_cache->meta_count, + + if (dap_chain_block_meta_extract(a_block_cache->block, a_block_cache->block_size, &a_block_cache->prev_hash, &a_block_cache->anchor_hash, &a_block_cache->merkle_root, @@ -121,9 +118,11 @@ int dap_chain_block_cache_update(dap_chain_block_cache_t *a_block_cache, dap_has &a_block_cache->links_hash_count, &a_block_cache->is_genesis, &a_block_cache->nonce, - &a_block_cache->nonce2); - DAP_DEL_Z(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); + &a_block_cache->nonce2)) + return -1; + + DAP_DEL_Z(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); if (a_block_cache->datum_count != a_block_cache->block->hdr.datum_count) { DAP_DELETE(a_block_cache->datum); @@ -146,7 +145,6 @@ void dap_chain_block_cache_delete(dap_chain_block_cache_t * a_block_cache) DAP_DEL_Z(a_block_cache->block_hash_str); DAP_DEL_Z(a_block_cache->datum); DAP_DEL_Z(a_block_cache->datum_hash); - DAP_DEL_Z(a_block_cache->meta); DAP_DEL_Z(a_block_cache->links_hash); DAP_DELETE(a_block_cache); } diff --git a/modules/type/blocks/dap_chain_block_chunk.c b/modules/type/blocks/dap_chain_block_chunk.c index 0e9d2aa3cd..800d11cab8 100644 --- a/modules/type/blocks/dap_chain_block_chunk.c +++ b/modules/type/blocks/dap_chain_block_chunk.c @@ -49,7 +49,7 @@ dap_chain_block_chunks_t * dap_chain_block_chunks_create(dap_chain_cs_blocks_t * for(size_t n=0; n< l_objs_count; n++){ dap_hash_fast_t l_block_hash; dap_chain_hash_fast_from_str(l_objs[n].key, &l_block_hash); - dap_chain_block_cache_t *l_block_cache = dap_chain_block_cache_new(&l_block_hash, (dap_chain_block_t *)l_objs[n].value, l_objs[n].value_len); + dap_chain_block_cache_t *l_block_cache = dap_chain_block_cache_new(&l_block_hash, (dap_chain_block_t *)l_objs[n].value, l_objs[n].value_len, n + 1); dap_chain_block_chunks_add(l_ret, l_block_cache ); } dap_global_db_objs_delete(l_objs,l_objs_count); diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c index 69587e89f5..a1acd1eab0 100644 --- a/modules/type/blocks/dap_chain_cs_blocks.c +++ b/modules/type/blocks/dap_chain_cs_blocks.c @@ -135,7 +135,7 @@ static void s_callback_cs_blocks_purge(dap_chain_t *a_chain); static dap_chain_block_t *s_new_block_move(dap_chain_cs_blocks_t *a_blocks, size_t *a_new_block_size); //Work with atoms -static size_t s_callback_count_atom(dap_chain_t *a_chain); +static uint64_t s_callback_count_atom(dap_chain_t *a_chain); static dap_list_t *s_callback_get_atoms(dap_chain_t *a_chain, size_t a_count, size_t a_page, bool a_reverse); static int s_chain_cs_blocks_new(dap_chain_t * a_chain, dap_config_t * a_chain_config); @@ -414,18 +414,14 @@ static int s_cli_parse_cmd_hash(char ** a_argv, int a_arg_index, int a_argc, cha * @param a_meta_title * @param a_meta */ -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 void s_cli_meta_hash_print(dap_string_t *a_str_tmp, const char *a_meta_title, dap_chain_block_meta_t *a_meta) { if (a_meta->hdr.data_size == sizeof (dap_chain_hash_fast_t)) { char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; - dap_chain_hash_fast_to_str((dap_chain_hash_fast_t*)a_meta->data, l_hash_str, sizeof(l_hash_str)); - dap_string_append_printf(a_str_tmp,"\t\tPREV: \"%s\": %s\n", a_meta_title,l_hash_str); - } else { - char *l_data_hex = DAP_NEW_Z_SIZE(char,a_meta->hdr.data_size * 2 + 3); - dap_bin2hex(l_data_hex, a_meta->data, a_meta->hdr.data_size); - dap_string_append_printf(a_str_tmp,"\t\t\%s: 0x%s\n", a_meta_title, l_data_hex); - DAP_DELETE(l_data_hex); - } + dap_chain_hash_fast_to_str((dap_chain_hash_fast_t *)a_meta->data, l_hash_str, sizeof(l_hash_str)); + dap_string_append_printf(a_str_tmp, "\t\t%s: %s\n", a_meta_title, l_hash_str); + } else + dap_string_append_printf(a_str_tmp,"\t\t\%s: Error, hash size is incorrect\n", a_meta_title); } /** @@ -610,35 +606,37 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply) dap_string_append_printf(l_str_tmp,"\t\t\tts_created: %s\n", buf); // Dump Metadata + size_t l_offset = 0; dap_string_append_printf(l_str_tmp,"\tMetadata. Count: %us\n",l_block->hdr.meta_count ); - for (uint32_t i=0; i < l_block_cache->meta_count; i++){ - dap_chain_block_meta_t * l_meta = l_block_cache->meta[i]; + for (uint32_t i=0; i < l_block->hdr.meta_count; i++) { + dap_chain_block_meta_t *l_meta = (dap_chain_block_meta_t *)(l_block->meta_n_datum_n_sign + l_offset); switch (l_meta->hdr.type) { - case DAP_CHAIN_BLOCK_META_GENESIS:{ - dap_string_append_printf(l_str_tmp, "\t\tGENESIS\n"); - }break; - case DAP_CHAIN_BLOCK_META_PREV:{ - s_cli_meta_hash_print(l_str_tmp, "PREV", l_meta); - }break; - case DAP_CHAIN_BLOCK_META_ANCHOR:{ - s_cli_meta_hash_print(l_str_tmp, "ANCHOR", l_meta); - }break; - case DAP_CHAIN_BLOCK_META_LINK:{ - s_cli_meta_hash_print(l_str_tmp, "LINK", l_meta); - }break; - case DAP_CHAIN_BLOCK_META_NONCE:{ - s_cli_meta_hex_print(l_str_tmp,"NONCE", l_meta); - }break; - case DAP_CHAIN_BLOCK_META_NONCE2:{ - s_cli_meta_hex_print(l_str_tmp,"NONCE2", l_meta); - }break; - default:{ - char * l_data_hex = DAP_NEW_Z_SIZE(char,l_meta->hdr.data_size*2+3); - dap_bin2hex(l_data_hex, l_meta->data, l_meta->hdr.data_size); - dap_string_append_printf(l_str_tmp, "\t\t 0x%0X: 0x%s\n", i, l_data_hex ); - DAP_DELETE(l_data_hex); - } + case DAP_CHAIN_BLOCK_META_GENESIS: + dap_string_append_printf(l_str_tmp, "\t\tGENESIS\n"); + break; + case DAP_CHAIN_BLOCK_META_PREV: + s_cli_meta_hash_print(l_str_tmp, "PREV", l_meta); + break; + case DAP_CHAIN_BLOCK_META_ANCHOR: + s_cli_meta_hash_print(l_str_tmp, "ANCHOR", l_meta); + break; + case DAP_CHAIN_BLOCK_META_LINK: + s_cli_meta_hash_print(l_str_tmp, "LINK", l_meta); + break; + case DAP_CHAIN_BLOCK_META_NONCE: + s_cli_meta_hex_print(l_str_tmp, "NONCE", l_meta); + break; + case DAP_CHAIN_BLOCK_META_NONCE2: + s_cli_meta_hex_print(l_str_tmp, "NONCE2", l_meta); + break; + default: { + char * l_data_hex = DAP_NEW_Z_SIZE(char,l_meta->hdr.data_size*2+3); + dap_bin2hex(l_data_hex, l_meta->data, l_meta->hdr.data_size); + dap_string_append_printf(l_str_tmp, "\t\t 0x%0X: 0x%s\n", i, l_data_hex ); + DAP_DELETE(l_data_hex); + } } + l_offset += sizeof(l_meta->hdr) + l_meta->hdr.data_size; } dap_string_append_printf(l_str_tmp,"\t\tdatums:\tcount: %zu\n",l_block_cache->datum_count); for (uint32_t i=0; i < l_block_cache->datum_count ; i++){ @@ -875,9 +873,10 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply) } break; } else if (dap_cli_server_cmd_check_option(a_argv, arg_index, a_argc, "show") >= 0) { - char *l_base_reward_str = dap_chain_balance_to_coins(l_net->pub.base_reward); - dap_cli_server_cmd_set_reply_text(a_str_reply, "Current base block reward is %s\n", l_base_reward_str); - DAP_DEL_Z(l_base_reward_str); + uint256_t l_cur_reward = dap_chain_net_get_reward(l_net, UINT64_MAX); + char *l_reward_str = dap_chain_balance_to_coins(l_cur_reward); + dap_cli_server_cmd_set_reply_text(a_str_reply, "Current base block reward is %s\n", l_reward_str); + DAP_DEL_Z(l_reward_str); break; } else if (dap_cli_server_cmd_check_option(a_argv, arg_index, a_argc, "collect") == -1) { dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block reward' requires subcommands 'set' or 'show' or 'collect'"); @@ -1075,7 +1074,7 @@ static int s_add_atom_datums(dap_chain_cs_blocks_t *a_blocks, dap_chain_block_ca size_t l_datum_data_size = l_datum->header.data_size; l_datum_size = l_datum_data_size + sizeof(l_datum->header); if(l_datum_size>a_block_cache->block_size- l_block_offset ){ - log_it(L_WARNING,"Corrupted block %s has strange datum on offset %zd with size %zd out of block sizee", + log_it(L_WARNING, "Corrupted block %s has strange datum on offset %zd with size %zd out of block size", a_block_cache->block_hash_str, l_block_offset,l_datum_size ); break; } @@ -1098,6 +1097,8 @@ static int s_add_atom_datums(dap_chain_cs_blocks_t *a_blocks, dap_chain_block_ca pthread_rwlock_unlock(&PVT(a_blocks)->datums_rwlock); } + debug_if(s_debug_more, L_DEBUG, "Block %s checked, %s", a_block_cache->block_hash_str, + l_ret == (int)a_block_cache->datum_count ? "all correct" : "there are rejected datums"); return l_ret; } @@ -1108,18 +1109,10 @@ static int s_add_atom_datums(dap_chain_cs_blocks_t *a_blocks, dap_chain_block_ca * @param a_block_cache * @return */ -static int s_add_atom_to_blocks(dap_chain_cs_blocks_t *a_blocks, dap_chain_block_cache_t *a_block_cache ) +static void s_add_atom_to_blocks(dap_chain_cs_blocks_t *a_blocks, dap_chain_block_cache_t *a_block_cache) { - int l_res = 0; - //pthread_rwlock_wrlock( &PVT(a_blocks)->rwlock ); // do lock in calling context! - l_res = s_add_atom_datums(a_blocks, a_block_cache); - debug_if(s_debug_more, L_DEBUG, "Block %s checked, %s", a_block_cache->block_hash_str, - l_res == (int)a_block_cache->datum_count ? "all correct" : "but ledger declined"); - // Ignore addition result for now - HASH_ADD(hh, PVT(a_blocks)->blocks, block_hash, sizeof (a_block_cache->block_hash), a_block_cache); - ++PVT(a_blocks)->blocks_count; - //pthread_rwlock_unlock( &PVT(a_blocks)->rwlock ); // do unlock in calling context! - return /* l_res */ 0; + + return; } @@ -1167,13 +1160,15 @@ static void s_bft_consensus_setup(dap_chain_cs_blocks_t * a_blocks) int l_check_res = 0; if (a_blocks->callback_block_verify) l_check_res = a_blocks->callback_block_verify(a_blocks, l_block_cache->block, l_block_cache->block_size); - if (!l_check_res) - l_check_res = s_add_atom_to_blocks(a_blocks, l_block_cache); - if ( l_check_res != 0 ){ + if (!l_check_res) { log_it(L_WARNING,"Can't move block %s from chunk to main chain - data inside wasn't verified: code %d", l_block_cache->block_hash_str, l_check_res); dap_chain_block_chunks_add(PVT(a_blocks)->chunks,l_block_cache); } + // TODO Rework blocks rwlock usage for this code + HASH_ADD(hh, PVT(a_blocks)->blocks, block_hash, sizeof(l_block_cache->block_hash), l_block_cache); + ++PVT(a_blocks)->blocks_count; + s_add_atom_datums(a_blocks, l_block_cache); } dap_chain_block_chunk_delete(l_chunk ); l_was_chunks_changed = true; @@ -1213,7 +1208,7 @@ static dap_chain_atom_verify_res_t s_callback_atom_add(dap_chain_t * a_chain, da pthread_rwlock_unlock(&PVT(l_blocks)->rwlock); return ATOM_PASS; } else { - l_block_cache = dap_chain_block_cache_new(&l_block_hash, l_block, l_block_size); + l_block_cache = dap_chain_block_cache_new(&l_block_hash, l_block, l_block_size, PVT(l_blocks)->blocks_count + 1); if (!l_block_cache) { log_it(L_DEBUG, "... corrupted block"); pthread_rwlock_unlock(&PVT(l_blocks)->rwlock); @@ -1225,9 +1220,12 @@ static dap_chain_atom_verify_res_t s_callback_atom_add(dap_chain_t * a_chain, da dap_chain_atom_verify_res_t ret = s_callback_atom_verify(a_chain, a_atom, a_atom_size); switch (ret) { case ATOM_ACCEPT: - s_add_atom_to_blocks(l_blocks, l_block_cache); + HASH_ADD(hh, PVT(l_blocks)->blocks, block_hash, sizeof(l_block_cache->block_hash), l_block_cache); + ++PVT(l_blocks)->blocks_count; + pthread_rwlock_unlock(&PVT(l_blocks)->rwlock); debug_if(s_debug_more, L_DEBUG, "Verified atom %p: ACCEPTED", a_atom); - break; + s_add_atom_datums(l_blocks, l_block_cache); + return ret; case ATOM_MOVE_TO_THRESHOLD: // TODO: reimplement and enable threshold for blocks /* { @@ -1284,25 +1282,10 @@ static dap_chain_atom_verify_res_t s_callback_atom_verify(dap_chain_t * a_chain, 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, - NULL, - &l_is_genesis, - &l_nonce, - &l_nonce2 ) ; - DAP_DEL_Z(l_meta); + bool l_is_genesis = dap_chain_block_meta_get(l_block, a_atom_size, DAP_CHAIN_BLOCK_META_GENESIS); + dap_hash_t *l_prev_hash_meta_data = (dap_hash_t *)dap_chain_block_meta_get(l_block, a_atom_size, DAP_CHAIN_BLOCK_META_PREV); + dap_hash_t l_block_prev_hash = l_prev_hash_meta_data ? *l_prev_hash_meta_data : (dap_hash_t){}; // 2nd level consensus if(l_blocks->callback_block_verify) @@ -1722,6 +1705,7 @@ static size_t s_callback_add_datums(dap_chain_t *a_chain, dap_chain_datum_t **a_ { dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain); dap_chain_cs_blocks_pvt_t *l_blocks_pvt = PVT(l_blocks); + dap_chain_net_t *l_net = dap_chain_net_by_id(a_chain->net_id); size_t l_datum_processed = 0; pthread_rwlock_wrlock(&l_blocks_pvt->rwlock); @@ -1756,10 +1740,11 @@ static size_t s_callback_add_datums(dap_chain_t *a_chain, dap_chain_datum_t **a_ * @param a_chain Chain object * @return size_t */ -static size_t s_callback_count_atom(dap_chain_t *a_chain) +static uint64_t s_callback_count_atom(dap_chain_t *a_chain) { dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain); - size_t l_ret = 0; + assert(l_blocks && l_blocks->chain == a_chain); + uint64_t l_ret = 0; pthread_rwlock_rdlock(&PVT(l_blocks)->rwlock); l_ret = PVT(l_blocks)->blocks_count; pthread_rwlock_unlock(&PVT(l_blocks)->rwlock); @@ -1828,7 +1813,7 @@ static dap_list_t *s_callback_get_atoms(dap_chain_t *a_chain, size_t a_count, si return l_list; } -static const dap_time_t s_block_timediff_unit = 60; +static const dap_time_t s_block_timediff_unit_size = 60; static uint256_t s_callback_calc_reward(dap_chain_t *a_chain, dap_hash_fast_t *a_block_hash, dap_pkey_t *a_block_sign_pkey) { @@ -1840,27 +1825,31 @@ static uint256_t s_callback_calc_reward(dap_chain_t *a_chain, dap_hash_fast_t *a return l_ret; const dap_chain_block_t *l_block = l_block_cache->block; size_t l_block_size = l_block_cache->block_size; - if (dap_chain_block_sign_match_pkey(l_block, l_block_size, a_block_sign_pkey)) { - dap_chain_net_t *l_net = dap_chain_net_by_id(a_chain->net_id); - if (!l_net) { - log_it(L_ERROR, "Invalid chain object"); - return l_ret; - } - dap_time_t l_block_time = l_block->hdr.ts_created; - if (l_block_time < 1700870400UL) { // 25 Nov 00:00:00 GMT - log_it(L_WARNING, "Timesatamp is too old, reward is not set for this block"); - return l_ret; - } - size_t l_signs_count = dap_chain_block_get_signs_count(l_block, l_block_size); - DIV_256(l_net->pub.base_reward, GET_256_FROM_64(l_signs_count), &l_ret); - dap_hash_fast_t *l_prev_block_hash = dap_chain_block_get_prev_hash(l_block, l_block_size); - if (l_prev_block_hash) { - l_block = dap_chain_get_atom_by_hash(a_chain, l_prev_block_hash, &l_block_size); - assert(l_block); - dap_time_t l_time_diff = l_block_time - l_block->hdr.ts_created; - MULT_256_256(l_ret, GET_256_FROM_64(l_time_diff), &l_ret); - DIV_256(l_ret, GET_256_FROM_64(s_block_timediff_unit), &l_ret); - } + if (!dap_chain_block_sign_match_pkey(l_block, l_block_size, a_block_sign_pkey)) + return l_ret; + dap_chain_net_t *l_net = dap_chain_net_by_id(a_chain->net_id); + if (!l_net) { + log_it(L_ERROR, "Invalid chain object"); + return l_ret; + } + dap_time_t l_block_time = l_block->hdr.ts_created; + if (l_block_time < DAP_REWARD_INIT_TIMESTAMP) { + log_it(L_WARNING, "Reward is not set for this block"); + return l_ret; + } + l_ret = dap_chain_net_get_reward(l_net, l_block_cache->block_number); + size_t l_signs_count = l_block_cache->sign_count; + if (l_block_cache->is_genesis) { + DIV_256(l_ret, GET_256_FROM_64(l_signs_count), &l_ret); + return l_ret; } + dap_hash_fast_t l_prev_block_hash = l_block_cache->prev_hash; + HASH_FIND(hh, PVT(l_blocks)->blocks, &l_prev_block_hash, sizeof(l_prev_block_hash), l_block_cache); + assert(!l_block_cache); + l_block = l_block_cache->block; + assert(l_block); + dap_time_t l_time_diff = l_block_time - dap_max(l_block->hdr.ts_created, DAP_REWARD_INIT_TIMESTAMP); + MULT_256_256(l_ret, GET_256_FROM_64(l_time_diff), &l_ret); + DIV_256(l_ret, GET_256_FROM_64(s_block_timediff_unit_size * l_signs_count), &l_ret); return l_ret; } diff --git a/modules/type/blocks/include/dap_chain_block.h b/modules/type/blocks/include/dap_chain_block.h index 6accd3802d..3c986857fc 100644 --- a/modules/type/blocks/include/dap_chain_block.h +++ b/modules/type/blocks/include/dap_chain_block.h @@ -73,7 +73,6 @@ typedef struct dap_chain_block_meta{ #define DAP_CHAIN_BLOCK_META_NONCE2 0x21 #define DAP_CHAIN_BLOCK_META_MERKLE 0x30 - /** * @struct dap_chain_block * @brief The dap_chain_block struct @@ -93,7 +92,16 @@ dap_chain_block_t *dap_chain_block_new(dap_chain_hash_fast_t *a_prev_block, size // Add metadata in block size_t dap_chain_block_meta_add(dap_chain_block_t ** a_block_ptr, size_t a_block_size, uint8_t a_meta_type, const void * a_data, size_t a_data_size); - +uint8_t *dap_chain_block_meta_get(const dap_chain_block_t *a_block, size_t a_block_size, uint8_t a_meta_type); +int dap_chain_block_meta_extract(dap_chain_block_t *a_block, size_t a_block_size, + dap_chain_hash_fast_t *a_block_prev_hash, + dap_chain_hash_fast_t *a_block_anchor_hash, + dap_chain_hash_fast_t *a_merkle, + 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); // Add datum in block size_t dap_chain_block_datum_add(dap_chain_block_t ** a_block_ptr, 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_ptr, size_t a_block_size, dap_chain_hash_fast_t* a_datum_hash); @@ -109,18 +117,3 @@ dap_hash_fast_t *dap_chain_block_get_prev_hash(const dap_chain_block_t *a_block, // Create and return datums list dap_chain_datum_t** dap_chain_block_get_datums(const 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(const 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_merkle, - 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 22cb469d54..5c752bf73f 100644 --- a/modules/type/blocks/include/dap_chain_block_cache.h +++ b/modules/type/blocks/include/dap_chain_block_cache.h @@ -35,6 +35,7 @@ typedef struct dap_chain_block_cache { dap_chain_hash_fast_t block_hash; char* block_hash_str; size_t block_size; + uint64_t block_number; // Local platform values representation time_t ts_created; @@ -44,17 +45,12 @@ typedef struct dap_chain_block_cache { dap_chain_datum_t ** datum; dap_hash_fast_t *datum_hash; - // Block's metadatas - size_t meta_count; - dap_chain_block_meta_t** meta; - // Extracted metadata dap_chain_hash_fast_t prev_hash; dap_chain_hash_fast_t anchor_hash; dap_chain_hash_fast_t merkle_root; dap_chain_hash_fast_t* links_hash; size_t links_hash_count; - uint64_t nonce; uint64_t nonce2; bool is_genesis; @@ -78,7 +74,8 @@ int dap_chain_block_cache_init(); void dap_chain_block_cache_deinit(); -dap_chain_block_cache_t *dap_chain_block_cache_new(dap_hash_fast_t *a_block_hash, dap_chain_block_t *a_block, size_t a_block_size); +dap_chain_block_cache_t *dap_chain_block_cache_new(dap_hash_fast_t *a_block_hash, dap_chain_block_t *a_block, + size_t a_block_size, uint64_t a_block_number); dap_chain_block_cache_t *dap_chain_block_cache_dup(dap_chain_block_cache_t *a_block); int dap_chain_block_cache_update(dap_chain_block_cache_t *a_block_cache, dap_hash_fast_t *a_block_hash); void dap_chain_block_cache_delete(dap_chain_block_cache_t *a_block_cache); diff --git a/modules/type/blocks/include/dap_chain_cs_blocks.h b/modules/type/blocks/include/dap_chain_cs_blocks.h index 4889dca957..47d2a24456 100644 --- a/modules/type/blocks/include/dap_chain_cs_blocks.h +++ b/modules/type/blocks/include/dap_chain_cs_blocks.h @@ -32,6 +32,8 @@ #define DAP_CHAIN_CS_BLOCKS_MAX_BLOCK_SIZE (256 * 1024) // 256 KB #endif +#define DAP_REWARD_INIT_TIMESTAMP 1700870400UL // 25 Nov 00:00:00 GMT + typedef struct dap_chain_cs_blocks dap_chain_cs_blocks_t; typedef void (*dap_chain_cs_blocks_callback_t)(dap_chain_cs_blocks_t *); -- GitLab